Skip to content

Commit

Permalink
Merge pull request #102 from siguici/create-qwik-astro
Browse files Browse the repository at this point in the history
Add @qwikdev/create-astro library
  • Loading branch information
siguici authored Apr 21, 2024
2 parents 5e8bb44 + 990fe4b commit a9679af
Show file tree
Hide file tree
Showing 83 changed files with 7,940 additions and 3,169 deletions.
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@
"enabled": true
},

"extends": ["./apps/website/biome.json"]
"extends": ["./apps/website/biome.json", "./libs/create-qwikdev-astro/biome.json"]
}
2 changes: 2 additions & 0 deletions libs/create-qwikdev-astro/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
src/
tsconfig.json
16 changes: 16 additions & 0 deletions libs/create-qwikdev-astro/biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"organizeImports": {
"ignore": ["dist", "stubs"]
},
"linter": {
"ignore": ["dist", "stubs"],
"rules": {
"style": {
"noParameterAssign": "off"
}
}
},
"formatter": {
"ignore": ["dist", "stubs"]
}
}
75 changes: 75 additions & 0 deletions libs/create-qwikdev-astro/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"name": "@qwikdev/create-astro",
"type": "module",
"license": "MIT",
"version": "0.0.0",
"description": "Interactive CLI for create @QwikDev/astro projects.",
"scripts": {
"build": "rimraf dist && tsc --build"
},
"contributors": [
{
"name": "MiΕ‘ko Hevery",
"email": "misko@hevery.com",
"url": "https://twitter.com/mhevery"
},
{
"name": "Jack Shelton",
"email": "me@jackshelton.com",
"url": "https://twitter.com/TheJackShelton"
},
{
"name": "Sigui KessΓ© Emmanuel",
"email": "contact@sigui.ci",
"url": "https://twitter.com/siguici"
}
],
"repository": {
"type": "git",
"url": "https://github.com/QwikDev/astro",
"directory": "libs/create-qwikdev-astro"
},
"types": "./dist/index.d.ts",
"main": "./dist/index.js",
"exports": {
".": "./dist/index.js",
"./package.json": "./package.json"
},
"files": ["dist", "stubs"],
"bin": {
"create-qwikdev-astro": "./dist/index.js"
},
"keywords": [
"astro-integration",
"astro-component",
"cli",
"console",
"create-qwik-astro",
"generator",
"optimization",
"perf",
"performance",
"qwik",
"qwikdev",
"qwik-astro",
"renderer",
"skeleton",
"starter-kit",
"template",
"withastro"
],
"publishConfig": {
"access": "public"
},
"bugs": "https://github.com/@QwikDev/astro/issues",
"devDependencies": {
"@clack/prompts": "^0.7.0",
"@types/which-pm-runs": "^1.0.2",
"@types/yargs": "^17.0.32",
"kleur": "^4.1.5",
"rimraf": "^5.0.5",
"typescript": "^5.4.5",
"which-pm-runs": "^1.1.0",
"yargs": "^17.7.2"
}
}
247 changes: 247 additions & 0 deletions libs/create-qwikdev-astro/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
#!/usr/bin/env node

import { type ChildProcess, exec, spawn } from "node:child_process";
import { cpSync, existsSync, mkdirSync } from "node:fs";
import fs from "node:fs";
import os from "node:os";
import path, { join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import {
cancel,
confirm,
intro,
isCancel,
log,
outro,
select,
spinner,
text
} from "@clack/prompts";
import { gray, red } from "kleur/colors";
import detectPackageManager from "which-pm-runs";

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

export function resolveRelativeDir(dir: string) {
return dir.startsWith("~/") ? resolve(os.homedir(), dir) : resolve(process.cwd(), dir);
}

export function $(cmd: string, args: string[], cwd: string) {
let child: ChildProcess;

const install = new Promise<boolean>((resolve) => {
try {
child = spawn(cmd, args, {
cwd,
stdio: "ignore"
});

child.on("error", (e) => {
if (e) {
log.error(`${red(String(e.message || e))}\n\n`);
}
resolve(false);
});

child.on("close", (code) => {
resolve(code === 0);
});
} catch (e) {
resolve(false);
}
});

const abort = async () => {
if (child) {
child.kill("SIGINT");
}
};

return { abort, install };
}

export function getPackageManager() {
return detectPackageManager()?.name || "npm";
}

export const isPackageManagerInstalled = (packageManager: string) => {
return new Promise((resolve) => {
exec(`${packageManager} --version`, (error, _, stderr) => {
resolve(!(error || stderr));
});
});
};

export const $pm = async (
args: string | string[],
cwd = process.cwd(),
env = process.env
) => {
const packageManager = getPackageManager();
args = Array.isArray(args) ? args : [args];

return new Promise((resolve, reject) => {
const child = spawn(packageManager, args, {
cwd,
stdio: "inherit",
env
});

child.on("close", (code) => {
if (code !== 0) {
reject({ command: `${packageManager} ${args.join(" ")}` });
return;
}
resolve(true);
});
});
};

export const installDependencies = async (cwd: string) => {
await $pm("install", cwd);
};

const createProject = async () => {
try {
intro("QwikDev/astro project creation");

const packageManager = getPackageManager();

const defaultProjectName = "./qwik-astro-app";
const projectNameAnswer = await text({
message: `Where would you like to create your new project? ${gray(
`(Use '.' or './' for current directory)`
)}`,
placeholder: defaultProjectName,
validate(value) {
if (value.length === 0) {
return "Value is required!";
}
}
});

if (typeof projectNameAnswer === "symbol") {
cancel("Operation canceled.");
return process.exit(0);
}

if (isCancel([projectNameAnswer, packageManager])) {
cancel("Operation canceled.");
process.exit(0);
}

const adapter = await select({
message: "Which adapter do you prefer?",
options: [
{
value: "node",
label: "Node"
},
{
value: "deno",
label: "Deno"
}
]
});

const favoriteLinterFormatter = await select({
message: "What is your favorite linter/formatter?",
options: [
{
value: "0",
label: "ESLint/Prettier"
},
{
value: "1",
label: "Biome"
}
]
});

log.step("Creating project directories and copying files...");

const kit = `${adapter}-${
favoriteLinterFormatter === "0" ? "eslint+prettier" : "biome"
}`;
const templatePath = path.join(__dirname, "..", "stubs", "templates", kit);
const outDir: string = resolveRelativeDir(projectNameAnswer.trim());
if (!existsSync(outDir)) {
mkdirSync(outDir, { recursive: true });
}
cpSync(templatePath, outDir, { recursive: true });
const addCIWorkflow = await confirm({
message: "Would you like to add CI workflow?",
initialValue: true
});
if (addCIWorkflow) {
const starterCIPath = join(
__dirname,
"..",
"stubs",
".github",
"workflows",
"ci.yml"
);
const projectCIPath = join(outDir, ".github", "workflows", "ci.yml");
cpSync(starterCIPath, projectCIPath, { force: true });
}
const runDepInstallAnswer = await confirm({
message: `Would you like to install ${packageManager} dependencies?`,
initialValue: true
});

const gitInitAnswer = await confirm({
message: "Initialize a new git repository?",
initialValue: true
});

if (gitInitAnswer) {
const s = spinner();

if (fs.existsSync(join(outDir, ".git"))) {
log.info("Git has already been initialized before. Skipping...");
} else {
s.start("Git initializing...");

try {
const res = [];
res.push(await $("git", ["init"], outDir).install);
res.push(await $("git", ["add", "-A"], outDir).install);
res.push(await $("git", ["commit", "-m", "Initial commit πŸŽ‰"], outDir).install);

if (res.some((r) => r === false)) {
throw "";
}

s.stop("Git initialized ✨");
} catch (e) {
s.stop("Git failed to initialize");
log.error(
red("Git failed to initialize. You can do this manually by running: git init")
);
}
}
}

if (typeof runDepInstallAnswer !== "symbol" && runDepInstallAnswer) {
log.step("Installing dependencies...");
await installDependencies(projectNameAnswer);
}

outro("QwikDev/astro project created successfully! 🍻");
} catch (err) {
console.error("An error occurred during QwikDev/astro project creation:", err);
process.exit(1);
}
};

async function main() {
await createProject();
}

main().catch(console.error);
34 changes: 34 additions & 0 deletions libs/create-qwikdev-astro/stubs/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

permissions:
contents: read

on: ["push", "pull_request"]

jobs:
ci:
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest]
node: [20.11]
experimental: [false]
name: πŸ‘· CI @qwikdev/astro Node-${{ matrix.node }} under ${{ matrix.os }}

steps:
- name: 🚚 Get latest code
uses: actions/checkout@v4

- name: πŸŽ‰ Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}

- name: ✨ Install dependencies
run: |
corepack enable
pnpm install
- name: βœ… Check code style
run: pnpm check
Loading

0 comments on commit a9679af

Please sign in to comment.