derw
Version:
An Elm-inspired language that transpiles to TypeScript
176 lines (175 loc) • 7.31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.install = install;
const baner_1 = require("@eeue56/baner");
const result_1 = require("@eeue56/ts-core/build/main/lib/result");
const child_process_1 = require("child_process");
const promises_1 = require("fs/promises");
const package_1 = require("../package");
const utils_1 = require("./utils");
const installParser = (0, baner_1.parser)([
(0, baner_1.longFlag)("name", "name of the package e.g derw-lang/stdlib", (0, baner_1.string)()),
(0, baner_1.longFlag)("version", "name of the package e.g main or master", (0, baner_1.string)()),
(0, baner_1.longFlag)("quiet", "Keep it short and sweet", (0, baner_1.empty)()),
(0, baner_1.bothFlag)("h", "help", "This help text", (0, baner_1.empty)()),
]);
function showInstallHelp() {
console.log("To install a new package run `derw install --name {package name} --version {version}`");
console.log("Or run me without args inside a package directory to install all packages in derw-package.json");
console.log((0, baner_1.help)(installParser));
}
async function install(isInPackageDirectory, argv) {
if (!isInPackageDirectory) {
console.log("No derw-package.json found. Maybe you need to run `derw init` first?");
process.exit(1);
}
const program = (0, baner_1.parse)(installParser, argv);
if (program.flags["h/help"].isPresent) {
showInstallHelp();
return;
}
const isQuiet = program.flags.quiet.isPresent;
const isInstallNewPackage = program.flags.name.isPresent;
if (argv.length > 3 && !(isInstallNewPackage || isQuiet)) {
showInstallHelp();
return;
}
const packageFile = await (0, package_1.loadPackageFile)("derw-package.json");
if (packageFile.kind === "Err") {
console.log("Failed to parse package file due to:");
console.log(packageFile.error);
process.exit(1);
}
const errors = (0, baner_1.allErrors)(program);
if (errors.length > 0) {
console.log("Errors:");
console.log(errors.join("\n"));
process.exit(1);
}
let validPackage = packageFile.value;
if (isInstallNewPackage) {
const name = program.flags.name.arguments.value;
let version = "main";
if (program.flags.version.isPresent) {
version = program.flags.version.arguments.value;
}
if (!isQuiet)
console.log("Reading derw-package.json...");
validPackage = (0, package_1.addDependency)((0, package_1.Dependency)(name, version), validPackage);
if (!isQuiet) {
console.log(`Writing new package ${name}@${version} to derw-package.json...`);
}
await (0, promises_1.writeFile)("derw-package.json", (0, package_1.exportPackage)(validPackage));
if (!isQuiet)
console.log("Done!");
}
if (validPackage.dependencies.length === 0) {
console.log("No dependencies to install!");
return;
}
else {
if (!isQuiet)
console.log("Installing packages...");
await installPackages(validPackage, isQuiet, []);
if (!isQuiet)
console.log(`Installed ${validPackage.dependencies.length} packages`);
}
}
function isPackageAlreadyThere(package_, packages) {
for (const p of packages) {
if (package_.name === p.name)
return true;
}
return false;
}
function isAlreadyInstalled(dependency, alreadyInstalledDependency) {
return (alreadyInstalledDependency.filter((d) => d.name === dependency.name && d.version === dependency.version).length > 0);
}
async function installPackages(validPackage, isQuiet, alreadyInstalledDependencies) {
await (0, utils_1.ensureDirectoryExists)("derw-packages");
const installedPackages = [];
for (const dependency of validPackage.dependencies) {
const alreadyInstalled = isAlreadyInstalled(dependency, alreadyInstalledDependencies);
if (alreadyInstalled)
continue;
if (!isQuiet)
console.log(`Fetching ${dependency.name}@${dependency.version}...`);
const depPackage = await fetchDependencyPackage(dependency);
if (depPackage.kind === "Ok") {
if (!isPackageAlreadyThere(depPackage.value, installedPackages)) {
const subpackages = await installPackages(depPackage.value, isQuiet, [
...alreadyInstalledDependencies,
...validPackage.dependencies,
]);
for (const subpackage of subpackages) {
installedPackages.push(subpackage);
}
}
}
await cloneRepo(dependency);
await checkoutRef(dependency);
if (await (0, utils_1.fileExists)(`derw-packages/${dependency.name}/package.json`)) {
if (!isQuiet)
console.log("Installing npm packages...");
await npmInstall(dependency);
}
if (depPackage.kind === "Ok") {
installedPackages.push(depPackage.value);
}
}
return installedPackages;
}
async function cloneRepo(dependency) {
await (0, utils_1.ensureDirectoryExists)(`derw-packages/${dependency.name}`);
const res = (0, child_process_1.spawnSync)("git", ["clone", `https://github.com/${dependency.name}.git`, dependency.name], { cwd: "derw-packages", encoding: "utf-8" });
if (res.error) {
console.log(`Encountered error cloning ${dependency.name}`);
console.log(res.error);
}
}
async function checkoutRef(dependency) {
let res = (0, child_process_1.spawnSync)("git", ["fetch", `origin`, `${dependency.version}`], {
cwd: `derw-packages/${dependency.name}`,
encoding: "utf-8",
});
if (res.error) {
console.log(`Encountered error fetching ${dependency.name}`);
console.log(res.error);
}
res = (0, child_process_1.spawnSync)("git", ["reset", "--hard", `origin/${dependency.version}`], {
cwd: `derw-packages/${dependency.name}`,
encoding: "utf-8",
});
if (res.error) {
console.log(`Encountered error checkout ${dependency.name}`);
console.log(res.error);
}
res = (0, child_process_1.spawnSync)("git", ["reset", "--hard", `${dependency.version}`], {
cwd: `derw-packages/${dependency.name}`,
encoding: "utf-8",
});
if (res.error) {
console.log(`Encountered error checkout ${dependency.name}`);
console.log(res.error);
}
}
async function npmInstall(dependency) {
const res = (0, child_process_1.spawnSync)("npm", ["install"], {
cwd: `derw-packages/${dependency.name}`,
encoding: "utf-8",
});
if (res.error) {
console.log(`Encountered error installing npm packages from ${dependency.name}`);
console.log(res.error);
}
}
async function fetchDependencyPackage(dependency) {
try {
const response = await fetch(`https://raw.githubusercontent.com/${dependency.name}/${dependency.version}/derw-package.json`);
return (0, package_1.decodePackage)(await response.json());
}
catch (error) {
console.log(error);
return (0, result_1.Err)(`Failed to fetch ${dependency.name}@${dependency.version}`);
}
}