Skip to content

Commit

Permalink
some more improvs
Browse files Browse the repository at this point in the history
  • Loading branch information
signorecello committed Mar 4, 2024
1 parent 4387b2b commit 2904549
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 95 deletions.
18 changes: 8 additions & 10 deletions boxes/bin.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/env node
import { Command } from "commander";
const program = new Command();
import path from "path";
import os from "os";
import axios from "axios";
import { chooseAndCloneBox } from "./scripts/steps/chooseBox.js";
import { sandboxRun } from "./scripts/steps/sandbox/run.js";
Expand All @@ -25,24 +23,24 @@ const { data } = await axios.get(
//
// if the user has set a version (ex. "master" or "0.23.0"), use that
// otherwise use the stable release (ex. 0.24.0)
const stable = `${data[0].tag_name.split("-v")[1]}`;
const version = process.env.VERSION || stable;
const latestStable = `${data[0].tag_name.split("-v")[1]}`;
const versionToInstall = process.env.VERSION || latestStable;

// if the user has set a semver version (matches the regex), fetch that tag (i.e. aztec-packages-v0.23.0)
// otherwise use the version as the tag
const tag = version.match(/^\d+\.\d+\.\d+$/)
? `aztec-packages-v${version}`
: version;
const tagToUse = versionToInstall.match(/^\d+\.\d+\.\d+$/)
? `aztec-packages-v${versionToInstall}`
: versionToInstall;

program.action(async () => {
// STEP 1: Choose the boilerplate
await chooseAndCloneBox(tag, version);
await chooseAndCloneBox(tagToUse, versionToInstall);

// STEP 2: Install the Sandbox
await sandboxInstallOrUpdate(stable, version);
await sandboxInstallOrUpdate(latestStable, versionToInstall);

// STEP 3: Running the Sandbox
await sandboxRun(version);
await sandboxRun(versionToInstall);
});

program.parse();
5 changes: 3 additions & 2 deletions boxes/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "create-aztec-app",
"packageManager": "yarn@4.1.0",
"version": "0.2.3",
"version": "0.2.11",
"type": "module",
"scripts": {
"compile": "yarn workspaces foreach -A -v run compile",
Expand All @@ -11,7 +11,7 @@
"workspaces": [
"boxes/*"
],
"bin": "VERSION=${VERSION:+} bin.js",
"bin": "bin.js",
"resolutions": {
"@aztec/accounts": "portal:../yarn-project/accounts",
"@aztec/aztec.js": "portal:../yarn-project/aztec.js",
Expand All @@ -33,6 +33,7 @@
"chalk": "^5.3.0",
"commander": "^12.0.0",
"node-pty": "^1.0.0",
"ora": "^8.0.1",
"tiged": "^2.12.6"
}
}
27 changes: 20 additions & 7 deletions boxes/scripts/steps/chooseBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,46 @@ import input from "@inquirer/input";
import tiged from "tiged";
import { getAvailableBoxes, replacePaths } from "../utils.js";
import chalk from "chalk";
import axios from "axios";
import ora from "ora";
const { log } = console;

export async function chooseAndCloneBox(tag, version) {
const availableBoxes = await getAvailableBoxes(tag, version);
const appType = await select({
message: `Please choose your Aztec boilerplate:`,
choices: availableBoxes.map((box) => {
return { value: box.name, name: box.description };
}),
choices: [
...availableBoxes.map((box) => {
return { value: box.name, name: box.description };
}),
{ value: "skip", name: "Skip this step" },
],
});

if (appType === "skip") return;

log(chalk.yellow(`You chose: ${appType}`));

const spinner = ora({
text: "Cloning the boilerplate code...",
color: "blue",
});

try {
// STEP 1: Clone the box
const appName = await input({
message: "Your app name:",
default: "my-aztec-app",
});

chalk.blue("Cloning the boilerplate code...");
spinner.start();

const emitter = tiged(
// same as the nargo dependencies above:
// "master" and "latest" both mean "master" for the github repo
// but if the user has set a semver version, we want that tag (i.e. aztec-packages-v0.23.0)
`AztecProtocol/aztec-packages/boxes/${appType}${["latest", "master"].includes(tag) ? "" : `#${tag}`}`,
`AztecProtocol/aztec-packages/boxes/${appType}${tag && `#${tag}`}`,
{
verbose: true,
},
);

emitter.on("info", (info) => {
Expand All @@ -45,5 +56,7 @@ export async function chooseAndCloneBox(tag, version) {
} catch (error) {
log(chalk.bgRed(error.message));
process.exit(1);
} finally {
spinner.stop();
}
}
94 changes: 62 additions & 32 deletions boxes/scripts/steps/sandbox/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,43 @@ const runPty = async (command, { success, error }) => {
}
};

export async function sandboxInstallOrUpdate(stable, version) {
function findOutUserVersion() {
/**
* We know user has docker installed.
* Now we get the result of the docker image inspect command
* If it throws with an empty object, that's because the image doesn't exist so the user
* Doesn't have the sandbox installed. We exit early since there's nothing to parse.
*
* If it returns an object, we parse the COMMIT_TAG field
* - If there's anything there, that's the version of the sandbox
* - If there's nothing there, that's because there's no tag yet, so he's on master
*/
let sandboxVersion = null;
let dockerOutput = null;
try {
dockerOutput = execSync("docker image inspect aztecprotocol/aztec 2>&1", {
encoding: "utf8",
});
} catch (error) {
// Something went wrong with the docker command
// So we assume sandbox is not installed
sandboxVersion == null;
}

if (!dockerOutput) return sandboxVersion;

// parsing the docker output to get the commit tag
sandboxVersion = JSON.parse(dockerOutput)[0]
.Config.Env.find((env) => env.includes("COMMIT_TAG"))
.split("=")[1];

// There's no tag yet, so the user is on master
if (!sandboxVersion) sandboxVersion = "master";

return sandboxVersion;
}

export async function sandboxInstallOrUpdate(latestStable, versionToInstall) {
// Checking for docker
try {
execSync("docker info >/dev/null 2>&1");
Expand All @@ -52,24 +88,11 @@ export async function sandboxInstallOrUpdate(stable, version) {
process.exit(1);
}

let sandboxVersion;
try {
const dockerOutput = execSync(
"docker image inspect aztecprotocol/aztec 2>&1",
{
encoding: "utf8",
},
);
sandboxVersion = JSON.parse(dockerOutput)[0]
.Config.Env.find((env) => env.includes("COMMIT_TAG"))
.split("=")[1];
console.log(sandboxVersion);
} catch (error) {
sandboxVersion == null;
}
// Let's get which version of the sandbox the user has installed
const sandboxVersion = findOutUserVersion();

// Checking for the Aztec Sandbox
if (!sandboxVersion) {
// Base case is that the user doesn't have the sandbox installed
if (sandboxVersion == null) {
const answer = await confirm({
message:
"Seems like you don't have the Aztec Sandbox installed. Do you want to install it?",
Expand All @@ -87,32 +110,39 @@ export async function sandboxInstallOrUpdate(stable, version) {
);
}
} else if (
sandboxVersion === stable &&
sandboxVersion !== version &&
!["latest", "master"].includes(version)
// Another situation is where the sandbox matches the stable version (i.e. 0.24.0) or master
(sandboxVersion === latestStable || sandboxVersion === "master") &&
// but the user has chosen a different version (i.e. "master", 0.23.0, etc)
sandboxVersion !== versionToInstall
) {
const answer = await confirm({
message: `The sandbox is version ${sandboxVersion} but your chosen version is ${version}. Do you want to install version ${version}?`,
message: `The sandbox is version ${sandboxVersion} but your chosen version is ${versionToInstall}. Do you want to install version ${versionToInstall}?`,
default: true,
});

if (answer) {
execSync(
`${["latest", "master"].includes(version) ? "VERSION=master" : ""} $HOME/.aztec/bin/aztec-up`,
{ stdio: "inherit" },
);
// cool thing is that user already has VERSION in the path, so we don't need to pass it here too
execSync(`$HOME/.aztec/bin/aztec-up`, { stdio: "inherit" });
}
} else if (sandboxVersion !== stable) {
} else if (
// Finally, there's a situation where
// the user didn't want any specific version
sandboxVersion !== versionToInstall &&
// and the sandbox is not up to date
// so we need to update to that since the cloned repo is also the latest
sandboxVersion !== latestStable &&
// we're also aware that the user might be on master
// so his version is actually not outdated!
versionToInstall !== "master"
) {
const answer = await confirm({
message: `The Sandbox is not up to date. Do you want to update it to ${stable}?`,
message: `The Sandbox is not up to date. Do you want to update it to ${latestStable}?`,
default: true,
});

if (answer) {
execSync(
`${["latest", "master"].includes(version) ? "VERSION=master" : ""} $HOME/.aztec/bin/aztec-up latest`,
{ stdio: "inherit" },
);
// again abusing the fact that the user has VERSION in the path
execSync(`$HOME/.aztec/bin/aztec-up`, { stdio: "inherit" });
}
}
}
23 changes: 17 additions & 6 deletions boxes/scripts/steps/sandbox/run.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import confirm from "@inquirer/confirm";
import { execSync } from "child_process";
import chalk from "chalk";
import axios from "axios";
import ora from "ora";
const { log } = console;

export async function sandboxRun(version) {
const spinner = ora({
text: "Trying to reach the sandbox...",
color: "blue",
});

try {
await fetch("http://localhost:8080", {
spinner.start();
await axios("http://localhost:8080", {
method: "POST",
timeout: 2000,
headers: {
"Content-Type": "application/json",
},
Expand All @@ -16,10 +25,13 @@ export async function sandboxRun(version) {
id: "null",
}),
});
spinner.stop();
log(chalk.green("The Sandbox already running!"));
} catch (error) {
spinner.stop();
const answer = await confirm({
message:
"I can't reach the Sandbox on port 8080. Do you want to start it?",
"I can't reach the Sandbox on localhost:8080. Do you want to start it?",
default: true,
});

Expand All @@ -28,10 +40,9 @@ export async function sandboxRun(version) {
chalk.green("Starting the sandbox... This might take a few minutes."),
);
log(chalk.bgGreen(`Go and explore the boilerplate code while you wait!`));
execSync(
`${["latest", "master"].includes(version) ? "VERSION=master" : ""} $HOME/.aztec/bin/aztec sandbox`,
{ stdio: "inherit" },
);
execSync(`$HOME/.aztec/bin/aztec sandbox`, { stdio: "inherit" });
}
} finally {
spinner.stop();
}
}
14 changes: 6 additions & 8 deletions boxes/scripts/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ export async function getAvailableBoxes(tag, version) {
let data;
try {
({ data } = await axios.get(
`https://api.github.com/repos/AztecProtocol/aztec-packages/contents/boxes/boxes?ref=${tag}`,
`https://api.github.com/repos/AztecProtocol/aztec-packages/contents/boxes/boxes${tag == "master" ? "" : `?ref=${tag}`}`,
axiosOpts,
));
} catch (e) {
if (e.response.statusText === "Not Found") {
({ data } = await axios.get(
`https://api.github.com/repos/AztecProtocol/aztec-packages/contents/boxes?ref=${tag}`,
`https://api.github.com/repos/AztecProtocol/aztec-packages/contents/boxes${tag == "master" ? "" : `?ref=${tag}`}`,
axiosOpts,
));
}
Expand All @@ -36,7 +36,7 @@ export async function getAvailableBoxes(tag, version) {
)
.map(async ({ path, name }) => {
({ data } = await axios.get(
`https://raw.githubusercontent.com/AztecProtocol/aztec-packages/${["latest", "master"].includes(tag) ? "master" : tag}/${path}/package.json`,
`https://raw.githubusercontent.com/AztecProtocol/aztec-packages/${tag == "master" ? "master" : tag}/${path}/package.json`,
axiosOpts,
));

Expand Down Expand Up @@ -112,9 +112,7 @@ export async function replacePaths(rootDir, tag, version) {
const directory = content.dependencies[dep].path.replace(/^(..\/)+/);
content.dependencies[dep] = {
git: "https://github.com/AztecProtocol/aztec-packages/",
// "master" and "latest" both mean "master" for the nargo dependencies
// plus, we're parsing the tag here, not the version, but as seen above, tag IS version if it's not semver
tag: ["latest", "master"].includes(tag) ? "master" : tag,
tag,
directory,
};
});
Expand All @@ -128,11 +126,11 @@ export async function replacePaths(rootDir, tag, version) {
let content = JSON.parse(fs.readFileSync(filePath, "utf8"));
Object.keys(content.dependencies)
.filter((deps) => deps.match("@aztec"))
// "master" and "latest" both mean "latest" for the npm release
// "master" actually means "latest" for the npm release
.map(
(dep) =>
(content.dependencies[dep] =
`${["latest", "master"].includes(version) ? "latest" : `^${version}`}`),
`${version === "master" ? "latest" : `^${version}`}`),
);
fs.writeFileSync(filePath, JSON.stringify(content), "utf8");
} catch (e) {
Expand Down
Loading

0 comments on commit 2904549

Please sign in to comment.