Skip to content
Merged
Changes from all 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
128 changes: 116 additions & 12 deletions index.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#!/usr/bin/env node
// @ts-check

import * as p from "@clack/prompts";
import path from "path";
import fs from "fs";
import os from "os";
import { fileURLToPath } from "url";
import { exec } from "child_process";
import { promisify } from "util";
Expand Down Expand Up @@ -77,10 +79,15 @@ async function updatePackageJson(projectName) {
);
}

async function updateRescriptJson(projectName) {
async function updateRescriptJson(projectName, sourceDir) {
await updateFile("rescript.json", contents => {
const config = JSON.parse(contents);
config["name"] = projectName;

if (sourceDir) {
config["sources"]["dir"] = sourceDir;
}

return JSON.stringify(config, null, 2);
});
}
Expand All @@ -95,18 +102,94 @@ function getVersion() {
return JSON.parse(contents).version;
}

async function main() {
console.clear();
function getProjectPackageJson() {
const packageJsonPath = path.join(process.cwd(), "package.json");
const contents = fs.readFileSync(packageJsonPath, "utf8");
return JSON.parse(contents);
}

p.intro(c.dim("create-rescript-app " + getVersion()));
async function addToExistingProject() {
const projectName = getProjectPackageJson().name;

p.note(
`${c.cyan("Fast, Simple, Fully Typed JavaScript from the Future")}
https://www.rescript-lang.org\n\nCreate a new ReScript 11 project with modern defaults
("Core" standard library, JSX 4 automatic mode)`,
"Welcome to ReScript!"
);
const templatePath = path.join(__dirname, "templates", "rescript-template-basic");
const projectPath = process.cwd();
const gitignorePath = path.join(projectPath, ".gitignore");

const s = p.spinner();

try {
const addToProj = await p.confirm({
message: `Detected a package.json file. Do you want to add ReScript to "${projectName}"?`,
});
checkCancel(addToProj);

s.start("Loading available versions...");
const [rescriptVersions, rescriptCoreVersions] = await Promise.all([
getPackageVersions("rescript", rescriptVersionRange),
getPackageVersions("@rescript/core", rescriptCoreVersionRange),
]);
s.stop("Versions loaded.");

const rescriptVersion = await p.select({
message: "ReScript version?",
options: rescriptVersions.map(v => ({ value: v })),
});
checkCancel(rescriptVersion);

const rescriptCoreVersion = await p.select({
message: "ReScript Core version?",
options: rescriptCoreVersions.map(v => ({ value: v })),
});
checkCancel(rescriptCoreVersion);

const sourceDir = await p.text({
message: "Where will you put your ReScript source files?",
defaultValue: "src",
placeholder: "src",
initialValue: "src",
});
checkCancel(sourceDir);

await fs.promises.copyFile(
path.join(templatePath, "rescript.json"),
path.join(projectPath, "rescript.json")
);

if (fs.existsSync(gitignorePath)) {
await fs.promises.appendFile(gitignorePath, "/lib/" + os.EOL + ".bsb.lock" + os.EOL);
}

await updateRescriptJson(projectName, sourceDir);

const sourceDirPath = path.join(projectPath, sourceDir);

if (!fs.existsSync(sourceDirPath)) {
fs.mkdirSync(sourceDirPath);
}

await fs.promises.copyFile(
path.join(templatePath, "src", "Demo.res"),
path.join(sourceDirPath, "Demo.res")
);

const packages = [`rescript@${rescriptVersion}`, `@rescript/core@${rescriptCoreVersion}`];

await promisify(exec)("npm add " + packages.join(" "));

s.stop("Added ReScript to your project.");
p.note(`cd ${projectName}\nnpm run res:dev`, "Next steps");
p.outro(`Happy hacking!`);
} catch (error) {
console.warn(error);
s.stop("Installation error.");

p.outro(`Adding ReScript to project failed.`);

p.log.error(error);
}
}

async function createNewProject() {
const projectName = await p.text({
message: "What is the name of your new ReScript project?",
placeholder: process.argv[2] || "my-rescript-app",
Expand All @@ -120,9 +203,9 @@ https://www.rescript-lang.org\n\nCreate a new ReScript 11 project with modern de
});
checkCancel(templateName);

try {
const s = p.spinner();
const s = p.spinner();

try {
s.start("Loading available versions...");
const [rescriptVersions, rescriptCoreVersions] = await Promise.all([
getPackageVersions("rescript", rescriptVersionRange),
Expand Down Expand Up @@ -175,4 +258,25 @@ Change to the ${c.cyan(projectName)} folder and view ${c.cyan("README.md")} for
}
}

async function main() {
console.clear();

p.intro(c.dim("create-rescript-app " + getVersion()));

p.note(
`${c.cyan("Fast, Simple, Fully Typed JavaScript from the Future")}
https://www.rescript-lang.org\n\nCreate a new ReScript 11 project with modern defaults
("Core" standard library, JSX 4 automatic mode)`,
"Welcome to ReScript!"
);

const existingPackageJson = fs.existsSync(path.join(process.cwd(), "package.json"));

if (existingPackageJson) {
addToExistingProject();
} else {
createNewProject();
}
}

main();