Skip to content

Commit

Permalink
Merge pull request #7096 from QwikDev/ds/migrate-v2-use-tags
Browse files Browse the repository at this point in the history
feat: rely on tags to retrieve version of v2 app
  • Loading branch information
shairez authored Nov 26, 2024
2 parents 9ad962e + d3cacaf commit 2a6a959
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 39 deletions.
17 changes: 5 additions & 12 deletions packages/qwik/src/cli/migrate-v2/replace-package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,13 @@ function updateFileContent(path: string, content: string) {
log.info(`"${path}" has been updated`);
}

export function replacePackage(
oldPackageName: string,
newPackageName: string,
newPackageVersion: string
): void {
replacePackageInDependencies(oldPackageName, newPackageName, newPackageVersion);
export function replacePackage(oldPackageName: string, newPackageName: string): void {
replacePackageInDependencies(oldPackageName, newPackageName);

replaceMentions(oldPackageName, newPackageName);
}

function replacePackageInDependencies(
oldPackageName: string,
newPackageName: string,
newPackageVersion: string
) {
function replacePackageInDependencies(oldPackageName: string, newPackageName: string) {
visitNotIgnoredFiles('.', (path) => {
if (basename(path) !== 'package.json') {
return;
Expand All @@ -38,7 +30,8 @@ function replacePackageInDependencies(
packageJson.optionalDependencies ?? {},
]) {
if (oldPackageName in deps) {
deps[newPackageName] = newPackageVersion;
// We keep the old version intentionally. It will be updated later within another step of the migration.
deps[newPackageName] = deps[oldPackageName];
delete deps[oldPackageName];
}
}
Expand Down
17 changes: 8 additions & 9 deletions packages/qwik/src/cli/migrate-v2/run-migration.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import { confirm, intro, isCancel, log } from '@clack/prompts';
import type { AppCommand } from '../utils/app-command';
import { bgMagenta, green } from 'kleur/colors';
import { bgMagenta, bgRed, bold, green } from 'kleur/colors';
import { bye } from '../utils/utils';
import { replacePackage } from './replace-package';
import {
installTsMorph,
removeTsMorphFromPackageJson,
updateDependencies,
} from './update-dependencies';
import { versions } from './versions';
import { replaceImportInFiles } from './rename-import';

export async function runV2Migration(app: AppCommand) {
intro(
`✨ ${bgMagenta(' This command will migrate your Qwik application from v1 to v2 \n')}` +
`✨ ${bgMagenta(' This command will migrate your Qwik application from v1 to v2')}\n` +
`This includes the following: \n` +
` - "@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` +
` - related dependencies will be updated \n`
` - related dependencies will be updated \n\n` +
`${bold(bgRed('Warning: migration tool is experimental and will migrate your application to the "alpha" release of Qwik V2'))}`
);
const proceed = await confirm({
message: 'Do you want to proceed?',
Expand All @@ -29,7 +28,7 @@ export async function runV2Migration(app: AppCommand) {

try {
const installedTsMorph = await installTsMorph();

const { replaceImportInFiles } = await import('./rename-import');
replaceImportInFiles(
[
['QwikCityProvider', 'QwikRouterProvider'],
Expand All @@ -42,10 +41,10 @@ export async function runV2Migration(app: AppCommand) {
'@builder.io/qwik-city'
);

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

if (installedTsMorph) {
await removeTsMorphFromPackageJson();
Expand Down
66 changes: 56 additions & 10 deletions packages/qwik/src/cli/migrate-v2/update-dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,81 @@
import { execSync } from 'node:child_process';
import { installDeps } from '../utils/install-deps';
import { getPackageManager, readPackageJson, writePackageJson } from './../utils/utils';
import { versions } from './versions';
import { packageNames, versionTagPriority } from './versions';
import { major } from 'semver';
import { log, spinner } from '@clack/prompts';

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

for (const key of Object.keys(devDependencies)) {
if (Object.prototype.hasOwnProperty.call(versions, key)) {
devDependencies[key] = versions[key as unknown as keyof typeof versions];
}
}
for (const key of Object.keys(dependencies)) {
if (Object.prototype.hasOwnProperty.call(versions, key)) {
dependencies[key] = versions[key as unknown as keyof typeof versions];
const version = getPackageTag();

for (const name of packageNames) {
if (dependencies[name] || devDependencies[name]) {
delete dependencies[name];
devDependencies[name] = version;
}
}

await writePackageJson(process.cwd(), packageJson);
runInstall();
const loading = spinner();
loading.start(`Updating dependencies...`);
await runInstall();
loading.stop('Dependencies have been updated');
}

/**
* Resolve the list of available package tags for the "@qwik.dev/core" and get the best match of
* ^2.0.0 based on the "versionTagPriority"
*/
function getPackageTag() {
// we assume all migrated packages have the same set of tags
const tags: [tag: string, version: string][] = execSync('npm dist-tag @qwik.dev/core', {
encoding: 'utf-8',
})
?.split('\n')
.filter(Boolean)
.map((data) =>
data
.split(':')
.map((v) => v?.trim())
.filter(Boolean)
)
.filter((v): v is [string, string] => v.length === 2)
.sort((a, b) => {
let aIndex = versionTagPriority.indexOf(a[0]);
let bIndex = versionTagPriority.indexOf(b[0]);
if (aIndex === -1) {
aIndex = Infinity;
} else if (bIndex === -1) {
bIndex = Infinity;
}
return aIndex - bIndex;
});

for (const [, version] of tags) {
if (major(version) === 2) {
return version;
}
}
log.warn('Failed to resolve the Qwik version tag, version "2.0.0" will be installed');
return '2.0.0';
}

export async function installTsMorph() {
const packageJson = await readPackageJson(process.cwd());
if (packageJson.dependencies?.['ts-morph'] || packageJson.devDependencies?.['ts-morph']) {
return false;
}
const loading = spinner();
loading.start('Fetching migration tools..');
(packageJson.devDependencies ??= {})['ts-morph'] = 'latest';
await writePackageJson(process.cwd(), packageJson);
await runInstall();
loading.stop('Migration tools have been loaded');
return true;
}

Expand Down
13 changes: 7 additions & 6 deletions packages/qwik/src/cli/migrate-v2/versions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const versions = {
'@qwik.dev/core': '2.0.0-alpha.1',
'@qwik.dev/router': '2.0.0-alpha.1',
'@qwik.dev/react': '2.0.0-alpha.1',
'eslint-plugin-qwik': '2.0.0-alpha.1',
};
export const versionTagPriority = ['latest', 'v2', 'rc', 'beta', 'alpha'];
export const packageNames = [
'@qwik.dev/core',
'@qwik.dev/router',
'@qwik.dev/react',
'eslint-plugin-qwik',
];
2 changes: 1 addition & 1 deletion scripts/create-qwik-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ async function bundleCreateQwikCli(config: BuildConfig, srcCliDir: string, distC
},
},
],
external: ['prettier', 'typescript'],
external: ['prettier', 'typescript', 'ts-morph', 'semver', 'ignore'],
define: {
'globalThis.CODE_MOD': 'false',
'globalThis.QWIK_VERSION': JSON.stringify(config.distVersion),
Expand Down
2 changes: 1 addition & 1 deletion scripts/submodule-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export async function submoduleCli(config: BuildConfig) {
},
},
],
external: ['prettier', 'typescript'],
external: ['prettier', 'typescript', 'ts-morph', 'semver', 'ignore'],
define: {
'globalThis.CODE_MOD': 'true',
'globalThis.QWIK_VERSION': JSON.stringify(config.distVersion),
Expand Down

0 comments on commit 2a6a959

Please sign in to comment.