diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f19cdbde1..8d1e5ef10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,8 +24,28 @@ jobs: - run: pnpm install --frozen-lockfile - run: pnpm test + build-create-waku: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + - uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'pnpm' + cache-dependency-path: '**/pnpm-lock.yaml' + - run: pnpm install --frozen-lockfile + - run: pnpm -r --filter="./packages/create-waku" run compile + - uses: actions/upload-artifact@v4 + with: + name: create-waku + path: packages/create-waku + if-no-files-found: error + e2e: name: E2E on ${{ matrix.os }} (Node ${{ matrix.version }}) - (${{ matrix.shared }}/4) + needs: + - build-create-waku strategy: fail-fast: false matrix: @@ -41,6 +61,10 @@ jobs: node-version: ${{ matrix.version }} cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - uses: actions/download-artifact@v4 + with: + name: create-waku + path: packages/create-waku - run: pnpm install --frozen-lockfile - run: pnpm run compile - name: Cache Playwright diff --git a/e2e/create-waku.spec.ts b/e2e/create-waku.spec.ts new file mode 100644 index 000000000..d4a71c998 --- /dev/null +++ b/e2e/create-waku.spec.ts @@ -0,0 +1,46 @@ +import { spawn } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import crypto from 'node:crypto'; +import { mkdir, readdir } from 'node:fs/promises'; +import { test, debugChildProcess } from './utils.js'; +import { expect } from '@playwright/test'; + +test('should create waku with default setup work', async () => { + const cliPath = fileURLToPath( + new URL('../packages/create-waku/dist/index.js', import.meta.url), + ); + + const dirname = crypto.randomUUID(); + await mkdir(new URL(`./.cache/${dirname}/`, import.meta.url), { + recursive: true, + }); + const cwd = fileURLToPath(new URL(`./.cache/${dirname}`, import.meta.url)); + const cp = spawn(process.execPath, [cliPath], { + cwd, + env: process.env, + }); + debugChildProcess(cp); + const stdin = cp.stdin!; + await new Promise((resolve) => { + cp.stdout!.on('data', (data) => { + const str = data.toString(); + if (str.includes('Project Name')) { + stdin.write('\n'); // use default + } else if (str.includes('Choose a starter template')) { + stdin.write('\n'); // use default + } + if (str.includes('Done.')) { + resolve(); + } + }); + }); + const paths = await readdir(cwd); + expect(paths[0]).toBe('waku-project'); + expect(paths.length).toBe(1); + const files = await readdir( + new URL(`./.cache/${dirname}/waku-project`, import.meta.url), + ); + expect(files).toContain('package.json'); + expect(files).toContain('src'); + expect(files).toContain('tsconfig.json'); +}); diff --git a/packages/create-waku/package.json b/packages/create-waku/package.json index 9bd3425f5..3fc40bd12 100644 --- a/packages/create-waku/package.json +++ b/packages/create-waku/package.json @@ -12,26 +12,25 @@ "directory": "packages/create-waku" }, "bin": { - "create-waku": "./dist/cli.js" + "create-waku": "./dist/index.js" }, "files": [ - "src", "dist", "template" ], "scripts": { - "start": "node dist/cli.js", + "start": "node ./dist/index.js", + "dev": "ncc build ./src/index.ts -w -o ./dist/", "compile": "rm -rf template dist *.tsbuildinfo && pnpm run template && pnpm run build", "template": "cp -r ../../examples template/ && rm -rf template/*/dist && rm -rf template/*/node_modules", - "build": "tsc -b" + "build": "ncc build ./src/index.ts -o ./dist/ --minify --no-cache --no-source-map-register" }, - "dependencies": { + "devDependencies": { + "@types/fs-extra": "^11.0.4", + "@types/prompts": "^2.4.9", + "@vercel/ncc": "^0.38.1", "fs-extra": "^11.2.0", "kolorist": "^1.8.0", "prompts": "^2.4.2" - }, - "devDependencies": { - "@types/fs-extra": "^11.0.4", - "@types/prompts": "^2.4.9" } } diff --git a/packages/create-waku/src/cli.ts b/packages/create-waku/src/index.ts similarity index 94% rename from packages/create-waku/src/cli.ts rename to packages/create-waku/src/index.ts index c0cfc8907..d320e03fe 100644 --- a/packages/create-waku/src/cli.ts +++ b/packages/create-waku/src/index.ts @@ -1,5 +1,4 @@ #!/usr/bin/env node - import { existsSync, readdirSync } from 'node:fs'; import fsPromises from 'node:fs/promises'; import path from 'node:path'; @@ -31,9 +30,14 @@ function canSafelyOverwrite(dir: string) { async function init() { let targetDir = ''; const defaultProjectName = 'waku-project'; - - const templateRoot = fileURLToPath(new URL('../template', import.meta.url)); - const CHOICES = await fsPromises.readdir(templateRoot); + const templateRoot = path.join( + fileURLToPath(import.meta.url), + '../../template', + ); + // maybe include `.DS_Store` on macOS + const CHOICES = (await fsPromises.readdir(templateRoot)).filter( + (dir) => !dir.startsWith('.'), + ); let result: { packageName: string; shouldOverwrite: string; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21128e6de..5f3c50ce2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -694,7 +694,16 @@ importers: version: 0.4.0(@babel/traverse@7.23.6)(@babel/types@7.23.6)(vite@5.0.9) packages/create-waku: - dependencies: + devDependencies: + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 + '@types/prompts': + specifier: ^2.4.9 + version: 2.4.9 + '@vercel/ncc': + specifier: ^0.38.1 + version: 0.38.1 fs-extra: specifier: ^11.2.0 version: 11.2.0 @@ -704,13 +713,6 @@ importers: prompts: specifier: ^2.4.2 version: 2.4.2 - devDependencies: - '@types/fs-extra': - specifier: ^11.0.4 - version: 11.0.4 - '@types/prompts': - specifier: ^2.4.9 - version: 2.4.9 packages/waku: dependencies: @@ -2340,6 +2342,11 @@ packages: - ts-node dev: true + /@vercel/ncc@0.38.1: + resolution: {integrity: sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw==} + hasBin: true + dev: true + /@vitejs/plugin-react@4.2.1(vite@5.0.9): resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -3865,7 +3872,7 @@ packages: graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.1 - dev: false + dev: true /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -4530,7 +4537,7 @@ packages: universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 - dev: false + dev: true /jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} @@ -4551,6 +4558,7 @@ packages: /kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} + dev: true /kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} @@ -4559,7 +4567,7 @@ packages: /kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - dev: false + dev: true /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} @@ -5623,7 +5631,7 @@ packages: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 - dev: false + dev: true /prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -6079,7 +6087,7 @@ packages: /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: false + dev: true /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} @@ -6585,7 +6593,7 @@ packages: /universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - dev: false + dev: true /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}