Skip to content

Commit fac6fb2

Browse files
author
Murat
committed
feat(upgrade): added imports prop in upgrade.yml
close #6
1 parent ef84151 commit fac6fb2

File tree

12 files changed

+229
-78
lines changed

12 files changed

+229
-78
lines changed

src/__tests__/unit/utils/upgrade/restoreBackupFiles.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { mockFs } from '../../../mocks/mockFs';
77
describe('restoreBackupFiles', () => {
88
it('should restore backup files in .upgrade', async () => {
99
mockFs.writeFileSync(
10-
path.join(getProjectPath(), '.upgrade/backup/test/some.file'),
10+
path.join(getProjectPath(), '.upgrade/imports/test/some.file'),
1111
'random'
1212
);
1313

@@ -25,7 +25,7 @@ describe('restoreBackupFiles', () => {
2525
});
2626
it('should handle copy error', async () => {
2727
mockFs.writeFileSync(
28-
path.join(getProjectPath(), '.upgrade/backup/test/some.file'),
28+
path.join(getProjectPath(), '.upgrade/imports/test/some.file'),
2929
'random'
3030
);
3131
mockFs.copyFile.mockImplementationOnce(

src/__tests__/unit/utils/upgrade/runUpgradeTasks.spec.ts

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ tasks:
2424
- append: test`
2525
);
2626

27-
const result = await runUpgradeTasks();
27+
const result = await runUpgradeTasks(undefined);
2828

2929
expect(result.didRun).toBeTruthy();
3030
expect(mockRunTask).toHaveBeenCalledWith({
@@ -52,13 +52,13 @@ tasks:
5252
- append: test`
5353
);
5454

55-
const result = await runUpgradeTasks();
55+
const result = await runUpgradeTasks(undefined);
5656

5757
expect(result.didRun).toBeTruthy();
5858
expect(mockRunTask).not.toHaveBeenCalled();
5959
});
6060
it('should handle not finding upgrade.yml', async () => {
61-
const result = await runUpgradeTasks();
61+
const result = await runUpgradeTasks(undefined);
6262

6363
expect(result.didRun).toBeFalsy();
6464
});
@@ -67,7 +67,7 @@ tasks:
6767
path.join(getProjectPath(), '.upgrade/upgrade.yml'),
6868
'random'
6969
);
70-
const result = await runUpgradeTasks();
70+
const result = await runUpgradeTasks(undefined);
7171

7272
expect(result.didRun).toBeFalsy();
7373
});
@@ -82,11 +82,69 @@ tasks:
8282
- append: test`
8383
);
8484

85-
const result = await runUpgradeTasks();
85+
const result = await runUpgradeTasks(undefined);
8686

8787
expect(result.didRun).toBeTruthy();
8888
if (result.didRun) {
8989
expect(result.failedTaskCount).toBe(1);
9090
}
9191
});
92+
it('should execute upgrade.yml imports', async () => {
93+
mockFs.writeFileSync('/oldProject/path/some.file', 'random');
94+
mockFs.writeFileSync(
95+
path.join(getProjectPath(), '.upgrade/upgrade.yml'),
96+
`
97+
imports:
98+
- path
99+
- path/some.file`
100+
);
101+
102+
const result = await runUpgradeTasks('/oldProject');
103+
104+
expect(result.didRun).toBeTruthy();
105+
expect(mockFs.readFileSync(getProjectPath() + '/path/some.file')).toBe(
106+
'random'
107+
);
108+
});
109+
it('should skip non existing upgrade.yml imports', async () => {
110+
mockFs.writeFileSync(
111+
path.join(getProjectPath(), '.upgrade/upgrade.yml'),
112+
`
113+
imports:
114+
- path/some.file`
115+
);
116+
mockFs.lstatSync.mockClear();
117+
const result = await runUpgradeTasks('/oldProject');
118+
119+
expect(result.didRun).toBeTruthy();
120+
expect(mockFs.lstatSync).not.toHaveBeenCalled();
121+
});
122+
it('should skip when no old project path specified', async () => {
123+
mockFs.writeFileSync(
124+
path.join(getProjectPath(), '.upgrade/upgrade.yml'),
125+
`
126+
imports:
127+
- path/some.file`
128+
);
129+
mockFs.lstatSync.mockClear();
130+
const result = await runUpgradeTasks(undefined);
131+
132+
expect(result.didRun).toBeTruthy();
133+
expect(mockFs.lstatSync).not.toHaveBeenCalled();
134+
});
135+
it('should handle copy error', async () => {
136+
mockFs.writeFileSync('/oldProject/path/some.file', 'random');
137+
mockFs.writeFileSync(
138+
path.join(getProjectPath(), '.upgrade/upgrade.yml'),
139+
`
140+
imports:
141+
- path/some.file`
142+
);
143+
mockFs.copyFile.mockImplementationOnce(
144+
(from: string, to: string, cb: CallableFunction) => {
145+
cb(new Error('random'));
146+
}
147+
);
148+
await expect(runUpgradeTasks('/oldProject')).rejects.toThrow('random');
149+
});
92150
});

src/getInfo.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ export async function getInfo(packageName: string): Promise<void> {
8080
if (localPathExists && localConfigPath) {
8181
config = parseConfig(localConfigPath) as IntegrationConfig;
8282
} else if (remoteFileContent)
83-
config = parseConfigString(remoteFileContent) as IntegrationConfig;
83+
config = parseConfigString(
84+
remoteFileContent,
85+
'integrate'
86+
) as IntegrationConfig;
8487
if (config) {
8588
const _config = config;
8689
logSuccess(

src/schema/upgrade.schema.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,16 +1727,19 @@
17271727
"env": {
17281728
"$ref": "#/definitions/AnyObject"
17291729
},
1730+
"imports": {
1731+
"items": {
1732+
"type": "string"
1733+
},
1734+
"type": "array"
1735+
},
17301736
"tasks": {
17311737
"items": {
17321738
"$ref": "#/definitions/ModTask"
17331739
},
17341740
"type": "array"
17351741
}
17361742
},
1737-
"required": [
1738-
"tasks"
1739-
],
17401743
"type": "object"
17411744
}
17421745

src/types/upgrade.types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { AnyObject, ModTask } from './mod.types';
22

33
export type UpgradeConfig = {
44
env?: AnyObject;
5-
tasks: ModTask[];
5+
imports?: string[];
6+
tasks?: ModTask[];
67
};
78

89
export type ImportGetter = {

src/upgrade.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -320,16 +320,16 @@ export async function upgrade(): Promise<void> {
320320

321321
logInfo(
322322
color.bold(color.inverse(color.magenta(' stage 3 '))) +
323-
color.bold(color.magenta(' Restore backup files '))
323+
color.bold(color.magenta(' Import files from .upgrade/imports '))
324324
);
325325

326326
const didRestore = await restoreBackupFiles().catch((e: Error) => {
327327
logWarning(e.message);
328328
});
329329
if (didRestore) {
330330
logSuccess(
331-
color.inverse(color.bold(color.green(' restored '))) +
332-
color.green(' backup files were restored successfully')
331+
color.inverse(color.bold(color.green(' imported '))) +
332+
color.green(' files were imported successfully')
333333
);
334334
}
335335

@@ -338,9 +338,11 @@ export async function upgrade(): Promise<void> {
338338
color.bold(color.magenta(' Execute upgrade.yml tasks '))
339339
);
340340

341-
const upgradeResult = await runUpgradeTasks().catch((e: Error) => {
342-
logWarning(e.message);
343-
});
341+
const upgradeResult = await runUpgradeTasks(oldProjectPath).catch(
342+
(e: Error) => {
343+
logWarning(e.message);
344+
}
345+
);
344346
if (upgradeResult && upgradeResult.didRun) {
345347
if (upgradeResult.failedTaskCount) {
346348
logWarning(

src/utils/parseConfig.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
11
import Ajv from 'ajv';
22
import fs from 'fs';
33
import { parse } from 'yaml';
4+
import { Constants } from '../constants';
45
import integrateYmlSchema from '../schema/integrate.schema.json';
6+
import upgradeYmlSchema from '../schema/upgrade.schema.json';
57

68
const ajv = new Ajv({ allowUnionTypes: true });
7-
const validate = ajv.compile(integrateYmlSchema);
9+
const validateIntegrate = ajv.compile(integrateYmlSchema);
10+
const validateUpgrade = ajv.compile(upgradeYmlSchema);
811

912
export function parseConfig(configPath: string): Record<string, any> {
1013
const configContent = fs.readFileSync(configPath, 'utf8');
11-
return parseConfigString(configContent);
14+
return parseConfigString(
15+
configContent,
16+
configPath.endsWith(Constants.UPGRADE_CONFIG_FILE_NAME)
17+
? 'upgrade'
18+
: 'integrate'
19+
);
1220
}
1321

14-
export function parseConfigString(configContent: string): Record<string, any> {
22+
export function parseConfigString(
23+
configContent: string,
24+
schema: 'integrate' | 'upgrade'
25+
): Record<string, any> {
1526
const config = parse(configContent) as Record<string, any>;
16-
if (!validate(config)) {
17-
throw new Error(validate.errors?.map(e => e.message).join(', '));
27+
if (schema == 'integrate' && !validateIntegrate(config)) {
28+
throw new Error(validateIntegrate.errors?.map(e => e.message).join(', '));
29+
} else if (schema == 'upgrade' && !validateUpgrade(config)) {
30+
throw new Error(validateUpgrade.errors?.map(e => e.message).join(', '));
1831
}
1932
return config;
2033
}

src/utils/upgrade/restoreBackupFiles.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,25 @@ import { getProjectPath } from '../getProjectPath';
1313

1414
export async function restoreBackupFiles(): Promise<boolean> {
1515
const backupFiles = globSync(
16-
[getProjectPath(), Constants.UPGRADE_FOLDER_NAME, 'backup', '**/*'].join(
16+
[getProjectPath(), Constants.UPGRADE_FOLDER_NAME, 'imports', '**/*'].join(
1717
'/'
1818
),
1919
{ nodir: true }
2020
);
2121
if (backupFiles.length === 0) {
22-
logMessageGray('skipped restore, no backup files found');
22+
logMessageGray('skipped restore, found no files to import');
2323
return false;
2424
}
2525

26-
startSpinner(`copying files from ${color.yellow('.upgrade/backup')}`);
26+
startSpinner(`copying files from ${color.yellow('.upgrade/imports')}`);
2727

2828
for (let i = 0; i < backupFiles.length; i++) {
2929
updateSpinner(
30-
`copying files from ${color.yellow('.upgrade/backup')} (${i + 1}/${backupFiles.length})`
30+
`copying files from ${color.yellow('.upgrade/imports')} (${i + 1}/${backupFiles.length})`
3131
);
3232
const file = backupFiles[i];
3333
const relativePath = path.relative(
34-
path.join(getProjectPath(), Constants.UPGRADE_FOLDER_NAME, 'backup'),
34+
path.join(getProjectPath(), Constants.UPGRADE_FOLDER_NAME, 'imports'),
3535
file
3636
);
3737
const destination = path.join(getProjectPath(), relativePath);

0 commit comments

Comments
 (0)