Skip to content

Commit

Permalink
feat: support context file location in repository
Browse files Browse the repository at this point in the history
  • Loading branch information
aeworxet committed Jul 4, 2023
1 parent 1b76c88 commit 95a0423
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 53 deletions.
13 changes: 8 additions & 5 deletions docs/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,26 @@ If your use case is that you work with multiple repositories, you might want to

### How to add context to a project

##### Using previously created context file:
##### Manually:
- Create file `.asyncapi-cli` containing [minimal empty context file](#minimalEmptyContextFile) in:
- current directory
- root of current repository
- user's home directory
- Make use of this file by executing command `asyncapi config context add [CONTEXT-NAME] [SPEC-FILE-PATH]`

##### Using CLI's `init` command:

`asyncapi config context init [CONTEXT-FILE-PATH]`

Where `[CONTEXT-FILE-PATH]` instructs CLI what directory should the context file be created in:
- current directory: `asyncapi config context init . (default)`
Where `[CONTEXT-FILE-PATH]` instructs CLI what directory should the file `.asyncapi-cli` containing [minimal empty context file](#minimalEmptyContextFile) be created in:
- current directory: `asyncapi config context init .` (default)
- root of current repository: `asyncapi config context init ./`
- user's home directory: `asyncapi config context init ~`

(if `[CONTEXT-FILE-PATH]` is omitted, empty context file is created in current directory)

If `[CONTEXT-FILE-PATH]` is omitted, the context file is created in current directory.
Make use of newly created `.asyncapi-cli` by executing command:

`asyncapi config context add [CONTEXT-NAME] [SPEC-FILE-PATH]`

### Context File structure

Expand Down
8 changes: 1 addition & 7 deletions src/commands/config/context/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,8 @@ export default class ContextInit extends Command {
async run() {
const { args } = await this.parse(ContextInit);
const contextFilePath = args['context-file-path'];
const contextName = args['context-name'];
const specFilePath = args['spec-file-path'];

const contextWritePath = await initContext(
contextFilePath,
contextName,
specFilePath
);
const contextWritePath = await initContext(contextFilePath);
this.log(`Initialized context ${contextWritePath}`);
}
}
20 changes: 6 additions & 14 deletions src/models/Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,8 @@ export interface ICurrentContext {
readonly context: string;
}

export async function initContext(
contextFilePath: string,
contextName: string,
specFilePath: string
) {
let fileContent: IContextFile = {
export async function initContext(contextFilePath: string) {
const fileContent: IContextFile = {
store: {},
};
let contextWritePath = '';
Expand All @@ -88,6 +84,10 @@ export async function initContext(
case './':
contextWritePath = repoRoot.path + path.sep + CONTEXT_FILENAME;
break;
// There are two variants of `~` case because tilde expansion in UNIX
// systems is not a guaranteed feature - sometimes `~` can return just `~`
// instead of home directory path.
// https://stackoverflow.com/questions/491877/how-to-find-a-users-home-directory-on-linux-or-unix#comment17161699_492669
case os.homedir():
contextWritePath = os.homedir() + path.sep + CONTEXT_FILENAME;
break;
Expand All @@ -98,14 +98,6 @@ export async function initContext(
contextWritePath = process.cwd() + path.sep + CONTEXT_FILENAME;
}

if (contextName && specFilePath) {
fileContent = {
store: {
[String(contextName)]: String(specFilePath),
},
};
}

try {
await writeFile(contextWritePath, JSON.stringify(fileContent), {
encoding: 'utf8',
Expand Down
111 changes: 84 additions & 27 deletions test/commands/context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,32 @@ describe('config:context, positive scenario', () => {
.stdout()
.command(['config:context:current'])
.it('should show current context', (ctx, done) => {
expect(ctx.stdout).toEqual(`${testHelper.context.current}: ${testHelper.context.store['home']}\n`);
expect(ctx.stdout).toEqual(
`${testHelper.context.current}: ${testHelper.context.store['home']}\n`
);
expect(ctx.stderr).toEqual('');
done();
});
});

describe('config:context:list', () => {
test
.stderr()
.stdout()
.command(['config:context:list'])
.it('should list contexts prints list if context file is present', (ctx, done) => {
expect(ctx.stdout).toEqual(
`home: ${path.resolve(__dirname, '../specification.yml')}\ncode: ${path.resolve(__dirname, '../specification.yml')}\n`
);
expect(ctx.stderr).toEqual('');
done();
});
.it(
'should list contexts prints list if context file is present',
(ctx, done) => {
expect(ctx.stdout).toEqual(
`home: ${path.resolve(
__dirname,
'../specification.yml'
)}\ncode: ${path.resolve(__dirname, '../specification.yml')}\n`
);
expect(ctx.stderr).toEqual('');
done();
}
);
});

describe('config:context:add', () => {
Expand All @@ -67,15 +75,18 @@ describe('config:context, positive scenario', () => {
.stderr()
.stdout()
.command(['config:context:add', 'test', './test/specification.yml'])
.it('should NOT add new context with already existing in context file name "test"', (ctx, done) => {
expect(ctx.stdout).toEqual(
''
);
expect(ctx.stderr).toEqual(`ContextError: Context with name "test" already exists in context file "${CONTEXT_FILE_PATH}".\n`);
done();
});
.it(
'should NOT add new context with already existing in context file name "test"',
(ctx, done) => {
expect(ctx.stdout).toEqual('');
expect(ctx.stderr).toEqual(
`ContextError: Context with name "test" already exists in context file "${CONTEXT_FILE_PATH}".\n`
);
done();
}
);
});

describe('config:context:edit', () => {
test
.stderr()
Expand All @@ -94,9 +105,7 @@ describe('config:context, positive scenario', () => {
.stdout()
.command(['config:context:use', 'code'])
.it('should update the current context', (ctx, done) => {
expect(ctx.stdout).toEqual(
'code is set as current\n'
);
expect(ctx.stdout).toEqual('code is set as current\n');
expect(ctx.stderr).toEqual('');
done();
});
Expand All @@ -112,16 +121,62 @@ describe('config:context, positive scenario', () => {
.stdout()
.command(['config:context:remove', 'code'])
.it('should remove existing context', (ctx, done) => {
expect(ctx.stdout).toEqual(
'code successfully deleted\n'
);
expect(ctx.stdout).toEqual('code successfully deleted\n');
expect(ctx.stderr).toEqual('');
done();
});
});

describe('config:context:init', () => {
test
.stderr()
.stdout()
.command(['config:context:init'])
.it('should initialize new empty context file without a switch', (ctx, done) => {
expect(ctx.stdout).toContain('Initialized context');
expect(ctx.stderr).toEqual('');
done();
});
});

describe('config:context:init', () => {
test
.stderr()
.stdout()
.command(['config:context:init', '.'])
.it('should initialize new empty context file with switch "."', (ctx, done) => {
expect(ctx.stdout).toContain('Initialized context');
expect(ctx.stderr).toEqual('');
done();
});
});

describe('config:context:init', () => {
test
.stderr()
.stdout()
.command(['config:context:init', './'])
.it('should initialize new empty context file with switch "./"', (ctx, done) => {
expect(ctx.stdout).toContain('Initialized context');
expect(ctx.stderr).toEqual('');
done();
});
});

describe('config:context:init', () => {
test
.stderr()
.stdout()
.command(['config:context:init', '~'])
.it('should initialize new empty context file with switch "~"', (ctx, done) => {
expect(ctx.stdout).toContain('Initialized context');
expect(ctx.stderr).toEqual('');
done();
});
});
});

describe('config:context, negative scenario', () => {
describe('config:context, negative scenario', () => {
beforeAll(() => {
// Any context file needs to be created before starting test suite,
// otherwise a totally legitimate context file will be created automatically
Expand All @@ -141,7 +196,7 @@ describe('config:context, negative scenario', () => {
.stdout()
.command(['config:context:add', 'home', './test/specification.yml'])
.it(
'should throw error on empty file saying that context file has wrong format.',
'should throw error on zero-sized file saying that context file has wrong format.',
(ctx, done) => {
expect(ctx.stdout).toEqual('');
expect(ctx.stderr).toContain(
Expand Down Expand Up @@ -189,15 +244,17 @@ describe('config:context, negative scenario', () => {
}
);
});

// Totally correct (and considered correct by `@oclif/core`) format of the
// context file
// `{"current":"home","store":{"home":"homeSpecFile","code":"codeSpecFile"}}`
// is considered wrong in `@oclif/test`, limiting possibilities of negative
// scenarios coding.
describe('config:context:add', () => {
testHelper.deleteDummyContextFile();
testHelper.createDummyContextFileWrong('{"current":"home","current2":"test","store":{"home":"homeSpecFile","code":"codeSpecFile"}}');
testHelper.createDummyContextFileWrong(
'{"current":"home","current2":"test","store":{"home":"homeSpecFile","code":"codeSpecFile"}}'
);
test
.stderr()
.stdout()
Expand Down

0 comments on commit 95a0423

Please sign in to comment.