Skip to content

Commit

Permalink
Merge pull request #206 from siguici/main
Browse files Browse the repository at this point in the history
🛠️ Make some fixes to the CLI
  • Loading branch information
siguici authored Dec 31, 2024
2 parents 297a487 + be0b961 commit 672d38b
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 96 deletions.
144 changes: 69 additions & 75 deletions libs/create-qwikdev-astro/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { $, $pmCreate, $pmInstall, $pmX } from "./process";
import {
__dirname,
clearDir,
deepMergeJsonFile,
getPackageJson,
getPackageManager,
mergeDotIgnoreFiles,
notEmptyDir,
pmRunCommand,
replacePackageJsonRunCommand,
resolveAbsoluteDir,
resolveRelativeDir,
safeCopy,
sanitizePackageName,
updatePackageName
} from "./utils";
Expand Down Expand Up @@ -209,7 +210,7 @@ export class Application extends Program<Definition, Input> {

const template: string =
definition.template === undefined &&
(await this.scanBoolean(definition, "Would you like to use a template?"))
(await this.scanBoolean(definition, "Would you like to use a template?", false))
? await this.scanString("What template would you like to use?", "")
: (definition.template ?? "");

Expand Down Expand Up @@ -361,7 +362,7 @@ export class Application extends Program<Definition, Input> {

this.step(`Creating new project in ${this.bgBlue(` ${outDir} `)} ... 🐇`);
this.copyTemplate(input, templatePath);
this.copyGitignore(input);
this.makeGitignore(input);
}

async runTemplate(input: Input) {
Expand All @@ -385,50 +386,20 @@ export class Application extends Program<Definition, Input> {
await this.prepareDir(input);
await $pmCreate(args.join(" "), process.cwd());

const outDir = input.outDir;
const stubPath = path.join(
__dirname,
"..",
"stubs",
"templates",
`none${input.biome ? "-biome" : ""}`
this.step(`Copying template files into ${this.bgBlue(` ${input.outDir} `)} ... 🐇`);
this.copyTemplate(
input,
path.join(
__dirname,
"..",
"stubs",
"templates",
`none${input.biome ? "-biome" : ""}`
)
);
this.makeGitignore(input);

const configFiles = input.biome
? ["biome.json"]
: [".eslintignore", ".eslintrc.cjs", ".prettierignore", "prettier.config.cjs"];

const vscodeDir = path.join(stubPath, ".vscode");
const vscodeFiles = ["extensions.json", "launch.json"];

const projectPackageJsonFile = path.join(outDir, "package.json");
const projectTsconfigJsonFile = path.join(outDir, "tsconfig.json");
const templatePackageJsonFile = path.join(stubPath, "package.json");
const templateTsconfigJsonFile = path.join(stubPath, "tsconfig.json");

this.step(`Copying template files into ${this.bgBlue(` ${outDir} `)} ... 🐇`);

for (const vscodeFile of vscodeFiles) {
const vscodeFilePath = path.join(vscodeDir, vscodeFile);
const projectVscodeFilePath = path.join(outDir, ".vscode", vscodeFile);

pathExistsSync(projectVscodeFilePath)
? deepMergeJsonFile(projectVscodeFilePath, vscodeFilePath, true)
: cpSync(vscodeFilePath, projectVscodeFilePath, {
force: true
});
}

for (const configFile of configFiles) {
cpSync(path.join(stubPath, configFile), path.join(outDir, configFile), {
force: true
});
}

deepMergeJsonFile(projectPackageJsonFile, templatePackageJsonFile, true);
deepMergeJsonFile(projectTsconfigJsonFile, templateTsconfigJsonFile, true);

return input.install;
return this.runInstall(input);
}

async start(input: Input): Promise<boolean> {
Expand Down Expand Up @@ -516,13 +487,16 @@ export class Application extends Program<Definition, Input> {
}
}

async runInstall(definition: Definition): Promise<boolean> {
async runInstall(input: Input): Promise<boolean> {
let ranInstall = false;
if (definition.install) {
this.step("Installing dependencies...");
if (!definition.dryRun) {
await $pmInstall(definition.destination);

if (input.install) {
this.step(`Installing${input.template ? " new " : " "}dependencies...`);

if (!input.dryRun) {
await $pmInstall(input.destination);
}

ranInstall = true;
}

Expand All @@ -534,46 +508,65 @@ export class Application extends Program<Definition, Input> {
const s = this.spinner();

const outDir = input.outDir;
const initialized = fs.existsSync(path.join(outDir, ".git"));
if (initialized) {
this.info("Git has already been initialized before.");
}

if (fs.existsSync(path.join(outDir, ".git"))) {
this.info("Git has already been initialized before. Skipping...");
} else {
s.start("Git initializing...");
s.start(`${initialized ? "Adding New Changes to" : "Initializing"} Git...`);

if (!input.dryRun) {
const res = [];
try {
if (!input.dryRun) {
const res = [];
if (!initialized) {
res.push(await $("git", ["init"], outDir).process);
res.push(await $("git", ["add", "-A"], outDir).process);
res.push(
await $("git", ["commit", "-m", "Initial commit 🎉"], outDir).process
);
}
res.push(await $("git", ["add", "-A"], outDir).process);
res.push(
await $(
"git",
[
"commit",
"-m",
`${initialized ? "➕ Add @qwikdev/astro" : "Initial commit 🎉"}`
],
outDir
).process
);

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

s.stop("Git initialized 🎲");
s.stop(`${initialized ? "Changes added to Git ✨" : "Git initialized 🎲"}`);
} catch (e) {
s.stop("Git failed to initialize");
this.error(
this.red(
"Git failed to initialize. You can do this manually by running: git init"
)
);
s.stop(`Git failed to ${initialized ? "add new changes" : "initialize"}`);
if (!initialized) {
this.error(
this.red(
"Git failed to initialize. You can do this manually by running: git init"
)
);
}
}
}
}
}

copyGitignore(input: Input) {
this.step("Copying `.gitignore` file...");
makeGitignore(input: Input) {
const dotGitignore = path.join(input.outDir, ".gitignore");
const exists = pathExistsSync(dotGitignore);

this.step(`${exists ? "Merging" : "Copying"} \`.gitignore\` file...`);

if (!input.dryRun) {
const gitignore = path.join(__dirname, "..", "stubs", "gitignore");
const dotGitignore = path.join(input.outDir, ".gitignore");
cpSync(gitignore, dotGitignore, { force: true });

if (exists) {
mergeDotIgnoreFiles(dotGitignore, gitignore, true);
} else {
cpSync(gitignore, dotGitignore, { force: true });
}
}
}

Expand All @@ -582,7 +575,8 @@ export class Application extends Program<Definition, Input> {
const outDir = input.outDir;
try {
ensureDirSync(outDir);
copySync(templatePath, outDir);

input.template ? safeCopy(templatePath, outDir) : copySync(templatePath, outDir);
} catch (error) {
this.error(this.red(`Template copy failed: ${error}`));
}
Expand Down
2 changes: 1 addition & 1 deletion libs/create-qwikdev-astro/src/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ export async function scanBoolean(
: typeof initialValue
> {
const value =
no === true && initialValue === undefined
no === true && !initialValue
? false
: yes === true && initialValue === undefined
? true
Expand Down
70 changes: 69 additions & 1 deletion libs/create-qwikdev-astro/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
import fs from "node:fs";
import fs, { readdirSync, statSync } from "node:fs";
import os from "node:os";
import path, { join, resolve, relative } from "node:path";
import { fileURLToPath } from "node:url";
import { copySync, ensureDirSync, pathExistsSync } from "fs-extra/esm";
import detectPackageManager from "which-pm-runs";

export const __filename = getModuleFilename();
export const __dirname = path.dirname(__filename);

export function safeCopy(source: string, target: string): void {
const files = readdirSync(source);

for (const file of files) {
const sourcePath = join(source, file);
const targetPath = join(target, file);

if (statSync(sourcePath).isDirectory()) {
ensureDirSync(targetPath);
safeCopy(sourcePath, targetPath);
} else if (!pathExistsSync(targetPath)) {
copySync(sourcePath, targetPath);
} else if (file.endsWith(".json")) {
deepMergeJsonFile(targetPath, sourcePath, true);
} else if (file.startsWith(".") && file.endsWith("ignore")) {
mergeDotIgnoreFiles(targetPath, sourcePath, true);
}
}
}

export function deepMergeJsonFile<T>(
targetJsonPath: string,
sourceJsonPath: string,
Expand Down Expand Up @@ -48,6 +69,53 @@ function isObject(item: unknown): item is Record<string, any> {
return item !== null && typeof item === "object" && !Array.isArray(item);
}

export function mergeDotIgnoreFiles(
target: string,
source: string,
replace = false
): string {
const contents = mergeDotIgnoreContents(
fileGetContents(target),
fileGetContents(source)
);

if (replace) {
filePutContents(target, contents);
}

return contents;
}

export function mergeDotIgnoreContents(content1: string, content2: string): string {
return mergeDotIgnoreLines(content1.split("\n"), content2.split("\n")).join("\n");
}

export function mergeDotIgnoreLines(lines1: string[], lines2: string[]): string[] {
const lines = Array.from(
new Set([...lines1.map((line) => line.trim()), ...lines2.map((line) => line.trim())])
).filter((line) => line !== "");

return formatLines(lines);
}

function formatLines(lines: string[]): string[] {
const formattedLines: string[] = [];
let previousWasComment = false;

lines.forEach((line, index) => {
const isComment = line.startsWith("#");

if (isComment && !previousWasComment && index !== 0) {
formattedLines.push("");
}

formattedLines.push(line);
previousWasComment = isComment;
});

return formattedLines;
}

export function getModuleFilename(): string {
const error = new Error();
const stack = error.stack;
Expand Down
29 changes: 10 additions & 19 deletions libs/create-qwikdev-astro/tests/cli.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,10 @@ const setup = () => {
return () => emptyDirSync(root);
};

const templateDirs = [".vscode", "src"];

const templateFiles = [
".vscode/launch.json",
".vscode/extensions.json",
"package.json",
"tsconfig.json"
];

const generatedDirs = [
...templateDirs,
".vscode",
"public",
"src",
"src/assets",
"src/components",
"src/layouts",
Expand All @@ -38,7 +30,8 @@ const generatedDirs = [
];

const generatedFiles = [
...templateFiles,
".vscode/extensions.json",
".vscode/launch.json",
"public/favicon.svg",
"src/assets/astro.svg",
"src/assets/qwik.svg",
Expand All @@ -50,11 +43,12 @@ const generatedFiles = [
"src/env.d.ts",
".gitignore",
"README.md",
"astro.config.ts"
"astro.config.ts",
"package.json",
"tsconfig.json"
] as const;

type GeneratedOptions = Partial<{
template: boolean;
biome: boolean;
install: boolean;
ci: boolean;
Expand All @@ -63,7 +57,7 @@ type GeneratedOptions = Partial<{

const getGeneratedFiles = (options: GeneratedOptions = {}): string[] => {
const files = [
...(options.template ? templateFiles : generatedFiles),
...generatedFiles,
...(options.biome
? ["biome.json"]
: [".eslintignore", ".eslintrc.cjs", ".prettierignore", "prettier.config.cjs"])
Expand Down Expand Up @@ -91,7 +85,7 @@ const getGeneratedFiles = (options: GeneratedOptions = {}): string[] => {
};

const getGeneratedDirs = (options: GeneratedOptions = {}): string[] => {
const dirs = options.template ? templateDirs : generatedDirs;
const dirs = generatedDirs;

/*
if (options.install) {
Expand Down Expand Up @@ -144,14 +138,11 @@ test.group(`create ${integration} app`, (group) => {
});

test("with template", async (context) => {
return testRun(["--template", "minimal"], context, {
template: true
});
return testRun(["--template", "minimal"], context);
}).disableTimeout();

test("with template and using Biome", async (context) => {
return testRun(["--template", "minimal", "--biome"], context, {
template: true,
biome: true
});
}).disableTimeout();
Expand Down

0 comments on commit 672d38b

Please sign in to comment.