Skip to content

Commit

Permalink
📡 add --stack option (#214)
Browse files Browse the repository at this point in the history
* starting check option

* primed to move functionality down to function

* shifting getSettings to async + tests

* basic solidarity setup

* properly parse json5 strings

* move check to stack

* now uses Solidarity Stacks repo

* fix shortcut and help

* verbiage chage

* no more local file

* fix folder flag

* fixing up tests

* break out helpers and write tests

* fix for tsc

* no more check folder

* adding CLI Options docs

* fix silent bug

* fix naming collision

* fix up tests

Closes #213
  • Loading branch information
GantMan authored Aug 11, 2018
1 parent a73fdb0 commit 64fce79
Show file tree
Hide file tree
Showing 21 changed files with 275 additions and 85 deletions.
2 changes: 1 addition & 1 deletion __tests__/__mocks__/mockContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ realSolidarityContext(realThing)

const noConfigSolidarity = {
checkRequirement: jest.fn(),
getSolidaritySettings: jest.fn(() => ({})),
getSolidaritySettings: jest.fn(() => Promise.resolve({})),
printResults: jest.fn(),
setSolidaritySettings: jest.fn(),
updateRequirement: jest.fn(),
Expand Down
14 changes: 7 additions & 7 deletions __tests__/command_helpers/appendSolidaritySettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ describe('appendSolidaritySettings', () => {

context.solidarity = {
...context.solidarity,
getSolidaritySettings: jest.fn(() => solidaritySettings),
getSolidaritySettings: jest.fn(() => Promise.resolve(solidaritySettings)),
}
})

it('appends the given requirement to the existing settings', () => {
it('appends the given requirement to the existing settings', async () => {
const newRequirement = {
three: [{ rule: 'cli' }],
}
Expand All @@ -31,13 +31,13 @@ describe('appendSolidaritySettings', () => {
first: 'cli',
}

const newSettings = appendSolidaritySettings(context, newRequirement)
const newSettings = await appendSolidaritySettings(context, newRequirement)

expect(keys(newSettings.requirements).length).toEqual(3)
expect(keys(newSettings.requirements.three).length).toEqual(1)
})

it('will append the given requirement to and existing requirement', () => {
it('will append the given requirement to and existing requirement', async () => {
context.parameters = {
first: 'cli',
second: 'ruby',
Expand All @@ -47,7 +47,7 @@ describe('appendSolidaritySettings', () => {
twoTest: [{ rule: 'cli', binary: 'ruby' }],
}

let newSettings = appendSolidaritySettings(context, newRequirement)
let newSettings = await appendSolidaritySettings(context, newRequirement)

expect(keys(newSettings.requirements).length).toEqual(2)
expect(newSettings.requirements.twoTest.length).toEqual(2)
Expand All @@ -57,7 +57,7 @@ describe('appendSolidaritySettings', () => {
})

describe('given a requirement with a prexisting rule', () => {
it('should just merge the rule w/ the existing rule', () => {
it('should just merge the rule w/ the existing rule', async () => {
context.parameters = {
first: 'env',
}
Expand All @@ -73,7 +73,7 @@ describe('appendSolidaritySettings', () => {
],
}

let newSettings = appendSolidaritySettings(context, newRequirement)
let newSettings = await appendSolidaritySettings(context, newRequirement)

expect(keys(newSettings.requirements).length).toEqual(2)
expect(newSettings.requirements.oneTest.length).toEqual(2)
Expand Down
50 changes: 50 additions & 0 deletions __tests__/command_helpers/getSolidarityHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { isURI, loadFile, loadWebCheck } from '../../src/extensions/functions/getSolidarityHelpers'

const context = require('mockContext')

describe('Test helper functions', () => {
describe('isURI', () => {
test('isURI positive case', () => {
expect(isURI('http://www.google.com')).toBeTruthy()
expect(isURI('https://www.google.com')).toBeTruthy()
})

test('isURI fail case', () => {
expect(isURI('nachos')).toBeFalsy()
expect(isURI('/nachos')).toBeFalsy()
expect(isURI('./nachos')).toBeFalsy()
})

})

describe('loadFile', () => {
test('loadFile positive cases', () => {
expect(loadFile(context, '__tests__/sandbox/solidarity_json')).toBeTruthy()
expect(loadFile(context, '__tests__/sandbox/solidarity_json/.solidarity.json')).toBeTruthy()
})

test('loadFile false cases', () => {
expect(() => {
loadFile(context, '__tests__/sandbox/fake_project')
}).toThrow()
expect(() => {
loadFile(context, '__tests__/sandbox/fake_project/nope.solidarity')
}).toThrow()
})
})

// describe('loadModule', () => {
// })

describe('loadWebCheck', () => {
test('loadWebCheck positive cases', async () => {
expect(await loadWebCheck(context, 'https://raw.githubusercontent.com/infinitered/solidarity-stacks/master/stacks/react-native.solidarity')).toBeTruthy()
})

test('loadWebCheck false cases', async () => {
await expect(loadWebCheck(context, 'https://raw.githubusercontent.com/infinitered/solidarity-stacks/master/stacks/failsauce'))
.rejects
.toThrow()
})
})
})
82 changes: 46 additions & 36 deletions __tests__/command_helpers/getSolidaritySettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,68 +6,78 @@ describe('basic getSolidaritySettings', () => {
describe('w/ success', () => {
test('getSolidaritySettings exists', () => expect(getSolidaritySettings).toMatchSnapshot())

test('getSolidaritySettings succeeds', () => {
const resultSettings = getSolidaritySettings(context)
test('getSolidaritySettings succeeds', async () => {
const resultSettings = await getSolidaritySettings(context)
// we got an object with requirements defined
expect(resultSettings).toMatchObject({ requirements: {} })
})

test('getSolidaritySettings succeeds', () => {
test('getSolidaritySettings succeeds', async () => {
process.chdir('__tests__/sandbox/solidarity_json')
const resultSettings = getSolidaritySettings(context)
const resultSettings = await getSolidaritySettings(context)
// we got an object with requirements defined
expect(resultSettings).toMatchObject({ requirements: {} })
process.chdir('../../../')
})
})

describe('w/ failure', () => {
test('getSolidaritySettings can fail', () => {
expect(() => {
process.chdir('__tests__')
getSolidaritySettings(context)
}).toThrow()
test('getSolidaritySettings can fail', async () => {

// Original sync style
// expect(() => {
// process.chdir('__tests__')
// getSolidaritySettings(context)
// }).toThrow()
// process.chdir('../')

process.chdir('__tests__')
await expect(getSolidaritySettings(context))
.rejects
.toThrow()
process.chdir('../')
})

test('getSolidaritySettings can warn with missing requirements', () => {
expect(() => {
process.chdir('__tests__/sandbox/solidarity_broken')
getSolidaritySettings(context)
}).toThrowError('ERROR: Found, but no requirements key. Please validate your solidarity file')
test('getSolidaritySettings can warn with missing requirements', async () => {
process.chdir('__tests__/sandbox/solidarity_broken')
await expect(getSolidaritySettings(context))
.rejects
.toThrow()
process.chdir('../../../')
})
})
})

describe('parameterized getSolidaritySettings', () => {
test('custom path with -f', () => {
test('custom path with -f', async () => {
context.parameters.options = { f: '__tests__/sandbox/solidarity_json' }
const resultSettings = getSolidaritySettings(context)
const resultSettings = await getSolidaritySettings(context)
// we got an object with requirements defined
expect(resultSettings).toMatchObject({ requirements: {} })
context.parameters.options = {}
})

test('custom path with --solidarityFile', () => {
test('custom path with --solidarityFile', async () => {
context.parameters.options = { solidarityFile: '__tests__/sandbox/solidarity_json' }
const resultSettings = getSolidaritySettings(context)
const resultSettings = await getSolidaritySettings(context)
// we got an object with requirements defined
expect(resultSettings).toMatchObject({ requirements: {} })
context.parameters.options = {}
})

test('failing path message', () => {
test('failing path message', async () => {
// test longhand
context.parameters.options = { solidarityFile: '__tests__/fake' }
expect(() => {
getSolidaritySettings(context)
}).toThrowError('ERROR: There is no solidarity file at the given path')
await expect(getSolidaritySettings(context))
.rejects
.toThrow('ERROR: There is no solidarity file at the given path')

// test shorthand
context.parameters.options = { f: '__tests__/fake' }
expect(() => {
getSolidaritySettings(context)
}).toThrowError('ERROR: There is no solidarity file at the given path')
await expect(getSolidaritySettings(context))
.rejects
.toThrow('ERROR: There is no solidarity file at the given path')

context.parameters.options = {}
})

Expand All @@ -76,35 +86,35 @@ describe('parameterized getSolidaritySettings', () => {
process.chdir('__tests__/sandbox/fake_project')
})

test('can find solidarity file in module with flag -m', () => {
context.parameters.options = { m: 'mock_module' }
const resultSettings = getSolidaritySettings(context)
test('can find solidarity file in module with flag -d', async () => {
context.parameters.options = { d: 'mock_module' }
const resultSettings = await getSolidaritySettings(context)
// we got an object with requirements defined
expect(resultSettings).toMatchObject({ requirements: {} })
context.parameters.options = {}
})

test('can find solidarity file in module with flag --module', () => {
test('can find solidarity file in module with flag --module', async () => {
context.parameters.options = { module: 'mock_module' }
const resultSettings = getSolidaritySettings(context)
const resultSettings = await getSolidaritySettings(context)
// we got an object with requirements defined
expect(resultSettings).toMatchObject({ requirements: {} })
context.parameters.options = {}
})

test('can find solidarity JSON file in module with flag --module', () => {
test('can find solidarity JSON file in module with flag --module', async () => {
context.parameters.options = { module: 'mock_second_module' }
const resultSettings = getSolidaritySettings(context)
const resultSettings = await getSolidaritySettings(context)
// we got an object with requirements defined
expect(resultSettings).toMatchObject({ requirements: {} })
context.parameters.options = {}
})

test('errors if no solidarity file in module', () => {
test('errors if no solidarity file in module', async () => {
context.parameters.options = { module: 'nope' }
expect(() => {
getSolidaritySettings(context)
}).toThrowError('ERROR: There is no solidarity file found with the given module')
await expect(getSolidaritySettings(context))
.rejects
.toThrow('ERROR: There is no solidarity file found with the given module');
context.parameters.options = {}
})

Expand Down
2 changes: 1 addition & 1 deletion __tests__/commands/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ it('enforces required properties', () => {

test('check solidarity create with no parameter', async () => {
await createCommand.run(mockContext)
expect(mockContext.print.error.mock.calls).toEqual([['Missing what to create'], ['solidarity create <wut?>']])
expect(mockContext.print.error.mock.calls).toEqual([['Missing what to create'], ['$ solidarity create <wut?>']])
expect(mockContext.print.info.mock.calls.length).toBe(1)
})

Expand Down
2 changes: 1 addition & 1 deletion __tests__/commands/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test('Calls print items several times', () => {
expect(context.print.success.mock.calls.length).toBe(0)
expect(context.print.colors.magenta.mock.calls.length).toBe(0)
helpCommand.run(context)
expect(context.print.info.mock.calls.length).toBe(8)
expect(context.print.info.mock.calls.length).toBe(9)
expect(context.print.printCommands.mock.calls.length).toBe(1)
expect(context.print.success.mock.calls.length).toBe(2)
expect(context.print.colors.magenta.mock.calls.length).toBe(2)
Expand Down
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- [Additional Info](/README.md#additional-info)
- Comprehensive Docs
- [Solidarity Rules Options](/docs/options.md)
- [Solidarity CLI Options](/docs/cliOptions.md)
- [Writing Plugins](/docs/plugins.md)
- [**All Contributors**](/docs/existingContributors.md)
- Blog Posts
Expand Down
55 changes: 55 additions & 0 deletions docs/cliOptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Solidarity Command Options
A listing of CLI options can be found by passing the `help` command to the CLI.

```
$ solidarity help
Solidarity
Commands
solidarity Check environment against solidarity rules
create (c) Displays this help
help (h) Displays this help
report (r) Report solidarity info about the current machine
snapshot (s) Take a snapshot of the versions and store in solidarity file
Flags
--verbose (-a) Prints all detected info during solidarity check
--moderate (-m) Prints failures in check or single success message
--silent (-s) No output, just a return code of success/failure
--solidarityFile (-f) Use given path to solidarity file for settings
--module (-d) Search for a solidarity file in the given npm package
--stack (-t) Use a known technology stack, and not the local file
Solidarity is open source - https://github.com/infinitered/solidarity
If you need additional help, join our Slack at http://community.infinite.red
```

Here we will go into detail on each option flag.

## verbose (-a)
Passing `--verbose` or `-a` flags will modify output to be verbose.

## moderate (-m)
Passing `--moderate` or `-m` flags will modify output to be moderate, meaning only failures exclusive or a single success will be printed.

## silent (-s)
Passing `--silent` or `-s` flags will modify output to be silent, meaning no output will occur. You'll have to see if the command return is non-zero to see if it failed.

## solidarityFile (-f)
Passing `--solidarityFile` or `-f` flags will direct the file to use for the solidarity check.

> For example: `solidarity -solidarityFile ./my/special/file.json` will run the designated file instead of looking for a local folder Solidarity file.
## module (-m)
Passing `--module` or `-m` flags will modify the designated solidarity file, to run a file found in the given `node_module` stack.

> For example: `solidarity --module smoothReporter` will run the solidarity file in the root of the npm package `smoothReporter` instead of our own.
## stack (-t)
Passing `--stack` or `-t` flags will make our stack look to GitHub for a well known tech stack.

> For example: `solidarity --stack react-native` will check our machine if we are ready to run React Native projects, but not a specific React Native project.
Stacks are community managed and found here: https://github.com/infinitered/solidarity-stacks
2 changes: 1 addition & 1 deletion docs/options.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Solidarity Options
# Solidarity File Options
Understanding the `.solidarity` file helps you read and write new solidarity checks for any project.

If you'd like to get auto-complete, or validation of your JSON rules, you can optionally add the following line to the `.solidarity` file for help in your personal editor.
Expand Down
14 changes: 13 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "solidarity",
"version": "2.1.0",
"version": "2.2.0",
"description": "Make sure all React Native dependencies are uniform across machines",
"repository": "https://github.com/infinitered/solidarity",
"bin": {
Expand Down
Loading

0 comments on commit 64fce79

Please sign in to comment.