mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-24 04:01:46 +00:00
A little 'asinit' CLI tool for quickly setting up a project; Minor refactoring
This commit is contained in:
@ -13,7 +13,7 @@
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const utf8 = require("./util/utf8");
|
||||
const utf8 = require("@protobufjs/utf8");
|
||||
const EOL = process.platform === "win32" ? "\r\n" : "\n";
|
||||
|
||||
// Use distribution files if present, otherwise run the sources directly
|
||||
|
235
bin/asinit
Normal file
235
bin/asinit
Normal file
@ -0,0 +1,235 @@
|
||||
#!/usr/bin/env node
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const chalk = require("chalk");
|
||||
const version = require("../package.json").version;
|
||||
|
||||
if (process.argv.length < 3) printHelp();
|
||||
|
||||
function printHelp() {
|
||||
console.log([
|
||||
"Version " + version,
|
||||
"Syntax: " + chalk.cyan("asinit") + " [project directory]",
|
||||
"",
|
||||
chalk.white.bold("Sets up a new AssemblyScript project or updates an existing one."),
|
||||
"",
|
||||
"For example, to create a new project in the current directory:",
|
||||
"",
|
||||
" " + chalk.cyan("asinit") + " .",
|
||||
].join("\n"));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const rl = require("readline").createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
const projectDir = path.resolve(process.argv[2]);
|
||||
const compilerDir = path.join(__dirname, "..");
|
||||
const compilerVersion = require(path.join(compilerDir, "package.json")).version;
|
||||
const assemblyDir = path.join(projectDir, "assembly");
|
||||
const tsconfigFile = path.join(assemblyDir, "tsconfig.json");
|
||||
const definitionsFile = path.relative(assemblyDir, path.join(compilerDir, "std", "assembly.d.ts"));
|
||||
const entryFile = path.join(assemblyDir, "index.ts");
|
||||
const buildDir = path.join(projectDir, "build");
|
||||
const gitignoreFile = path.join(buildDir, ".gitignore");
|
||||
const packageFile = path.join(projectDir, "package.json");
|
||||
|
||||
console.log([
|
||||
"Version: " + version,
|
||||
"",
|
||||
chalk.white.bold([
|
||||
"This command will make sure that the following files exist in the project",
|
||||
"directory '" + projectDir + "':"
|
||||
].join("\n")),
|
||||
"",
|
||||
chalk.cyan(" ./assembly"),
|
||||
" Directory holding the AssemblyScript sources being compiled to WebAssembly.",
|
||||
"",
|
||||
chalk.cyan(" ./assembly/tsconfig.json"),
|
||||
" TypeScript configuration inheriting recommended AssemblyScript settings.",
|
||||
"",
|
||||
chalk.cyan(" ./assembly/index.ts"),
|
||||
" Exemplary entry file being compiled to WebAssembly to get you started.",
|
||||
"",
|
||||
chalk.cyan(" ./build"),
|
||||
" Build artifact directory where compiled WebAssembly files are stored.",
|
||||
"",
|
||||
chalk.cyan(" ./build/.gitignore"),
|
||||
" Git configuration that excludes compiled binaries from source control.",
|
||||
"",
|
||||
chalk.cyan(" ./package.json"),
|
||||
" Package info containing the necessary commands to compile to WebAssembly.",
|
||||
"",
|
||||
"The command will try to update existing files to match the correct settings",
|
||||
"for this instance of the compiler in '" + compilerDir + "'.",
|
||||
""
|
||||
].join("\n"));
|
||||
|
||||
rl.question(chalk.white.bold("Do you want to proceed?") + " [Y/n] ", answer => {
|
||||
if (!/^y?$/i.test(answer)) {
|
||||
process.exit(1);
|
||||
return;
|
||||
}
|
||||
console.log();
|
||||
ensureProjectDirectory();
|
||||
ensureAssemblyDirectory();
|
||||
ensureTsconfigJson();
|
||||
ensureEntryFile();
|
||||
ensureBuildDirectory();
|
||||
ensureGitignore();
|
||||
ensurePackageJson();
|
||||
console.log([
|
||||
chalk.green("Done!"),
|
||||
"",
|
||||
"To edit the entry file, open '" + chalk.cyan("assembly/index.ts") + "' in your editor of choice.",
|
||||
"Create as many additional files as necessary and use them as imports.",
|
||||
"",
|
||||
"To build the entry file to WebAssembly when you are ready, run:",
|
||||
"",
|
||||
chalk.white.bold(" npm run asbuild"),
|
||||
"",
|
||||
"Running the command above creates the following binaries incl. their respective",
|
||||
"text format representations and source maps:",
|
||||
"",
|
||||
chalk.cyan(" ./build/untouched.wasm"),
|
||||
chalk.cyan(" ./build/untouched.wasm.map"),
|
||||
chalk.cyan(" ./build/untouched.wat"),
|
||||
"",
|
||||
" ^ The untouched WebAssembly module as generated by the compiler.",
|
||||
" This one matches your sources exactly, without any optimizations.",
|
||||
"",
|
||||
chalk.cyan(" ./build/optimized.wasm"),
|
||||
chalk.cyan(" ./build/optimized.wasm.map"),
|
||||
chalk.cyan(" ./build/optimized.wat"),
|
||||
"",
|
||||
" ^ The optimized WebAssembly module using default optimization settings (-O2s).",
|
||||
" You can change the optimization settings in '" + chalk.cyan("package.json")+ "'.",
|
||||
"",
|
||||
chalk.white.bold("Additional documentation is available at the AssemblyScript wiki:"),
|
||||
"",
|
||||
" https://github.com/AssemblyScript/assemblyscript/wiki",
|
||||
"",
|
||||
"Have a nice day!"
|
||||
].join("\n"));
|
||||
rl.close();
|
||||
});
|
||||
|
||||
function ensureProjectDirectory() {
|
||||
console.log("- Making sure that the project directory exists...");
|
||||
if (!fs.existsSync(projectDir)) {
|
||||
fs.mkdirSync(projectDir);
|
||||
console.log(chalk.green(" Created: ") + projectDir);
|
||||
} else {
|
||||
console.log(chalk.yellow(" Exists: ") + projectDir);
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
|
||||
function ensureAssemblyDirectory() {
|
||||
console.log("- Making sure that the 'assembly' directory exists...");
|
||||
if (!fs.existsSync(assemblyDir)) {
|
||||
fs.mkdirSync(assemblyDir);
|
||||
console.log(chalk.green(" Created: ") + assemblyDir);
|
||||
} else {
|
||||
console.log(chalk.yellow(" Exists: ") + assemblyDir);
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
|
||||
function ensureTsconfigJson() {
|
||||
console.log("- Making sure that 'assembly/tsconfig.json' is set up...");
|
||||
const definitionsPath = definitionsFile.replace(/\\/g, "/");
|
||||
if (!fs.existsSync(tsconfigFile)) {
|
||||
fs.writeFileSync(tsconfigFile, JSON.stringify({
|
||||
"extends": definitionsPath,
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}, null, 2));
|
||||
console.log(chalk.green(" Created: ") + tsconfigFile);
|
||||
|
||||
} else {
|
||||
let tsconfig = JSON.parse(fs.readFileSync(tsconfigFile, "utf8"));
|
||||
tsconfig["extends"] = definitionsPath;
|
||||
fs.writeFileSync(tsconfigFile, JSON.stringify(tsconfig, null, 2));
|
||||
console.log(chalk.green(" Updated: ") + tsconfigFile);
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
|
||||
function ensureEntryFile() {
|
||||
console.log("- Making sure that 'assembly/index.ts' exists...");
|
||||
if (!fs.existsSync(entryFile)) {
|
||||
fs.writeFileSync(entryFile, [
|
||||
"// The entry file of your WebAssembly module.",
|
||||
"",
|
||||
"export function add(a: i32, b: i32): i32 {",
|
||||
" return a + b;",
|
||||
"}"
|
||||
].join("\n") + "\n");
|
||||
console.log(chalk.green(" Created: ") + entryFile);
|
||||
} else {
|
||||
console.log(chalk.yellow(" Exists: ") + entryFile);
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
|
||||
function ensureBuildDirectory() {
|
||||
console.log("- Making sure that the 'build' directory exists...");
|
||||
if (!fs.existsSync(buildDir)) {
|
||||
fs.mkdirSync(buildDir);
|
||||
console.log(chalk.green(" Created: ") + buildDir);
|
||||
} else {
|
||||
console.log(chalk.yellow(" Exists: ") + buildDir);
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
|
||||
function ensureGitignore() {
|
||||
console.log("- Making sure that 'build/.gitignore' is set up...");
|
||||
if (!fs.existsSync(gitignoreFile)) {
|
||||
fs.writeFileSync(gitignoreFile, [
|
||||
"*.wasm",
|
||||
"*.asm.js"
|
||||
].join("\n") + "\n");
|
||||
console.log(chalk.green(" Created: ") + gitignoreFile);
|
||||
} else {
|
||||
console.log(chalk.yellow(" Exists: ") + gitignoreFile);
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
|
||||
function ensurePackageJson() {
|
||||
console.log("- Making sure that 'package.json' contains the build commands...")
|
||||
const entryPath = path.relative(projectDir, entryFile).replace(/\\/g, "/");
|
||||
const buildUntouched = "asc " + entryPath + " -b build/untouched.wasm -t build/untouched.wat --sourceMap --validate";
|
||||
const buildOptimized = "asc " + entryPath + " -b build/optimized.wasm -t build/optimized.wat --sourceMap --validate --optimize --noDebug";
|
||||
const buildAll = "npm run asbuild:untouched && npm run asbuild:optimized";
|
||||
if (!fs.existsSync(packageFile)) {
|
||||
fs.writeFileSync(packageFile, JSON.stringify({
|
||||
"scripts": {
|
||||
"asbuild:untouched": buildUntouched,
|
||||
"asbuild:optimized": buildOptimized,
|
||||
"asbuild": buildAll
|
||||
}
|
||||
}, null, 2));
|
||||
console.log(chalk.green(" Created: ") + packageFile);
|
||||
} else {
|
||||
let pkg = JSON.parse(fs.readFileSync(packageFile));
|
||||
let scripts = pkg["scripts"];
|
||||
if (!scripts) scripts = {};
|
||||
if (!scripts["asbuild"]) {
|
||||
scripts["asbuild:untouched"] = buildUntouched;
|
||||
scripts["asbuild:optimized"] = buildOptimized;
|
||||
scripts["asbuild"] = buildAll;
|
||||
pkg["scripts"] = scripts;
|
||||
fs.writeFileSync(packageFile, JSON.stringify(pkg, null, 2));
|
||||
console.log(chalk.green(" Updated: ") + packageFile);
|
||||
} else {
|
||||
console.log(chalk.yellow(" Exists: ") + packageFile);
|
||||
}
|
||||
}
|
||||
console.log();
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
// see: https://github.com/dcodeIO/protobuf.js/tree/master/lib/utf8
|
||||
|
||||
exports.length = function utf8_length(string) {
|
||||
var len = 0,
|
||||
c = 0;
|
||||
for (var i = 0; i < string.length; ++i) {
|
||||
c = string.charCodeAt(i);
|
||||
if (c < 128) {
|
||||
len += 1;
|
||||
} else if (c < 2048) {
|
||||
len += 2;
|
||||
} else if ((c & 0xFC00) === 0xD800 && (string.charCodeAt(i + 1) & 0xFC00) === 0xDC00) {
|
||||
++i;
|
||||
len += 4;
|
||||
} else {
|
||||
len += 3;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
};
|
||||
|
||||
exports.read = function utf8_read(buffer, start, end) {
|
||||
var len = end - start;
|
||||
if (len < 1)
|
||||
return "";
|
||||
var parts = null,
|
||||
chunk = [],
|
||||
i = 0, t;
|
||||
while (start < end) {
|
||||
t = buffer[start++];
|
||||
if (t < 128) {
|
||||
chunk[i++] = t;
|
||||
} else if (t > 191 && t < 224) {
|
||||
chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;
|
||||
} else if (t > 239 && t < 365) {
|
||||
t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000;
|
||||
chunk[i++] = 0xD800 + (t >> 10);
|
||||
chunk[i++] = 0xDC00 + (t & 1023);
|
||||
} else {
|
||||
chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;
|
||||
}
|
||||
if (i > 8191) {
|
||||
(parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
if (parts) {
|
||||
if (i) parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
|
||||
return parts.join("");
|
||||
}
|
||||
return String.fromCharCode.apply(String, chunk.slice(0, i));
|
||||
};
|
||||
|
||||
exports.write = function utf8_write(string, buffer, offset) {
|
||||
var start = offset,
|
||||
c1, c2;
|
||||
for (var i = 0; i < string.length; ++i) {
|
||||
c1 = string.charCodeAt(i);
|
||||
if (c1 < 128) {
|
||||
buffer[offset++] = c1;
|
||||
} else if (c1 < 2048) {
|
||||
buffer[offset++] = c1 >> 6 | 192;
|
||||
buffer[offset++] = c1 & 63 | 128;
|
||||
} else if ((c1 & 0xFC00) === 0xD800 && ((c2 = string.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) {
|
||||
c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF);
|
||||
++i;
|
||||
buffer[offset++] = c1 >> 18 | 240;
|
||||
buffer[offset++] = c1 >> 12 & 63 | 128;
|
||||
buffer[offset++] = c1 >> 6 & 63 | 128;
|
||||
buffer[offset++] = c1 & 63 | 128;
|
||||
} else {
|
||||
buffer[offset++] = c1 >> 12 | 224;
|
||||
buffer[offset++] = c1 >> 6 & 63 | 128;
|
||||
buffer[offset++] = c1 & 63 | 128;
|
||||
}
|
||||
}
|
||||
return offset - start;
|
||||
};
|
Reference in New Issue
Block a user