Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: issue with not reading spec file in working directory when no global context is created #48

Merged
merged 5 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions src/hooks/context/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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';
Expand Down Expand Up @@ -125,10 +125,11 @@ export interface useSpecFileOutput {

export const useSpecfile = (flags: useSpecFileInput): useSpecFileOutput => {
const contextService: ContextService = container.resolve(ContextService);
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 +139,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());

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

const autoDetectSpecFileInWorkingDir = (specFile: string | undefined): SpecificationFile => {
if (typeof specFile === 'undefined') { throw new NoSpecPathFoundError(); }
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() {
super();
this.message = messages.NO_SPEC_PATH_FOUND;
}
}
2 changes: 2 additions & 0 deletions src/messages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ export const ValidationMessage = (filePath: string) => ({
error: () => `File: ${filePath} does not exists or is not a file!`,
message: () => `File: ${filePath} successfully validated!`
});

Souvikns marked this conversation as resolved.
Show resolved Hide resolved
export const NO_SPEC_PATH_FOUND = 'No spec path found in your working directory, please use flags or store a context';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to do better here. User, when running asyncapi validate most probably do not have an idea about all our options, defaults, and way we load files, priorities - we need to make it clear. Good help messages are a key for good developer experience.

how about? 👇🏼

Suggested change
export const NO_SPEC_PATH_FOUND = 'No spec path found in your working directory, please use flags or store a context';
export const NO_SPEC_FOUND = 'Unable to perform validation. Specify what AsyncAPI file should be validated.\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 validate --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 validate --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.';

Now, above is just a suggestion of how message should be printed, but from code perspective it should be splitted

Part Unable to perform validation. Specify what AsyncAPI file should be validated. should be only in context of asyncapi validation and the rest of the message should be reusable. Why reusable? because it will be always used in other commands when the same error will happen that there is no file specified, when we will have command asyncapi optimize it will be the same. So you need to make sure that examples that I provided in the message are customizable, in context of validation user see asyncapi validate --file path/to/file/asyncapi.yml, but in context of optimization user will see asyncapi optimize --file path/to/file/asyncapi.yml