Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert Sveltekit to Webstone App #233

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sixty-wombats-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"create-webstone-app": minor
---

add functionality to turn existing sveltekit app to a webstone app
2 changes: 1 addition & 1 deletion .gitpod/tasks/1-webstone-dev/before.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ npm install -g pnpm
gp sync-done pnpm-installed-globally
cd webstone
pnpm install
pnpx playwright install
pnpm playwright install
gp sync-done dependencies-installed
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
"prepare": "husky install",
"release": "changeset publish",
"test": "pnpm test:unit",
"test:e2e": "pnpx playwright test",
"test:e2e:open": "pnpx playwright test --headed",
"test:e2e": "pnpm playwright test",
"test:e2e:open": "pnpm playwright test --headed",
"test:unit": "c8 --all --include=**/src --reporter=html pnpm test:unit:only",
"test:unit:only": "NODE_OPTIONS='--loader tsx' uvu packages tests"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/create-webstone-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"enquirer": "2.3.6",
"execa": "6.1.0",
"fs-extra": "10.1.0",
"listr2": "4.0.5"
"listr2": "4.0.5",
"tempy": "^3.0.0"
}
}
31 changes: 30 additions & 1 deletion packages/create-webstone-app/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import chalk from "chalk";
import fs from "fs-extra";
import path from "path";

import { ListrTaskWrapper, ListrRenderer } from "listr2/dist/index";

const minimalVersion = 405;

export interface Ctx {
appDir: string;
webAppDir?: string;
isSveltekit: boolean;
tempDir: string;
webAppDir: string;
}

export type WebstoneTask = ListrTaskWrapper<Ctx, typeof ListrRenderer>;
Expand Down Expand Up @@ -41,3 +47,26 @@ Next steps:
- ${chalk.bold(chalk.cyan("pnpm ws dev"))}
`);
};

export const isSveltekit = (appDir: string) => {
if (fs.existsSync(path.join(appDir, "package.json"))) {
const packageJson = fs.readJsonSync(path.join(appDir, "package.json"));
if (packageJson.devDependencies["@sveltejs/kit"]) {
return true;
}
}
return false;
};

export const checkCorrectSveltekitVersion = (version: string) => {
const versionRegex = /^1\.0\.0-next\.(\d{3})$/;
const error = Error(
`Please upgrade to a Sveltekit Version greater than 1.0.0-next.${minimalVersion}`
);
if (version === "next") return true;
const matches = version.match(versionRegex);
if (!matches) throw error;
const [, kitVersion] = matches;
if (parseInt(kitVersion) < minimalVersion) throw error;
return true;
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import fs from "fs-extra";
import { ListrTask } from "listr2/dist/index";

import { Ctx, WebstoneTask } from "../../helpers";
import {
checkCorrectSveltekitVersion,
Ctx,
isSveltekit,
WebstoneTask,
} from "../../helpers.js";

const determineAppDirName = async (ctx: Ctx, task: WebstoneTask) => {
const appName = process.argv[2];
Expand All @@ -16,6 +21,24 @@ export const createAppDir = async (ctx: Ctx, task: WebstoneTask) => {
const appDir = ctx.appDir;

if (fs.existsSync(appDir)) {
if (isSveltekit(appDir)) {
ctx.isSveltekit = true;
const isSveltekitResponse = await task.prompt({
type: "Confirm",
message:
"This directory already contains a Sveltekit project. Do you want to turn the existing project to a webstone app?",
initial: false,
});
if (!isSveltekitResponse) {
throw new Error("Exiting, app is already a Sveltekit project");
}
checkCorrectSveltekitVersion(
fs.readJsonSync(`${appDir}/package.json`).devDependencies[
"@sveltejs/kit"
]
);
return appDir;
}
if (fs.readdirSync(appDir).length > 0) {
const response = await task.prompt({
type: "confirm",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,31 @@ import fs from "fs-extra";
import path, { dirname } from "path";
import { ListrTask } from "listr2/dist/index";
import { fileURLToPath } from "url";
import { temporaryDirectory } from "tempy";

const ignorePaths = [
"node_modules",
"build",
".svelte-kit",
"package",
"package-lock.json",
"yarn.lock",
Comment on lines +8 to +13
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would we handle this? I think we can take the .gitignore as reference for folders and files that don't matter when copying. The question are lockfiles from package managers: Do we delete them? As we are using the pnpm we can't keep then, but this might cause trouble when installing the project dependencies. What do you think @mikenikles?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fair to say this is no longer an issue once we merge #247, agreed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep!

];

import { Ctx } from "../../helpers";

const __dirname = dirname(fileURLToPath(import.meta.url));

export const copyTemplate = (ctx: Ctx) => {
ctx.webAppDir = `${ctx.appDir}/services/web`;
if (ctx.isSveltekit) {
ctx.tempDir = temporaryDirectory({ prefix: "webstone" });
ignorePaths.forEach((pathString: string) => {
fs.existsSync(path.join(ctx.appDir, pathString)) &&
fs.rmdirSync(path.join(ctx.appDir, pathString));
});
fs.moveSync(ctx.appDir, ctx.tempDir, { overwrite: true });
}
const templateDir = path.join(__dirname, "../../..", "template");
fs.copySync(templateDir, ctx.appDir);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import { Ctx } from "../../helpers";

const initWebApp = async (ctx: Ctx) => {
const webAppDir = `${ctx.appDir}/services/web`;
ctx.webAppDir = webAppDir;
console.log(`Installing web app in ${webAppDir}...`);

if (ctx.isSveltekit) {
fs.emptyDirSync(ctx.webAppDir);
fs.moveSync(ctx.tempDir, ctx.webAppDir, { overwrite: true });
fs.removeSync(ctx.tempDir);
return;
}
try {
fs.removeSync(`${webAppDir}/.keep`);

Expand Down
12 changes: 6 additions & 6 deletions packages/create-webstone-app/tests/helpers/create-app-dir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test("app dir does not exist, no app dir provided", async () => {
output: "",
};

const fakeContext: Ctx = {
const fakeContext: Partial<Ctx> = {
appDir: ".",
};

Expand Down Expand Up @@ -51,7 +51,7 @@ test("app dir does not exist, app dir with space", async () => {
output: "",
};

const fakeContext: Ctx = {
const fakeContext: Partial<Ctx> = {
appDir: "test-app",
};
const fakeFsExistsSync = sinon.fake.returns(false);
Expand All @@ -72,7 +72,7 @@ test("app dir does not exist", async () => {
output: "",
};

const fakeContext: Ctx = {
const fakeContext: Partial<Ctx> = {
appDir: "test-app",
};

Expand All @@ -94,7 +94,7 @@ test("app dir exists and is empty", async () => {
output: "",
};

const fakeContext: Ctx = {
const fakeContext: Partial<Ctx> = {
appDir: "test-app",
};

Expand All @@ -121,7 +121,7 @@ test("app dir exists and is not empty, overwrite it", async () => {
prompt: fakeListrPrompt,
};

const fakeContext: Ctx = {
const fakeContext: Partial<Ctx> = {
appDir: "test-app",
};
const fakeFsExistsSync = sinon.fake.returns(true);
Expand Down Expand Up @@ -153,7 +153,7 @@ test("app dir exists and is not empty, do not overwrite it", async () => {
prompt: fakeListrPrompt,
};

const fakeContext: Ctx = {
const fakeContext: Partial<Ctx> = {
appDir: "test-app",
};
const fakeFsExistsSync = sinon.fake.returns(true);
Expand Down
67 changes: 67 additions & 0 deletions packages/create-webstone-app/tests/helpers/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import sinon from "sinon";
import { test } from "uvu";
import * as assert from "uvu/assert";
import fs from "fs-extra";
import { isSveltekit, checkCorrectSveltekitVersion } from "../../src/helpers";

test.before.each(() => {
sinon.replace(console, "log", sinon.fake());
});

test.after.each(() => {
sinon.restore();
});

test("successfully recognize Sveltekit app", async () => {
const fakePackageJson = {
devDependencies: {
"@sveltejs/kit": "1.0.0-next.999",
},
};
const fakeReadJsonSync = sinon.fake.returns(fakePackageJson);
const fakeExists = sinon.fake.returns(true);

sinon.replace(fs, "readJsonSync", fakeReadJsonSync);
sinon.replace(fs, "existsSync", fakeExists);

assert.equal(isSveltekit("testapp"), true);
});

test("recognize, that project is not a sveltekit app", async () => {
const fakePackageJson = {
devDependencies: {
react: "16.8.6",
},
};

const fakeExists = sinon.fake.returns(true);
const fakeReadJsonSync = sinon.fake.returns(fakePackageJson);
sinon.replace(fs, "readJsonSync", fakeReadJsonSync);
sinon.replace(fs, "existsSync", fakeExists);

assert.equal(isSveltekit("testapp"), false);
});

test("no package.json provided", async () => {
const fakeExists = sinon.fake.returns(false);
sinon.replace(fs, "existsSync", fakeExists);

assert.equal(isSveltekit("testapp"), false);
});

test("wrong version of sveltekit", async () => {
try {
checkCorrectSveltekitVersion("1.0.0.next.0");
} catch (e) {
assert.match(
e.message,
/Please upgrade to a Sveltekit Version greater than 1.0.0-next.\d{3}/
);
}
});

test("correct version of sveltekit", async () => {
assert.ok(checkCorrectSveltekitVersion("1.0.0-next.999"));
});

test.run();
41 changes: 41 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.