makecode
Version:
MakeCode (PXT) - web-cached build tool
226 lines • 9.78 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.bumpCommand = exports.buildCommand = void 0;
const commander_1 = require("commander");
const chalk = require("chalk");
const node_watch_1 = require("node-watch");
const commands_1 = require("makecode-core/built/commands");
const loader_1 = require("makecode-core/built/loader");
const host_1 = require("makecode-core/built/host");
const mkc_1 = require("makecode-core/built/mkc");
const nodeHost_1 = require("./nodeHost");
const bump_1 = require("./bump");
const simserver_1 = require("./simserver");
let debugMode = false;
function info(msg) {
console.log(chalk.blueBright(msg));
}
function msg(msg) {
console.log(chalk.green(msg));
}
function error(msg) {
console.error(chalk.red(msg));
}
async function buildCommand(opts, info) {
var _a;
if ((_a = info === null || info === void 0 ? void 0 : info.args) === null || _a === void 0 ? void 0 : _a.length) {
error("invalid command");
process.exit(1);
}
(0, commands_1.applyGlobalOptions)(opts);
if (opts.deploy && opts.monoRepo) {
error("--deploy and --mono-repo cannot be used together");
process.exit(1);
}
if (opts.deploy && opts.javaScript) {
error("--deploy and --java-script cannot be used together");
process.exit(1);
}
if (opts.watch) {
startWatch(opts);
}
else
await (0, commands_1.buildCommandOnce)(opts);
}
exports.buildCommand = buildCommand;
async function bumpCommand(opts) {
(0, commands_1.applyGlobalOptions)(opts);
const prj = await (0, commands_1.resolveProject)(opts);
await (0, bump_1.bumpAsync)(prj, opts === null || opts === void 0 ? void 0 : opts.versionFile, opts === null || opts === void 0 ? void 0 : opts.stage, (opts === null || opts === void 0 ? void 0 : opts.major) ? "major" : (opts === null || opts === void 0 ? void 0 : opts.minor) ? "minor" : (opts === null || opts === void 0 ? void 0 : opts.patch) ? "patch" : undefined);
}
exports.bumpCommand = bumpCommand;
function clone(v) {
return JSON.parse(JSON.stringify(v));
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function serveCommand(opts) {
(0, commands_1.applyGlobalOptions)(opts);
opts.javaScript = true;
if (opts.watch)
startWatch(clone(opts));
opts = clone(opts);
opts.update = false;
const prj = await (0, commands_1.resolveProject)(opts, !!opts.watch);
const port = parseInt(opts.port) || 7001;
const url = `http://127.0.0.1:${port}`;
const forceLocal = !!opts.forceLocal;
msg(`simulator at ${url}`);
msg(`Jacdac+simulator at https://microsoft.github.io/jacdac-docs/clients/javascript/devtools#${url}`);
(0, simserver_1.startSimServer)(prj.editor, port, forceLocal);
}
function startWatch(opts) {
const binaries = {};
const watcher = (0, node_watch_1.default)("./", {
recursive: true,
delay: 200,
filter(f, skip) {
// skip node_modules, pxt_modules, built, .git
if (/\/?((node|pxt)_modules|built|\.git)/i.test(f))
return skip;
// only watch for js files
return /\.(json|ts|asm|cpp|c|h|hpp)$/i.test(f);
},
});
let building = false;
let buildPending = false;
const build = async (ev, filename) => {
if (ev)
msg(`detected ${ev} ${filename}`);
buildPending = true;
await delay(100); // wait for other change events, that might have piled-up to arrive
// don't trigger 2 build, wait and do it again
if (building) {
msg(` build in progress, waiting...`);
return;
}
// start a build
try {
building = true;
while (buildPending) {
buildPending = false;
const opts0 = clone(opts);
if (ev)
// if not first time, don't update
opts0.update = false;
const files = (await (0, commands_1.buildCommandOnce)(opts0)).outfiles;
if (files)
Object.entries(files).forEach(([key, value]) => {
if (/\.(hex|json|asm)$/.test(key))
binaries[key] = value;
else
binaries[key] = Buffer.from(value, "base64");
});
}
}
catch (e) {
error(e);
}
finally {
building = false;
}
};
watcher.on("change", build);
msg(`start watching for file changes`);
build(undefined, undefined);
}
function createCommand(name, opts) {
const cmd = commander_1.program
.command(name, opts)
.option("--colors", "force color output")
.option("--no-colors", "disable color output")
.option("--debug", "enable debug output from PXT")
.option("-f, --compile-flags <flag,...>", "set PXT compiler options (?compile=... or PXT_COMPILE_SWITCHES=... in other tools)");
return cmd;
}
async function mainCli() {
(0, host_1.setHost)((0, nodeHost_1.createNodeHost)());
(0, mkc_1.setLogging)({
log: info,
error: error,
debug: s => {
if (debugMode)
console.debug(chalk.gray(s));
},
});
commander_1.program.version(require("../package.json").version);
createCommand("build", { isDefault: true })
.description("build project")
.option("-w, --watch", "watch source files and rebuild on changes")
.option("-n, --native", "compile native (default)")
.option("-d, --deploy", "copy resulting binary to UF2 or HEX drive")
.option("-h, --hw <id,...>", "set hardware(s) for which to compile (implies -n)")
.option("-j, --java-script", "compile to JavaScript")
.option("-u, --update", "check for web-app updates")
.option("-c, --config-path <file>", 'set configuration file path (default: "mkc.json")')
.option("-r, --mono-repo", "also build all subfolders with 'pxt.json' in them")
.option("--always-built", "always generate files in built/ folder (and not built/hw-variant/)")
.action(buildCommand);
createCommand("serve")
.description("start local simulator web server")
.option("--no-watch", "do not watch source files")
.option("-p, --port <number>", "port to listen at, default to 7001")
.option("-u, --update", "check for web-app updates")
.option("-c, --config-path <file>", 'set configuration file path (default: "mkc.json")')
.option("--force-local", "force using all local files")
.action(serveCommand);
createCommand("download")
.argument("<url>", "url to the shared project from your makecode editor")
.description("download project from share URL")
.action(commands_1.downloadCommand);
createCommand("bump")
.description("interactive version incrementer for a project or mono-repo")
.option("--version-file <file>", "write generated version number into the file")
.option("--stage", "skip git commit and push operations")
.option("--patch", "auto-increment patch version number")
.option("--minor", "auto-increment minor version number")
.option("--major", "auto-increment major version number")
.action(bumpCommand);
createCommand("init")
.addArgument(new commander_1.Argument("[template]", "project template name").choices(loader_1.descriptors.map(d => d.id)))
.argument("[repo...]", "dependencies to be added to the project")
.description("initializes the project, downloads the dependencies, optionally for a particular editor")
.option("--symlink-pxt-modules", "symlink files in pxt_modules/* for auto-completion")
.option("--link-pxt-modules", "write pxt_modules/* adhering to 'links' field in mkc.json (for pxt cli build)")
.action(commands_1.initCommand);
createCommand("install")
.description("downloads the dependencies")
.option("-r, --mono-repo", "also install in all subfolders with 'pxt.json' in them")
.option("--symlink-pxt-modules", "symlink files in pxt_modules/* for auto-completion")
.option("--link-pxt-modules", "write pxt_modules/* adhering to 'links' field in mkc.json (for pxt cli build)")
.action(commands_1.installCommand);
createCommand("clean")
.description("deletes built artifacts")
.action(commands_1.cleanCommand);
createCommand("add")
.argument("<repo>", "url to the github repository")
.argument("[name]", "name of the dependency")
.description("add new dependencies")
.option("-c, --config-path <file>", 'set configuration file path (default: "mkc.json")')
.action(commands_1.addCommand);
createCommand("search")
.argument("<query>", "extension to search for")
.description("search for an extension")
.option("-c, --config-path <file>", 'set configuration file path (default: "mkc.json")')
.action(commands_1.searchCommand);
createCommand("share")
.description("creates a public share link for the project")
.action(commands_1.shareCommand);
createCommand("stack", { hidden: true })
.description("expand stack trace")
.action(commands_1.stackCommand);
await commander_1.program.parseAsync(process.argv);
}
async function mainWrapper() {
try {
await mainCli();
}
catch (e) {
error("Exception: " + e.stack);
error("Build failed");
process.exit(1);
}
}
mainWrapper();
//# sourceMappingURL=cli.js.map