Skip to content

Commit

Permalink
fix: allow for hyphen in command id
Browse files Browse the repository at this point in the history
  • Loading branch information
peternhale committed Feb 10, 2023
1 parent 384749b commit 9a17454
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 63 deletions.
3 changes: 2 additions & 1 deletion src/commands/schema/compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {Schema} from 'ts-json-schema-generator'
import {SnapshotCommand} from '../../snapshot-command'
import {getAllFiles, SchemaGenerator, Schemas} from './generate'
import {bold, cyan, red, underline} from 'chalk'
import {getKeyNameFromFilename} from '../../util'

export type SchemaComparison = Array<{ op: Operation; path: (string | number)[]; value: any }>

Expand Down Expand Up @@ -122,7 +123,7 @@ export default class SchemaCompare extends SnapshotCommand {
} else {
for (const file of schemaFiles) {
const schema = JSON.parse(fs.readFileSync(file).toString('utf8')) as Schema
const key = path.basename(file.replace(/-/g, ':')).replace('.json', '')
const key = path.basename(getKeyNameFromFilename(file))
if (file.split(path.sep).includes('hooks')) {
schemas.hooks[key] = schema
} else {
Expand Down
97 changes: 49 additions & 48 deletions src/commands/schema/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import {Flags} from '@oclif/core'
import {createGenerator, Schema} from 'ts-json-schema-generator'
import {SnapshotCommand} from '../../snapshot-command'
import {red} from 'chalk'
import {getSchemaFileName} from '../../util'

export type SchemasMap = {
[key: string]: Schema;
}

export type Schemas = { commands: SchemasMap; hooks: SchemasMap}
export type Schemas = { commands: SchemasMap; hooks: SchemasMap }

export type GenerateResponse = string[];

Expand Down Expand Up @@ -128,7 +129,7 @@ export class SchemaGenerator {

const hooks = this.base.config.pjson.oclif?.hooks ?? {}
const hookId = Object.keys(hooks).find(key => {
const hookFiles = (Array.isArray(hooks[key]) ? hooks[key] : [hooks[key]])as string[]
const hookFiles = (Array.isArray(hooks[key]) ? hooks[key] : [hooks[key]]) as string[]
const hookFileNames = hookFiles.map(f => path.basename(f).split('.')[0])
const currentFileName = path.basename(file).split('.')[0]
return hookFileNames.includes(currentFileName)
Expand Down Expand Up @@ -183,58 +184,58 @@ export class SchemaGenerator {
}

export default class SchemaGenerate extends SnapshotCommand {
public static flags = {
filepath: Flags.string({
description: 'directory to save the generated schema files; can use "{version}" to insert the current CLI/plugin version',
default: './schemas',
}),
singlefile: Flags.boolean({
description: 'put generated schema into a single file',
default: false,
}),
ignorevoid: Flags.boolean({
description: 'ignore commands that return void',
default: true,
}),
};

public async run(): Promise<GenerateResponse> {
const {flags} = await this.parse(SchemaGenerate)
const generator = new SchemaGenerator(this, flags.ignorevoid)

const schemas = await generator.generate()

const directory = flags.filepath.replace('{version}', this.config.version)
fs.mkdirSync(directory, {recursive: true})

const files: string[] = []
if (flags.singlefile) {
const filePath = path.join(directory, 'schema.json')
fs.writeFileSync(filePath, JSON.stringify(schemas, null, 2))
public static flags = {
filepath: Flags.string({
description: 'directory to save the generated schema files; can use "{version}" to insert the current CLI/plugin version',
default: './schemas',
}),
singlefile: Flags.boolean({
description: 'put generated schema into a single file',
default: false,
}),
ignorevoid: Flags.boolean({
description: 'ignore commands that return void',
default: true,
}),
}

public async run(): Promise<GenerateResponse> {
const {flags} = await this.parse(SchemaGenerate)
const generator = new SchemaGenerator(this, flags.ignorevoid)

const schemas = await generator.generate()

const directory = flags.filepath.replace('{version}', this.config.version)
fs.mkdirSync(directory, {recursive: true})

const files: string[] = []
if (flags.singlefile) {
const filePath = path.join(directory, 'schema.json')
fs.writeFileSync(filePath, JSON.stringify(schemas, null, 2))
this.log(`Generated JSON schema file "${filePath}"`)
files.push(filePath)
} else {
for (const [cmdId, schema] of Object.entries(schemas.commands)) {
const fileName = getSchemaFileName(cmdId)
const filePath = path.join(directory, fileName)
fs.writeFileSync(filePath, JSON.stringify(schema, null, 2))
this.log(`Generated JSON schema file "${filePath}"`)
files.push(filePath)
} else {
for (const [cmdId, schema] of Object.entries(schemas.commands)) {
const fileName = `${cmdId.replace(/:/g, '-')}.json`
const filePath = path.join(directory, fileName)
}

if (Object.values(schemas.hooks).length > 0) {
const hooksDir = path.join(directory, 'hooks')
fs.mkdirSync(hooksDir, {recursive: true})
for (const [hookId, schema] of Object.entries(schemas.hooks)) {
const fileName = getSchemaFileName(hookId)
const filePath = path.join(hooksDir, fileName)
fs.writeFileSync(filePath, JSON.stringify(schema, null, 2))
this.log(`Generated JSON schema file "${filePath}"`)
files.push(filePath)
}

if (Object.values(schemas.hooks).length > 0) {
const hooksDir = path.join(directory, 'hooks')
fs.mkdirSync(hooksDir, {recursive: true})
for (const [hookId, schema] of Object.entries(schemas.hooks)) {
const fileName = `${hookId.replace(/:/g, '-')}.json`
const filePath = path.join(hooksDir, fileName)
fs.writeFileSync(filePath, JSON.stringify(schema, null, 2))
this.log(`Generated JSON schema file "${filePath}"`)
files.push(filePath)
}
}
}

return files
}

return files
}
}
22 changes: 22 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as path from 'path'

/**
* Get the file name for a given command ID replacing "-" with "__" and ":" with "-"
* @param cmdId - command ID
* @returns {string} - file name
*/
export const getSchemaFileName = (cmdId: string): string => {
const baseName = cmdId.replace(/-/g, '__').replace(/:/g, '-')
return `${baseName}.json`
}

/**
* Get the command ID from a given file name replacing "-" with ":" and "__" with "-"
* @param file - file name
* @returns {string} - command ID
*/
export const getKeyNameFromFilename = (file: string): string => {
return path.basename(file.replace(/-/g, ':'))
.replace(/__/g, '-')
.replace('.json', '')
}
40 changes: 40 additions & 0 deletions test/util.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {expect} from '@oclif/test'
import {getKeyNameFromFilename} from '../src/util'
import {getSchemaFileName} from '../lib/util'

describe('util test', () => {
describe('getKeyNameFromFilename', () => {
it('should return correct command id when only hyphens in file name a-b-c.json', () => {
expect(getKeyNameFromFilename('a-b-c.json')).to.equal('a:b:c')
})
it('should return correct command id when escaped hyphens in file name a-b-c__d.json', () => {
expect(getKeyNameFromFilename('a-b-c__d.json')).to.equal('a:b:c-d')
})
it('should return correct command id when escaped hyphens in file name a__b-c__d.json', () => {
expect(getKeyNameFromFilename('a__b-c__d.json')).to.equal('a-b:c-d')
})
it('should return correct command id when escaped hyphens in file name a-b__c__d.json', () => {
expect(getKeyNameFromFilename('a-b__c__d.json')).to.equal('a:b-c-d')
})
it('should return correct command id when underscore in file name a-b-c_d.json', () => {
expect(getKeyNameFromFilename('a-b-c_d.json')).to.equal('a:b:c_d')
})
})
describe('getSchemaFileName', () => {
it('should return correct file name when only ":" in command id a:b:c', () => {
expect(getSchemaFileName('a:b:c')).to.equal('a-b-c.json')
})
it('should return correct file name when hyphens in command id a:b:c-d', () => {
expect(getSchemaFileName('a:b:c-d')).to.equal('a-b-c__d.json')
})
it('should return correct file name when hyphens in command id a-b:c-d', () => {
expect(getSchemaFileName('a-b:c-d')).to.equal('a__b-c__d.json')
})
it('should return correct file name when hyphens in command id a:b-c-d', () => {
expect(getSchemaFileName('a:b-c-d')).to.equal('a-b__c__d.json')
})
it('should return correct file name when underscore in command id a:b:c_d', () => {
expect(getSchemaFileName('a:b:c_d')).to.equal('a-b-c_d.json')
})
})
})
16 changes: 2 additions & 14 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3334,16 +3334,11 @@ isarray@^1.0.0, isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=

isbinaryfile@^4.0.10:
isbinaryfile@^4.0.10, isbinaryfile@^4.0.8:
version "4.0.10"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3"
integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==

isbinaryfile@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf"
integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==

isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
Expand Down Expand Up @@ -4862,20 +4857,13 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"

rxjs@^7.0.0:
rxjs@^7.0.0, rxjs@^7.2.0:
version "7.8.0"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4"
integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==
dependencies:
tslib "^2.1.0"

rxjs@^7.2.0:
version "7.5.4"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.4.tgz#3d6bd407e6b7ce9a123e76b1e770dc5761aa368d"
integrity sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==
dependencies:
tslib "^2.1.0"

safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
Expand Down

0 comments on commit 9a17454

Please sign in to comment.