-
Notifications
You must be signed in to change notification settings - Fork 355
Expand file tree
/
Copy pathintegration.ts
More file actions
111 lines (88 loc) · 3.78 KB
/
Copy pathintegration.ts
File metadata and controls
111 lines (88 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { Command } from '@commander-js/extra-typings';
import { exec as execCb } from 'child_process';
import { colorize } from 'consola/utils';
import { parse } from 'dotenv';
import { outputFileSync, writeJsonSync } from 'fs-extra/esm';
import kebabCase from 'lodash.kebabcase';
import { coerce, compare } from 'semver';
import { promisify } from 'util';
import { z } from 'zod';
const exec = promisify(execCb);
export const ManifestSchema = z.object({
name: z.string(),
dependencies: z.object({ add: z.array(z.string()) }),
devDependencies: z.object({ add: z.array(z.string()) }),
environmentVariables: z.array(z.string()),
});
type Manifest = z.infer<typeof ManifestSchema>;
export const integration = new Command('integration')
.argument('<integration-name>', 'Formatted name of the integration')
.option('--commit-hash <hash>', 'Override integration source branch with a specific commit hash')
.action(async (integrationNameRaw, options) => {
console.warn(
colorize(
'yellow',
'⚠ `create-catalyst integration` is deprecated and will be replaced by the ' +
'`catalyst upgrade` command.',
),
);
// @todo check for integration name conflicts
const integrationName = z.string().transform(kebabCase).parse(integrationNameRaw);
const manifest: Manifest = {
name: integrationName,
dependencies: { add: [] },
devDependencies: { add: [] },
environmentVariables: [],
};
await exec('git fetch --tags');
const { stdout: headRefStdOut } = await exec('git rev-parse --abbrev-ref HEAD');
let [sourceRef] = headRefStdOut.split('\n');
if (options.commitHash) {
sourceRef = options.commitHash;
}
const { stdout: catalystTags } = await exec('git tag --list @bigcommerce/catalyst-core@\\*');
const [latestCoreTag] = catalystTags
.split('\n')
.filter(Boolean)
.sort((a, b) => {
const versionA = coerce(a.replace('@bigcommerce/catalyst-core@', ''));
const versionB = coerce(b.replace('@bigcommerce/catalyst-core@', ''));
if (versionA && versionB) {
return compare(versionA, versionB);
}
return 0;
})
.reverse();
const PackageDependenciesSchema = z.object({
dependencies: z.object({}).passthrough(),
devDependencies: z.object({}).passthrough(),
});
const getPackageDeps = async (ref: string) => {
const { stdout } = await exec(`git show ${ref}:core/package.json`);
return PackageDependenciesSchema.parse(JSON.parse(stdout));
};
const integrationJson = await getPackageDeps(sourceRef);
const latestCoreTagJson = await getPackageDeps(latestCoreTag);
const diffObjectKeys = (a: Record<string, unknown>, b: Record<string, unknown>) => {
return Object.keys(a).filter((key) => !Object.keys(b).includes(key));
};
manifest.dependencies.add = diffObjectKeys(
integrationJson.dependencies,
latestCoreTagJson.dependencies,
);
manifest.devDependencies.add = diffObjectKeys(
integrationJson.devDependencies,
latestCoreTagJson.devDependencies,
);
const { stdout: latestCoreEnv } = await exec(`git show ${latestCoreTag}:core/.env.example`);
const { stdout: integrationEnv } = await exec(`git show ${sourceRef}:core/.env.example`);
manifest.environmentVariables = diffObjectKeys(parse(integrationEnv), parse(latestCoreEnv));
const { stdout: integrationDiff } = await exec(
`git diff ${latestCoreTag}...${sourceRef} -- ':(exclude)core/package.json' ':(exclude)pnpm-lock.yaml'`,
);
outputFileSync(`integrations/${integrationName}/integration.patch`, integrationDiff);
writeJsonSync(`integrations/${integrationName}/manifest.json`, manifest, {
spaces: 2,
});
console.log('Integration created successfully.');
});