Skip to content

Commit

Permalink
fix: issue with not reading spec file in working directory when no gl…
Browse files Browse the repository at this point in the history
…obal context is created (#48)
  • Loading branch information
Souvikns authored Aug 17, 2021
1 parent 1988012 commit b7b831e
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 10 deletions.
12 changes: 12 additions & 0 deletions src/hooks/cli/hook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { CLIService } from './service';
import { container } from 'tsyringe';

export interface useCliOutput {
command: string,
args: any
}

export const useCli = (): useCliOutput => {
const cliService: CLIService = container.resolve(CLIService);
return { command: cliService.command(), args: cliService.args() };
};
2 changes: 2 additions & 0 deletions src/hooks/cli/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './hook';
export * from './service';
16 changes: 16 additions & 0 deletions src/hooks/cli/service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import meow from 'meow';
import { injectable } from 'tsyringe';

injectable();
export class CLIService {
private _cli = meow('', { argv: process.argv.slice(2), autoHelp: false })

command(): string {
return this._cli.input[0] || '';
}

args(): any {
return this._cli.flags;
}
}

30 changes: 21 additions & 9 deletions src/hooks/context/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Context, ContextFileNotFoundError, ContextNotFoundError, MissingCurrentContextError } from './models';
import { Context, ContextFileNotFoundError, ContextNotFoundError, MissingCurrentContextError, NoSpecPathFoundError } from './models';
import { ContextService } from './contextService';
import { container } from 'tsyringe';
import { SpecificationFile } from '../validation';
import * as messages from '../../messages';
import { CLIService } from '../cli';

export type Result = {
response?: any,
Expand Down Expand Up @@ -125,10 +126,12 @@ export interface useSpecFileOutput {

export const useSpecfile = (flags: useSpecFileInput): useSpecFileOutput => {
const contextService: ContextService = container.resolve(ContextService);
const cliService: CLIService = container.resolve(CLIService);
let specFile: SpecificationFile;

try {
if (flags.file) {
const specFile: SpecificationFile = new SpecificationFile(flags.file);
specFile = new SpecificationFile(flags.file);
if (specFile.isNotValid()) { throw new Error('Invalid spec path'); }
return { specFile };
}
Expand All @@ -138,25 +141,34 @@ export const useSpecfile = (flags: useSpecFileInput): useSpecFileOutput => {
if (flags.context) {
const ctxFile = ctx.store[flags.context];
if (!ctxFile) { throw new ContextNotFoundError(flags.context); }
const specFile = new SpecificationFile(ctxFile);
specFile = new SpecificationFile(ctxFile);
return { specFile };
}

if (ctx.current) {
const currentFile = ctx.store[ctx.current];
if (!currentFile) { throw new MissingCurrentContextError(); }
const specFile = new SpecificationFile(currentFile);
specFile = new SpecificationFile(currentFile);
return { specFile };
}

const autoDetectedSpecPath = contextService.autoDetectSpecFile();

if (typeof autoDetectedSpecPath === 'undefined') { throw new Error('No spec path found in your working directory, please use flags or store a context'); }

const specFile = new SpecificationFile(autoDetectedSpecPath);
specFile = autoDetectSpecFileInWorkingDir(contextService.autoDetectSpecFile(), cliService.command());

return { specFile };
} catch (error) {
if (error instanceof ContextFileNotFoundError) {
try {
specFile = autoDetectSpecFileInWorkingDir(contextService.autoDetectSpecFile(), cliService.command());
return { specFile };
} catch (error) {
return { error };
}
}
return { error };
}
};

const autoDetectSpecFileInWorkingDir = (specFile: string | undefined, command: string): SpecificationFile => {
if (typeof specFile === 'undefined') { throw new NoSpecPathFoundError(command); }
return new SpecificationFile(specFile);
};
7 changes: 7 additions & 0 deletions src/hooks/context/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ export class MissingArgumentstError extends Error {
this.message = messages.MISSING_ARGUMENTS;
}
}

export class NoSpecPathFoundError extends Error {
constructor(command: string) {
super();
this.message = messages.NO_SPEC_FOUND(command);
}
}
9 changes: 8 additions & 1 deletion src/messages.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable security/detect-object-injection */
export const NO_CONTEXTS_SAVED = 'No contexts saved yet, run asyncapi --help to learn more';

export const CONTEXT_NOT_FOUND = (contextName: string) => `Context ${contextName} does not exists.`;
Expand All @@ -6,11 +7,17 @@ export const MISSING_CURRENT_CONTEXT = 'No context is set as current, please set

export const MISSING_ARGUMENTS = 'Missing arguments.';

export const NEW_CONTEXT_ADDED = (contextName: string) => `New context added.\n\nYou can set it as your current context:\n asyncapi context use ${contextName}\nYou can use this context when needed with --context flag: asyncapi validate --context ${contextName}`;
export const NEW_CONTEXT_ADDED = (contextName: string) => `New context added.\n\nYou can set it as your current context: asyncapi context use ${contextName}\nYou can use this context when needed with --context flag: asyncapi validate --context ${contextName}`;

export const CONTEXT_DELETED = 'context deleted successfully';

export const ValidationMessage = (filePath: string) => ({
error: () => `File: ${filePath} does not exists or is not a file!`,
message: () => `File: ${filePath} successfully validated!`
});

export const NO_SPEC_FOUND = (command: string) => `${FALLBACK_MESSAGES[command]}\n\nThese are your options to specify in the CLI what AsyncAPI file should be used:\n- You can use --file flag to provide a path to the AsyncAPI file: asyncapi ${command} --file path/to/file/asyncapi.yml\n- You can use --context flag to provide a name of the context that points to your AsyncAPI file: asyncapi ${command} --context mycontext\n- In case you did not specify a context that you want to use, the CLI checks if there is a default context and uses it. To set default context run: asyncapi context use mycontext\n- In case you did not provide any reference to AsyncAPI file and there is no default context, the CLI detects if in your current working directory you have files like asyncapi.json, asyncapi.yaml, asyncapi.yml. Just rename your file accordingly.`;

export const FALLBACK_MESSAGES: {[name: string]: string} = {
validate: 'Unable to perform validation. Specify what AsyncAPI file should be validated.'
};

0 comments on commit b7b831e

Please sign in to comment.