Skip to content

Commit

Permalink
feat: pass config file in CLI options
Browse files Browse the repository at this point in the history
BREAKING CHANGE: wrong parameters in config files now throw errors
  • Loading branch information
msanguineti committed Nov 18, 2019
1 parent 17daa6b commit 956ae30
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 44 deletions.
47 changes: 24 additions & 23 deletions __tests__/core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,11 @@ describe('testing core functionalities', () => {
expect(defaults.integration).toEqual(1)
})

test('load default values if no config files - part I', () => {
const defaults = core.loadConfigFile()

expect(defaults.main).toMatch('master')
expect(defaults.usedev).not.toBeTruthy()
expect(defaults.integration).toEqual(1)
test('throw if no config file is found', () => {
expect(() => core.loadConfigFile()).toThrow(/^Cannot load/)
})

test('load default values if no config files - part II', () => {
test('load default values if no default config files are found', () => {
const defaults = core.loadConfigValues()

expect(defaults.main).toMatch('master')
Expand Down Expand Up @@ -66,10 +62,7 @@ describe('testing core functionalities', () => {
}`
).to(tempConfigFile)

const defaults = core.loadConfigFile(tempConfigFile)

expect(defaults).toBeDefined()
expect(defaults.development).toMatch('develop')
expect(() => core.loadConfigFile(tempConfigFile)).toThrow(/^development/)
})

test('write to (and load from) .js file', () => {
Expand All @@ -95,27 +88,35 @@ describe('testing core functionalities', () => {
})

test('config value for a branch name is invalid', () => {
core.writeConfigFile({
data: { development: 'akn//&&svn...#k/' }
})
expect(() =>
core.writeConfigFile({
data: { development: 'akn//&&svn...#k/' }
})
).toThrow(/^development/)
})

test('config value usedev is invalid', () => {
core.writeConfigFile({
data: { usedev: 'true' }
})
expect(() =>
core.writeConfigFile({
data: { usedev: 'true' }
})
).toThrow(/^usedev/)
})

test('config value push is invalid', () => {
core.writeConfigFile({
data: { push: 'maybe' }
})
expect(() =>
core.writeConfigFile({
data: { push: 'maybe' }
})
).toThrow(/^push/)
})

test('config value integration is invalid', () => {
core.writeConfigFile({
data: { integration: 4 }
})
expect(() =>
core.writeConfigFile({
data: { integration: 4 }
})
).toThrow(/^integration/)
})
})

Expand Down
8 changes: 6 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ const argv = yargs
.command(new Feature())
.command(new Release())
.command(new Hotfix())
.option('c', {
alias: 'config',
type: 'string',
description: 'Config file to use'
})
.help()
.alias('h', 'help').argv

if (argv._.length <= 0) {
if (argv._.length <= 0)
console.log(warning(`Try ${basename(process.argv[1])} --help`))
}
2 changes: 1 addition & 1 deletion src/cmds/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ export class Feature implements CommandModule {
return yargs.command(new StartFeature()).command(new FinishFeature())
}

public handler = (): void => {}
public handler = () => {}
}
4 changes: 3 additions & 1 deletion src/cmds/feature/finish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { spawnSync } from 'child_process'
import { prompt } from 'inquirer'
import { exec } from 'shelljs'
import { Arguments, Argv, CommandModule } from 'yargs'
import { isValidBranchName } from '../../core'
import { isValidBranchName, loadConfigFile } from '../../core'

export class FinishFeature implements CommandModule {
public command: string = 'finish <featureBranch> [options]'
Expand All @@ -25,6 +25,8 @@ export class FinishFeature implements CommandModule {
}

public handler = (argv: Arguments) => {
if (argv.c) loadConfigFile(argv.c as string)

const mergeInto = argv.usedev ? argv.development : argv.main
if (isValidBranchName(mergeInto)) return handleFinish(argv, mergeInto)
}
Expand Down
4 changes: 3 additions & 1 deletion src/cmds/feature/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
*/
import { exec } from 'shelljs'
import { Arguments, CommandModule } from 'yargs'
import { isValidBranchName } from '../../core'
import { isValidBranchName, loadConfigFile } from '../../core'

export class StartFeature implements CommandModule {
public command: string = 'start <featureBranch>'

public describe: string = 'Start a new feature'

public handler = (argv: Arguments) => {
if (argv.c) loadConfigFile(argv.c as string)

const branchOff = argv.usedev ? argv.development : argv.main

if (
Expand Down
3 changes: 3 additions & 0 deletions src/cmds/hotfix/finish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import { prompt } from 'inquirer'
import { exec } from 'shelljs'
import { Arguments, CommandModule } from 'yargs'
import { info } from '../../utils/text'
import { loadConfigFile } from '../../core'

export class FinishHotfix implements CommandModule {
public command: string = 'finish <hotfixName>'

public describe: string = 'Finishes a hotfix.'

public handler = (argv: Arguments): Promise<void> => {
if (argv.c) loadConfigFile(argv.c as string)

return handleFinish(argv)
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/cmds/hotfix/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { exec } from 'shelljs'
import { Arguments, CommandModule } from 'yargs'
import { isValidBranchName } from '../../core'
import { isValidBranchName, loadConfigFile } from '../../core'

export class StartHotfix implements CommandModule {
public command: string = 'start <hotfixName> <from>'
Expand All @@ -17,6 +17,8 @@ export class StartHotfix implements CommandModule {
<from> should be a branch (e.g. develop), a tag (e.g. 2.3.0) or a commit (e.g. 9af345)`

public handler = (argv: Arguments): void => {
if (argv.c) loadConfigFile(argv.c as string)

if (
isValidBranchName(argv.hotfixName) &&
(argv.from ? isValidBranchName(argv.from) : true)
Expand Down
3 changes: 3 additions & 0 deletions src/cmds/release/finish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { prompt } from 'inquirer'
import { exec } from 'shelljs'
import { Arguments, CommandModule } from 'yargs'
import { info } from '../../utils/text'
import { loadConfigFile } from '../../core'

export class FinishRelease implements CommandModule {
public command: string = 'finish <releaseName>'
Expand All @@ -21,6 +22,8 @@ export class FinishRelease implements CommandModule {
}

const handleFinish = async (argv: Arguments) => {
if (argv.c) loadConfigFile(argv.c as string)

const mergeInto = argv.usedev ? argv.development : argv.main

exec(`git checkout ${argv.release}/${argv.releaseName}`)
Expand Down
4 changes: 3 additions & 1 deletion src/cmds/release/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { exec } from 'shelljs'
import { Arguments, CommandModule } from 'yargs'
import { isValidBranchName } from '../../core'
import { isValidBranchName, loadConfigFile } from '../../core'

export class StartRelease implements CommandModule {
public command: string = 'start <releaseName> <from>'
Expand All @@ -17,6 +17,8 @@ export class StartRelease implements CommandModule {
<from> should be a branch (e.g. develop) or a commit (e.g. 9af345)`

public handler = (argv: Arguments): void => {
if (argv.c) loadConfigFile(argv.c as string)

if (
isValidBranchName(argv.releaseName) &&
(argv.from ? isValidBranchName(argv.from) : true)
Expand Down
35 changes: 22 additions & 13 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,16 @@ export const getDefaultConfigValues = (): ConfigValues => {
*/
export const loadConfigFile = (configFile?: string): ConfigValues => {
if (!configFile || !test('-f', configFile)) {
return defaultConfigValues
throw new Error(`Cannot load configuration values from: ${configFile}`)
}

const configValues =
getFileExt(configFile) === '.js'
? require(configFile)
: JSON.parse(sed(/(\/\*[\w\W]+\*\/|(\/\/.*))/g, '', configFile))

if (sanityCheck(configValues)) {
return { ...defaultConfigValues, ...configValues }
} else {
return { ...defaultConfigValues }
}
sanityCheck(configValues)
return { ...defaultConfigValues, ...configValues }
}

/**
Expand All @@ -73,6 +70,8 @@ export const loadConfigFile = (configFile?: string): ConfigValues => {
export const loadConfigValues = (): ConfigValues => {
const configFile = findUp.sync(defaultConfigFileNames) || undefined

if (!configFile) return defaultConfigValues

return loadConfigFile(configFile)
}

Expand All @@ -92,7 +91,7 @@ export const writeConfigFile = ({
}): boolean => {
let toWrite: string

if (!sanityCheck(data)) return false
sanityCheck(data)

switch (getFileExt(file)) {
case '.js':
Expand Down Expand Up @@ -139,17 +138,23 @@ const sanityCheck = (configValues: ConfigValues): boolean => {
case 'release':
case 'feature':
if (!isValidBranchName(element)) {
return false
throw new Error(
`${key} branch name is invalid. Value found: ${element}`
)
}
break
case 'usedev':
if (typeof element !== 'boolean') {
return false
throw new Error(
`${key} has to be either 'true' or 'false'. Value found: ${element}`
)
}
break
case 'integration':
if (typeof element !== 'number' || (element < 1 || element > 3)) {
return false
throw new Error(
`${key} has to be a number >=1 and <=3. Value found: ${element}`
)
}
break
case 'interactive':
Expand All @@ -159,12 +164,16 @@ const sanityCheck = (configValues: ConfigValues): boolean => {
typeof element !== 'string' ||
!element.match(/(ask|always|never)/)
) {
return false
throw new Error(
`${key} has to be either 'ask', 'always' or 'never'. Value found: ${element}`
)
}
break
case 'tags':
if (typeof element !== 'boolean') {
return false
throw new Error(
`${key} has to be either 'true' or 'false'. Value found: ${element}`
)
}
break
}
Expand Down Expand Up @@ -200,7 +209,7 @@ const defaultConfigFileName: string = 'gof.config.js'
const defaultConfigFileNames: string[] = [
defaultConfigFileName,
'.gofrc.js',
'.gofrc.json'
'.gofrc'
]

// const supportedExtensions = ['.js', '.json']
Expand Down
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
// Search under node_modules for non-relative imports.
"moduleResolution": "node",
// Process & infer types from .js files.
"allowJs": true,
// "allowJs": true,
// Don't emit; allow Babel to transform files.
"noEmit": true,
// Enable strictest settings like strictNullChecks & noImplicitAny.
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
// Disallow features that require cross-file information for emit.
// "isolatedModules": true,
// Import non-ES modules as default imports.
Expand Down

0 comments on commit 956ae30

Please sign in to comment.