Skip to content

Commit

Permalink
feat: ability to set org context (#268)
Browse files Browse the repository at this point in the history
Related to neondatabase/cloud#13076

Changes
* You can now set org context `neonctl set-context --org-id
org-round-art-46961103`
* This will set the context for `neonctl projects list` and `neonctl
projects create`

**Testing**
![Screenshot 2024-08-12 at 19 44
01](https://github.com/user-attachments/assets/da67acef-8717-4c6d-9219-3b63b2cc731e)

You can also reset the context by calling `neonctl set-context` without
any params
![Screenshot 2024-08-12 at 19 46
10](https://github.com/user-attachments/assets/ee742e8d-5f98-47d8-a6eb-cde4a747d449)
  • Loading branch information
PlayLikeNeverB4 authored Aug 13, 2024
1 parent d89b352 commit 5c855d4
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 35 deletions.
68 changes: 42 additions & 26 deletions mocks/main/projects/GET.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,49 @@ export default function (req, res) {
});

if (req.query.org_id) {
expect(req.query.org_id).toBe('org-2');
expect(['org-2', 'org-3']).toContain(req.query.org_id);

return res.json({
projects: [
{
id: 4,
name: 'Project_4',
created_at: '2019-01-01T00:00:00.000Z',
updated_at: '2019-01-01T00:00:00.000Z',
org_id: 'org-2',
},
{
id: 5,
name: 'Project_5',
created_at: '2019-01-01T00:00:00.000Z',
updated_at: '2019-01-01T00:00:00.000Z',
org_id: 'org-2',
},
{
id: 6,
name: 'Project_6',
created_at: '2019-01-01T00:00:00.000Z',
updated_at: '2019-01-01T00:00:00.000Z',
org_id: 'org-2',
},
],
});
if (req.query.org_id === 'org-2') {
return res.json({
projects: [
{
id: 4,
name: 'Project_4',
created_at: '2019-01-01T00:00:00.000Z',
updated_at: '2019-01-01T00:00:00.000Z',
org_id: 'org-2',
},
{
id: 5,
name: 'Project_5',
created_at: '2019-01-01T00:00:00.000Z',
updated_at: '2019-01-01T00:00:00.000Z',
org_id: 'org-2',
},
{
id: 6,
name: 'Project_6',
created_at: '2019-01-01T00:00:00.000Z',
updated_at: '2019-01-01T00:00:00.000Z',
org_id: 'org-2',
},
],
});
}

if (req.query.org_id === 'org-3') {
return res.json({
projects: [
{
id: 7,
name: 'Project_7',
created_at: '2019-01-01T00:00:00.000Z',
updated_at: '2019-01-01T00:00:00.000Z',
org_id: 'org-3',
},
],
});
}
}

res.json({
Expand Down
68 changes: 62 additions & 6 deletions src/commands/__snapshots__/set_context.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,62 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`set_context > should set the context > get project id overrides context set project 1`] = `
exports[`set_context > can set the context to project and organization at the same time > set-context 1`] = `""`;

exports[`set_context > can set the context to project and organization at the same time > set-context 2`] = `
"{
"projectId": "test_project",
"orgId": "org-2"
}"
`;

exports[`set_context > should set the context to organization > create projects selecting organization from the context 1`] = `
"project:
id: new-project-789012
name: test_project
created_at: 2022-01-01T00:00:00.000Z
org_id: org-2
connection_uris:
- connection_uri: postgres://localhost:5432/test_project
"
`;

exports[`set_context > should set the context to organization > list projects selecting organization from the context 1`] = `
"- id: 4
name: Project_4
created_at: 2019-01-01T00:00:00.000Z
updated_at: 2019-01-01T00:00:00.000Z
org_id: org-2
- id: 5
name: Project_5
created_at: 2019-01-01T00:00:00.000Z
updated_at: 2019-01-01T00:00:00.000Z
org_id: org-2
- id: 6
name: Project_6
created_at: 2019-01-01T00:00:00.000Z
updated_at: 2019-01-01T00:00:00.000Z
org_id: org-2
"
`;

exports[`set_context > should set the context to organization > list projects with explicit org id overrides context 1`] = `
"- id: 7
name: Project_7
created_at: 2019-01-01T00:00:00.000Z
updated_at: 2019-01-01T00:00:00.000Z
org_id: org-3
"
`;

exports[`set_context > should set the context to organization > set-context 1`] = `""`;

exports[`set_context > should set the context to organization > set-context 2`] = `
"{
"orgId": "org-2"
}"
`;

exports[`set_context > should set the context to project > get project id overrides context set project 1`] = `
"id: project-id-123
name: project name 123
created_at: 2019-01-01T00:00:00Z
Expand All @@ -12,7 +68,7 @@ settings:
"
`;

exports[`set_context > should set the context > list branches selecting project from the context 1`] = `
exports[`set_context > should set the context to project > list branches selecting project from the context 1`] = `
"- id: br-main-branch-123456
name: main
default: true
Expand Down Expand Up @@ -41,7 +97,7 @@ exports[`set_context > should set the context > list branches selecting project
"
`;

exports[`set_context > should set the context > set the branchId and projectId is from context 1`] = `
exports[`set_context > should set the context to project > set the branchId and projectId is from context 1`] = `
"- name: db1
owner_name: user1
- name: db2
Expand All @@ -51,11 +107,11 @@ exports[`set_context > should set the context > set the branchId and projectId i
"
`;

exports[`set_context > should set the context > set the branchId and projectId is from context 2`] = `""`;
exports[`set_context > should set the context to project > set the branchId and projectId is from context 2`] = `""`;

exports[`set_context > should set the context > set-context 1`] = `""`;
exports[`set_context > should set the context to project > set-context 1`] = `""`;

exports[`set_context > should set the context > set-context 2`] = `
exports[`set_context > should set the context to project > set-context 2`] = `
"{
"projectId": "test"
}"
Expand Down
79 changes: 78 additions & 1 deletion src/commands/set_context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const test = originalTest.extend<{
});

describe('set_context', () => {
describe('should set the context', () => {
describe('should set the context to project', () => {
test('set-context', async ({ testCliCommand, readFile }) => {
await testCliCommand([
'set-context',
Expand Down Expand Up @@ -124,4 +124,81 @@ describe('set_context', () => {
);
});
});

describe('should set the context to organization', () => {
test('set-context', async ({ testCliCommand, readFile }) => {
await testCliCommand([
'set-context',
'--org-id',
'org-2',
'--context-file',
CONTEXT_FILE,
]);
expect(readFile(CONTEXT_FILE)).toMatchSnapshot();
});

test('list projects selecting organization from the context', async ({
testCliCommand,
writeFile,
}) => {
writeFile(CONTEXT_FILE, {
orgId: 'org-2',
});
await testCliCommand([
'projects',
'list',
'--context-file',
CONTEXT_FILE,
]);
});

test('list projects with explicit org id overrides context', async ({
testCliCommand,
writeFile,
}) => {
writeFile(CONTEXT_FILE, {
orgId: 'org-2',
});
await testCliCommand([
'project',
'list',
'--org-id',
'org-3',
'--context-file',
CONTEXT_FILE,
]);
});

test('create projects selecting organization from the context', async ({
testCliCommand,
writeFile,
}) => {
writeFile(CONTEXT_FILE, {
orgId: 'org-2',
});
await testCliCommand([
'projects',
'create',
'--name',
'test_project',
'--context-file',
CONTEXT_FILE,
]);
});
});

describe('can set the context to project and organization at the same time', () => {
test('set-context', async ({ testCliCommand, readFile }) => {
await testCliCommand([
'set-context',
'--project-id',
'test_project',
'--org-id',
'org-2',
'--context-file',
CONTEXT_FILE,
]);
expect(readFile(CONTEXT_FILE)).toMatchSnapshot();
});
});
});
14 changes: 12 additions & 2 deletions src/commands/set_context.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import yargs from 'yargs';
import { Context, updateContextFile } from '../context.js';
import { BranchScopeProps } from '../types.js';
import { CommonProps } from '../types.js';

type SetContextProps = {
projectId?: string;
orgId?: string;
};

export const command = 'set-context';
export const describe = 'Set the current context';
Expand All @@ -10,11 +15,16 @@ export const builder = (argv: yargs.Argv) =>
describe: 'Project ID',
type: 'string',
},
'org-id': {
describe: 'Organization ID',
type: 'string',
},
});

export const handler = (props: BranchScopeProps) => {
export const handler = (props: CommonProps & SetContextProps) => {
const context: Context = {
projectId: props.projectId,
orgId: props.orgId,
};
updateContextFile(props.contextFile, context);
};
4 changes: 4 additions & 0 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { normalize, resolve } from 'node:path';
import yargs from 'yargs';

export type Context = {
orgId?: string;
projectId?: string;
branchId?: string;
};
Expand Down Expand Up @@ -48,6 +49,9 @@ export const enrichFromContext = (
return;
}
const context = readContextFile(args.contextFile);
if (!args.orgId) {
args.orgId = context.orgId;
}
if (!args.projectId) {
args.projectId = context.projectId;
}
Expand Down

0 comments on commit 5c855d4

Please sign in to comment.