Skip to content

Commit 2a6a959

Browse files
authored
Merge pull request #7096 from QwikDev/ds/migrate-v2-use-tags
feat: rely on tags to retrieve version of v2 app
2 parents 9ad962e + d3cacaf commit 2a6a959

File tree

6 files changed

+78
-39
lines changed

6 files changed

+78
-39
lines changed

packages/qwik/src/cli/migrate-v2/replace-package.ts

+5-12
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,13 @@ function updateFileContent(path: string, content: string) {
99
log.info(`"${path}" has been updated`);
1010
}
1111

12-
export function replacePackage(
13-
oldPackageName: string,
14-
newPackageName: string,
15-
newPackageVersion: string
16-
): void {
17-
replacePackageInDependencies(oldPackageName, newPackageName, newPackageVersion);
12+
export function replacePackage(oldPackageName: string, newPackageName: string): void {
13+
replacePackageInDependencies(oldPackageName, newPackageName);
1814

1915
replaceMentions(oldPackageName, newPackageName);
2016
}
2117

22-
function replacePackageInDependencies(
23-
oldPackageName: string,
24-
newPackageName: string,
25-
newPackageVersion: string
26-
) {
18+
function replacePackageInDependencies(oldPackageName: string, newPackageName: string) {
2719
visitNotIgnoredFiles('.', (path) => {
2820
if (basename(path) !== 'package.json') {
2921
return;
@@ -38,7 +30,8 @@ function replacePackageInDependencies(
3830
packageJson.optionalDependencies ?? {},
3931
]) {
4032
if (oldPackageName in deps) {
41-
deps[newPackageName] = newPackageVersion;
33+
// We keep the old version intentionally. It will be updated later within another step of the migration.
34+
deps[newPackageName] = deps[oldPackageName];
4235
delete deps[oldPackageName];
4336
}
4437
}

packages/qwik/src/cli/migrate-v2/run-migration.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
import { confirm, intro, isCancel, log } from '@clack/prompts';
22
import type { AppCommand } from '../utils/app-command';
3-
import { bgMagenta, green } from 'kleur/colors';
3+
import { bgMagenta, bgRed, bold, green } from 'kleur/colors';
44
import { bye } from '../utils/utils';
55
import { replacePackage } from './replace-package';
66
import {
77
installTsMorph,
88
removeTsMorphFromPackageJson,
99
updateDependencies,
1010
} from './update-dependencies';
11-
import { versions } from './versions';
12-
import { replaceImportInFiles } from './rename-import';
1311

1412
export async function runV2Migration(app: AppCommand) {
1513
intro(
16-
`✨ ${bgMagenta(' This command will migrate your Qwik application from v1 to v2 \n')}` +
14+
`✨ ${bgMagenta(' This command will migrate your Qwik application from v1 to v2')}\n` +
1715
`This includes the following: \n` +
1816
` - "@builder.io/qwik", "@builder.io/qwik-city" and "@builder.io/qwik-react" packages will be rescoped to "@qwik.dev/core", "@qwik.dev/router" and "@qwik.dev/react" respectively \n` +
19-
` - related dependencies will be updated \n`
17+
` - related dependencies will be updated \n\n` +
18+
`${bold(bgRed('Warning: migration tool is experimental and will migrate your application to the "alpha" release of Qwik V2'))}`
2019
);
2120
const proceed = await confirm({
2221
message: 'Do you want to proceed?',
@@ -29,7 +28,7 @@ export async function runV2Migration(app: AppCommand) {
2928

3029
try {
3130
const installedTsMorph = await installTsMorph();
32-
31+
const { replaceImportInFiles } = await import('./rename-import');
3332
replaceImportInFiles(
3433
[
3534
['QwikCityProvider', 'QwikRouterProvider'],
@@ -42,10 +41,10 @@ export async function runV2Migration(app: AppCommand) {
4241
'@builder.io/qwik-city'
4342
);
4443

45-
replacePackage('@builder.io/qwik-city', '@qwik.dev/router', versions['@qwik.dev/router']);
46-
replacePackage('@builder.io/qwik-react', '@qwik.dev/react', versions['@qwik.dev/react']);
44+
replacePackage('@builder.io/qwik-city', '@qwik.dev/router');
45+
replacePackage('@builder.io/qwik-react', '@qwik.dev/react');
4746
// "@builder.io/qwik" should be the last one because it's name is a substring of the package names above
48-
replacePackage('@builder.io/qwik', '@qwik.dev/core', versions['@qwik.dev/core']);
47+
replacePackage('@builder.io/qwik', '@qwik.dev/core');
4948

5049
if (installedTsMorph) {
5150
await removeTsMorphFromPackageJson();

packages/qwik/src/cli/migrate-v2/update-dependencies.ts

+56-10
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,81 @@
1+
import { execSync } from 'node:child_process';
12
import { installDeps } from '../utils/install-deps';
23
import { getPackageManager, readPackageJson, writePackageJson } from './../utils/utils';
3-
import { versions } from './versions';
4+
import { packageNames, versionTagPriority } from './versions';
5+
import { major } from 'semver';
6+
import { log, spinner } from '@clack/prompts';
47

58
export async function updateDependencies() {
69
// TODO(migrate-v2): rely on workspaceRoot instead?
710
const packageJson = await readPackageJson(process.cwd());
811
const devDependencies = (packageJson.devDependencies ??= {});
912
const dependencies = (packageJson.dependencies ??= {});
1013

11-
for (const key of Object.keys(devDependencies)) {
12-
if (Object.prototype.hasOwnProperty.call(versions, key)) {
13-
devDependencies[key] = versions[key as unknown as keyof typeof versions];
14-
}
15-
}
16-
for (const key of Object.keys(dependencies)) {
17-
if (Object.prototype.hasOwnProperty.call(versions, key)) {
18-
dependencies[key] = versions[key as unknown as keyof typeof versions];
14+
const version = getPackageTag();
15+
16+
for (const name of packageNames) {
17+
if (dependencies[name] || devDependencies[name]) {
18+
delete dependencies[name];
19+
devDependencies[name] = version;
1920
}
2021
}
2122

2223
await writePackageJson(process.cwd(), packageJson);
23-
runInstall();
24+
const loading = spinner();
25+
loading.start(`Updating dependencies...`);
26+
await runInstall();
27+
loading.stop('Dependencies have been updated');
28+
}
29+
30+
/**
31+
* Resolve the list of available package tags for the "@qwik.dev/core" and get the best match of
32+
* ^2.0.0 based on the "versionTagPriority"
33+
*/
34+
function getPackageTag() {
35+
// we assume all migrated packages have the same set of tags
36+
const tags: [tag: string, version: string][] = execSync('npm dist-tag @qwik.dev/core', {
37+
encoding: 'utf-8',
38+
})
39+
?.split('\n')
40+
.filter(Boolean)
41+
.map((data) =>
42+
data
43+
.split(':')
44+
.map((v) => v?.trim())
45+
.filter(Boolean)
46+
)
47+
.filter((v): v is [string, string] => v.length === 2)
48+
.sort((a, b) => {
49+
let aIndex = versionTagPriority.indexOf(a[0]);
50+
let bIndex = versionTagPriority.indexOf(b[0]);
51+
if (aIndex === -1) {
52+
aIndex = Infinity;
53+
} else if (bIndex === -1) {
54+
bIndex = Infinity;
55+
}
56+
return aIndex - bIndex;
57+
});
58+
59+
for (const [, version] of tags) {
60+
if (major(version) === 2) {
61+
return version;
62+
}
63+
}
64+
log.warn('Failed to resolve the Qwik version tag, version "2.0.0" will be installed');
65+
return '2.0.0';
2466
}
2567

2668
export async function installTsMorph() {
2769
const packageJson = await readPackageJson(process.cwd());
2870
if (packageJson.dependencies?.['ts-morph'] || packageJson.devDependencies?.['ts-morph']) {
2971
return false;
3072
}
73+
const loading = spinner();
74+
loading.start('Fetching migration tools..');
3175
(packageJson.devDependencies ??= {})['ts-morph'] = 'latest';
76+
await writePackageJson(process.cwd(), packageJson);
3277
await runInstall();
78+
loading.stop('Migration tools have been loaded');
3379
return true;
3480
}
3581

Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
export const versions = {
2-
'@qwik.dev/core': '2.0.0-alpha.1',
3-
'@qwik.dev/router': '2.0.0-alpha.1',
4-
'@qwik.dev/react': '2.0.0-alpha.1',
5-
'eslint-plugin-qwik': '2.0.0-alpha.1',
6-
};
1+
export const versionTagPriority = ['latest', 'v2', 'rc', 'beta', 'alpha'];
2+
export const packageNames = [
3+
'@qwik.dev/core',
4+
'@qwik.dev/router',
5+
'@qwik.dev/react',
6+
'eslint-plugin-qwik',
7+
];

scripts/create-qwik-cli.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async function bundleCreateQwikCli(config: BuildConfig, srcCliDir: string, distC
5858
},
5959
},
6060
],
61-
external: ['prettier', 'typescript'],
61+
external: ['prettier', 'typescript', 'ts-morph', 'semver', 'ignore'],
6262
define: {
6363
'globalThis.CODE_MOD': 'false',
6464
'globalThis.QWIK_VERSION': JSON.stringify(config.distVersion),

scripts/submodule-cli.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export async function submoduleCli(config: BuildConfig) {
3535
},
3636
},
3737
],
38-
external: ['prettier', 'typescript'],
38+
external: ['prettier', 'typescript', 'ts-morph', 'semver', 'ignore'],
3939
define: {
4040
'globalThis.CODE_MOD': 'true',
4141
'globalThis.QWIK_VERSION': JSON.stringify(config.distVersion),

0 commit comments

Comments
 (0)