Skip to content

Commit

Permalink
feat(cli): create class for the pull command (#328)
Browse files Browse the repository at this point in the history
  • Loading branch information
y-lakhdar authored Jul 13, 2021
1 parent 0b7c9f8 commit 8ec50e9
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 4 deletions.
62 changes: 62 additions & 0 deletions packages/cli/src/commands/org/config/pull.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {ResourceType} from '@coveord/platform-client';
import {flags, Command} from '@oclif/command';
import {Config} from '../../../lib/config/config';
import {
IsAuthenticated,
Preconditions,
} from '../../../lib/decorators/preconditions';
import {Snapshot} from '../../../lib/snapshot/snapshot';
import {SnapshotFactory} from '../../../lib/snapshot/snapshotFactory';

export default class Pull extends Command {
public static description = 'Pull resources from an organization';

public static flags = {
target: flags.string({
char: 't',
description:
'The unique identifier of the organization from which to pull the resources. If not specified, the organization you are connected to will be used.',
helpValue: 'destinationorganizationg7dg3gd',
required: false,
}),
// TODO: CDX-447: add flag to select resource types to export
};

public static hidden = true;

@Preconditions(IsAuthenticated())
public async run() {
const snapshot = await this.getSnapshot();

await this.refreshProject(snapshot);
await snapshot.delete();
}

private async refreshProject(_snapshot: Snapshot) {
// TODO: CDX-446: refresh project
}

private async getSnapshot() {
const target = await this.getTargetOrg();

return SnapshotFactory.createFromOrg(this.resourceTypesToExport, target);
}

private async getTargetOrg() {
const {flags} = this.parse(Pull);
if (flags.target) {
return flags.target;
}
const cfg = await this.configuration.get();
return cfg.organization;
}

private get configuration() {
return new Config(this.config.configDir, this.error);
}

private get resourceTypesToExport(): ResourceType[] {
// TODO: CDX-447: pass resource types to export
throw new Error('not implemented yet');
}
}
32 changes: 30 additions & 2 deletions packages/cli/src/lib/snapshot/snapshotFactory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ jest.mock('../platform/authenticatedClient');
jest.mock('fs');
jest.mock('./snapshot');

import {ResourceType} from '@coveord/platform-client';
import {createReadStream, ReadStream} from 'fs';
import {join} from 'path';
import {Readable} from 'stream';
Expand All @@ -14,6 +15,7 @@ const mockedCreateReadStream = mocked(createReadStream);
const mockedAuthenticatedClient = mocked(AuthenticatedClient, true);
const mockedSnapshot = mocked(Snapshot, true);
const mockedCreateSnapshotFromFile = jest.fn();
const mockedCreateFromOrganization = jest.fn();
const mockedPushSnapshot = jest.fn();
const mockedDryRunSnapshot = jest.fn();
const mockedGetClient = jest.fn();
Expand Down Expand Up @@ -42,6 +44,7 @@ const doMockAuthenticatedClient = () => {
resourceSnapshot: {
get: mockedGetSnapshot,
createFromFile: mockedCreateSnapshotFromFile,
createFromOrganization: mockedCreateFromOrganization,
push: mockedPushSnapshot,
dryRun: mockedDryRunSnapshot,
},
Expand All @@ -60,7 +63,7 @@ describe('SnapshotFactory', () => {
doMockSnapshot();
});

describe('when the the resources are compressed', () => {
describe('when the snapshot is created from a ZIP', () => {
const pathToZip = join('dummy', 'path');

beforeEach(async () => {
Expand Down Expand Up @@ -93,7 +96,7 @@ describe('SnapshotFactory', () => {
});
});

describe('when creating snapshot from id', () => {
describe('when the snapshot is created from an exisiting one', () => {
const targetId = 'target-id';
const snapshotId = 'snapshot-id';

Expand All @@ -113,4 +116,29 @@ describe('SnapshotFactory', () => {
});
});
});

describe('when the snapshot is created from the organization', () => {
const targetId = 'target-id';

beforeEach(async () => {
const resourcesToExport: ResourceType[] = [
ResourceType.field,
ResourceType.extension,
];
await SnapshotFactory.createFromOrg(resourcesToExport, targetId);
});

it('should create a client connected to the right organization', () => {
expect(mockedGetClient).toHaveBeenCalledWith({
organization: 'target-id',
});
});

it('should create a snapshot with the specified resources', () => {
expect(mockedCreateFromOrganization).toHaveBeenCalledWith(
{resourcesToExport: {EXTENSION: ['*'], FIELD: ['*']}},
expect.objectContaining({})
);
});
});
});
25 changes: 23 additions & 2 deletions packages/cli/src/lib/snapshot/snapshotFactory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
CreateFromFileOptions,
ResourceSnapshotsReportType,
ResourceType,
} from '@coveord/platform-client';
import {createReadStream, ReadStream} from 'fs';
import {AuthenticatedClient} from '../platform/authenticatedClient';
Expand Down Expand Up @@ -50,8 +51,28 @@ export class SnapshotFactory {
return new Snapshot(model, client);
}

public static async createFromOrg() {
// TODO: need 2 instances of AuthenticatedClient: one for the source org, and the other one for the destination org
public static async createFromOrg(
resourceTypesToExport: ResourceType[],
targetOrg: string
) {
const client = await this.getClient(targetOrg);
const resourcesToExport: Partial<Record<ResourceType, string[]>> = {};
resourceTypesToExport.forEach((currentType) => {
resourcesToExport[currentType] = ['*'];
});

const model = await client.resourceSnapshot.createFromOrganization(
{resourcesToExport},
{includeChildrenResources: true, developerNotes: 'Created by Coveo-CLI'}
);

const snapshot = new Snapshot(model, client);

await snapshot.waitUntilDone({
operationToWaitFor: ResourceSnapshotsReportType.CreateSnapshot,
});

return snapshot;
}

private static async getClient(targetOrg: string) {
Expand Down

0 comments on commit 8ec50e9

Please sign in to comment.