mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 07:28:12 +08:00
Move branding and package install into cargo-run (#4266)
* Move branding asset fetch into cargo-run * Move frontend npm install into cargo-run * Rename branding::ensure to branding::setup * Wording nits --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -109,7 +109,7 @@ deps.crane.lib.buildPackage (
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
preBuild = ''
|
preBuild = ''
|
||||||
# Prevent `package-installer.js` from trying to update npm dependencies
|
# Prevent `cargo-run`'s frontend setup from trying to update npm dependencies
|
||||||
touch -r frontend/package-lock.json -d '+1 year' frontend/node_modules/.install-timestamp
|
touch -r frontend/package-lock.json -d '+1 year' frontend/node_modules/.install-timestamp
|
||||||
|
|
||||||
export HOME="$TMPDIR"
|
export HOME="$TMPDIR"
|
||||||
|
|||||||
@@ -1,147 +0,0 @@
|
|||||||
/* eslint-disable no-console */
|
|
||||||
|
|
||||||
import crypto from "crypto";
|
|
||||||
import fs from "fs";
|
|
||||||
import http from "http";
|
|
||||||
import https from "https";
|
|
||||||
import path from "path";
|
|
||||||
import { fileURLToPath } from "url";
|
|
||||||
import zlib from "zlib";
|
|
||||||
import * as tar from "tar";
|
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
|
||||||
const __dirname = path.dirname(__filename);
|
|
||||||
|
|
||||||
const BRANDING_INFO_FILE = path.join(__dirname, "../.branding");
|
|
||||||
const BRANDING_DIR = path.join(__dirname, "../branding");
|
|
||||||
const INSTALLED_BRANDING_INFO_FILE = path.join(BRANDING_DIR, ".branding");
|
|
||||||
const TEMP_FILE = path.join(__dirname, "branding_download.tar.gz");
|
|
||||||
|
|
||||||
function downloadFile(url, dest) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const file = fs.createWriteStream(dest);
|
|
||||||
const protocol = url.startsWith("https") ? https : http;
|
|
||||||
|
|
||||||
const request = protocol.get(url, (response) => {
|
|
||||||
if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 307) {
|
|
||||||
file.close();
|
|
||||||
fs.unlink(dest, () => {});
|
|
||||||
if (response.headers.location) {
|
|
||||||
downloadFile(response.headers.location, dest).then(resolve).catch(reject);
|
|
||||||
} else {
|
|
||||||
reject(new Error("Redirect location missing"));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.statusCode !== 200) {
|
|
||||||
file.close();
|
|
||||||
fs.unlink(dest, () => {});
|
|
||||||
reject(new Error(`Failed to download: ${response.statusCode}`));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
response.pipe(file);
|
|
||||||
file.on("finish", () => {
|
|
||||||
file.close(resolve);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
request.on("error", (err) => {
|
|
||||||
fs.unlink(dest, () => {});
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
if (!fs.existsSync(BRANDING_INFO_FILE)) {
|
|
||||||
console.error(`Branding info file not found at ${BRANDING_INFO_FILE}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = fs.readFileSync(BRANDING_INFO_FILE, "utf8");
|
|
||||||
|
|
||||||
if (fs.existsSync(INSTALLED_BRANDING_INFO_FILE)) {
|
|
||||||
const installedContent = fs.readFileSync(INSTALLED_BRANDING_INFO_FILE, "utf8");
|
|
||||||
if (content === installedContent) {
|
|
||||||
console.log("Branding assets are up to date.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lines = content
|
|
||||||
.split("\n")
|
|
||||||
.map((l) => l.trim())
|
|
||||||
.filter((l) => l.length > 0);
|
|
||||||
|
|
||||||
if (lines.length < 2) {
|
|
||||||
console.error("Branding file must contain at least two lines: URL and Hash");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = lines[0];
|
|
||||||
const expectedHash = lines[1];
|
|
||||||
|
|
||||||
console.log(`Downloading branding assets from <${url}>...`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await downloadFile(url, TEMP_FILE);
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Download failed:", err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Download complete. Verifying hash...");
|
|
||||||
|
|
||||||
const fileBuffer = fs.readFileSync(TEMP_FILE);
|
|
||||||
const hashSum = crypto.createHash("sha256");
|
|
||||||
hashSum.update(fileBuffer);
|
|
||||||
const hex = hashSum.digest("hex");
|
|
||||||
|
|
||||||
if (hex !== expectedHash) {
|
|
||||||
console.error("Hash mismatch!");
|
|
||||||
console.error(`Expected: ${expectedHash}`);
|
|
||||||
console.error(`Actual: ${hex}`);
|
|
||||||
if (fs.existsSync(TEMP_FILE)) fs.unlinkSync(TEMP_FILE);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Hash verified. Extracting...");
|
|
||||||
|
|
||||||
if (fs.existsSync(BRANDING_DIR)) {
|
|
||||||
fs.rmSync(BRANDING_DIR, { recursive: true, force: true });
|
|
||||||
}
|
|
||||||
fs.mkdirSync(BRANDING_DIR, { recursive: true });
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Extract the tar.gz file
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
fs.createReadStream(TEMP_FILE)
|
|
||||||
.pipe(zlib.createGunzip())
|
|
||||||
.pipe(
|
|
||||||
tar.x({
|
|
||||||
cwd: BRANDING_DIR,
|
|
||||||
strip: 1,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.on("error", reject)
|
|
||||||
.on("finish", resolve);
|
|
||||||
});
|
|
||||||
fs.copyFileSync(BRANDING_INFO_FILE, INSTALLED_BRANDING_INFO_FILE);
|
|
||||||
console.log("Extraction complete.");
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to extract archive:", error);
|
|
||||||
} finally {
|
|
||||||
if (fs.existsSync(TEMP_FILE)) {
|
|
||||||
fs.unlinkSync(TEMP_FILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
.then(() => process.exit(0))
|
|
||||||
.catch((err) => {
|
|
||||||
console.error("An error occurred:", err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// This script automatically installs the npm packages listed in package-lock.json and runs as part of `npm run setup` (invoked by `cargo run`).
|
|
||||||
// It skips the installation if this has already run and neither package.json nor package-lock.json has been modified since.
|
|
||||||
|
|
||||||
import { execSync } from "child_process";
|
|
||||||
import { existsSync, statSync, writeFileSync } from "fs";
|
|
||||||
|
|
||||||
const INSTALL_TIMESTAMP_FILE = "node_modules/.install-timestamp";
|
|
||||||
|
|
||||||
// Checks if the install is needed by comparing modification times
|
|
||||||
const isInstallNeeded = () => {
|
|
||||||
if (!existsSync(INSTALL_TIMESTAMP_FILE)) return true;
|
|
||||||
|
|
||||||
const timestamp = statSync(INSTALL_TIMESTAMP_FILE).mtime;
|
|
||||||
return ["package.json", "package-lock.json", "package-installer.js"].some((file) => {
|
|
||||||
return existsSync(file) && statSync(file).mtime > timestamp;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Run `npm ci` if needed and update the install timestamp
|
|
||||||
if (isInstallNeeded()) {
|
|
||||||
try {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log("Installing npm packages...");
|
|
||||||
|
|
||||||
// Check if packages are up to date, doing so quickly by using `npm ci`, preferring local cached packages, and skipping the package audit and other checks.
|
|
||||||
// The devDependencies are explicitly included because they hold the build tooling (Vite, etc.), which npm would
|
|
||||||
// otherwise omit in environments that set NODE_ENV=production (like CI does for the sake of the Vite build).
|
|
||||||
execSync("npm ci --include=dev --prefer-offline --no-audit --no-fund", { stdio: "inherit" });
|
|
||||||
|
|
||||||
// Touch the install timestamp file
|
|
||||||
writeFileSync(INSTALL_TIMESTAMP_FILE, "");
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log("Finished installing npm packages.");
|
|
||||||
} catch (_) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error("\n\n--------------------> Failed to install npm packages. Please delete `/frontend/node_modules` then try again.\n\n");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log("All npm packages are up-to-date.");
|
|
||||||
}
|
|
||||||
Generated
-64
@@ -26,7 +26,6 @@
|
|||||||
"sass": "^1.99.0",
|
"sass": "^1.99.0",
|
||||||
"svelte": "^5.55.1",
|
"svelte": "^5.55.1",
|
||||||
"svelte-check": "^4.4.6",
|
"svelte-check": "^4.4.6",
|
||||||
"tar": "^7.5.13",
|
|
||||||
"typescript": "^6.0.2",
|
"typescript": "^6.0.2",
|
||||||
"typescript-eslint": "^8.58.0",
|
"typescript-eslint": "^8.58.0",
|
||||||
"vite": "^8.0.3"
|
"vite": "^8.0.3"
|
||||||
@@ -293,19 +292,6 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@isaacs/fs-minipass": {
|
|
||||||
"version": "4.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
|
|
||||||
"integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"minipass": "^7.0.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.13",
|
"version": "0.3.13",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||||
@@ -2058,16 +2044,6 @@
|
|||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/chownr": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BlueOak-1.0.0",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/clsx": {
|
"node_modules/clsx": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||||
@@ -4394,19 +4370,6 @@
|
|||||||
"node": ">=16 || 14 >=14.17"
|
"node": ">=16 || 14 >=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minizlib": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"minipass": "^7.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mkdirp": {
|
"node_modules/mkdirp": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||||
@@ -5919,23 +5882,6 @@
|
|||||||
"url": "https://opencollective.com/synckit"
|
"url": "https://opencollective.com/synckit"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tar": {
|
|
||||||
"version": "7.5.13",
|
|
||||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz",
|
|
||||||
"integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BlueOak-1.0.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@isaacs/fs-minipass": "^4.0.0",
|
|
||||||
"chownr": "^3.0.0",
|
|
||||||
"minipass": "^7.1.2",
|
|
||||||
"minizlib": "^3.1.0",
|
|
||||||
"yallist": "^5.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tinyglobby": {
|
"node_modules/tinyglobby": {
|
||||||
"version": "0.2.15",
|
"version": "0.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||||
@@ -6523,16 +6469,6 @@
|
|||||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/yallist": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BlueOak-1.0.0",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/yocto-queue": {
|
"node_modules/yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"check": "svelte-check --fail-on-warnings && eslint",
|
"check": "svelte-check --fail-on-warnings && eslint",
|
||||||
"fix": "eslint --fix",
|
"fix": "eslint --fix"
|
||||||
"setup": "node package-installer.js && node branding-installer.js"
|
|
||||||
},
|
},
|
||||||
"//": "NOTE: `source-sans-pro` is never to be upgraded to 3.x because that renders 1px above its intended position.",
|
"//": "NOTE: `source-sans-pro` is never to be upgraded to 3.x because that renders 1px above its intended position.",
|
||||||
"///": "Waiting on <https://github.com/import-js/eslint-plugin-import/issues/3227> before we can update @eslint/js and eslint to 10.x",
|
"///": "Waiting on <https://github.com/import-js/eslint-plugin-import/issues/3227> before we can update @eslint/js and eslint to 10.x",
|
||||||
@@ -32,7 +31,6 @@
|
|||||||
"sass": "^1.99.0",
|
"sass": "^1.99.0",
|
||||||
"svelte": "^5.55.1",
|
"svelte": "^5.55.1",
|
||||||
"svelte-check": "^4.4.6",
|
"svelte-check": "^4.4.6",
|
||||||
"tar": "^7.5.13",
|
|
||||||
"typescript": "^6.0.2",
|
"typescript": "^6.0.2",
|
||||||
"typescript-eslint": "^8.58.0",
|
"typescript-eslint": "^8.58.0",
|
||||||
"vite": "^8.0.3"
|
"vite": "^8.0.3"
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ fn extract_tar_gz(body: &[u8], dir: &Path, strip: usize, include: &[String]) ->
|
|||||||
}
|
}
|
||||||
entry.unpack(&target).map_err(|e| Error::Io(e, format!("unpacking '{}'", target.display())))?;
|
entry.unpack(&target).map_err(|e| Error::Io(e, format!("unpacking '{}'", target.display())))?;
|
||||||
}
|
}
|
||||||
eprintln!("Extracted into {}", dir.display());
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
use crate::cmd::prelude::*;
|
||||||
|
use crate::{Error, workspace_dir};
|
||||||
|
|
||||||
|
const INFO_FILE: &str = ".branding";
|
||||||
|
const DIR: &str = "branding";
|
||||||
|
|
||||||
|
pub fn setup() -> Result<(), Error> {
|
||||||
|
let workspace = workspace_dir();
|
||||||
|
let info_path = workspace.join(INFO_FILE);
|
||||||
|
let dir_path = workspace.join(DIR);
|
||||||
|
let marker_path = dir_path.join(INFO_FILE);
|
||||||
|
|
||||||
|
let info = std::fs::read_to_string(&info_path).map_err(|e| Error::Io(e, format!("reading '{}'", info_path.display())))?;
|
||||||
|
|
||||||
|
if let Ok(marker) = std::fs::read_to_string(&marker_path)
|
||||||
|
&& marker == info
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut lines = info.lines().map(str::trim).filter(|l| !l.is_empty());
|
||||||
|
let url = lines
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| Error::Io(std::io::Error::other("missing URL"), format!("parsing '{}'", info_path.display())))?;
|
||||||
|
let sha256 = lines
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| Error::Io(std::io::Error::other("missing SHA-256"), format!("parsing '{}'", info_path.display())))?;
|
||||||
|
|
||||||
|
eprintln!("Downloading branding assets from <{url}>...");
|
||||||
|
|
||||||
|
if dir_path.exists() {
|
||||||
|
std::fs::remove_dir_all(&dir_path).map_err(|e| Error::Io(e, format!("removing '{}'", dir_path.display())))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::internal("download").args([url, sha256, DIR, "--extract", "--strip", "1"]).dir(&workspace).run()?;
|
||||||
|
|
||||||
|
std::fs::copy(&info_path, &marker_path).map_err(|e| Error::Io(e, format!("writing '{}'", marker_path.display())))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -11,7 +11,32 @@ pub fn frontend_dir() -> PathBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup() -> Result<(), Error> {
|
pub fn setup() -> Result<(), Error> {
|
||||||
utils::npm(["run", "setup"]).dir(frontend_dir()).run()
|
let frontend = frontend_dir();
|
||||||
|
let node_modules = frontend.join("node_modules");
|
||||||
|
let timestamp_path = node_modules.join(".install-timestamp");
|
||||||
|
|
||||||
|
let mtime = |p: PathBuf| std::fs::metadata(p).and_then(|m| m.modified()).ok();
|
||||||
|
|
||||||
|
if let Some(install_time) = mtime(timestamp_path.clone())
|
||||||
|
&& let Some(package_json_time) = mtime(frontend.join("package.json"))
|
||||||
|
&& let Some(package_lock_json_time) = mtime(frontend.join("package-lock.json"))
|
||||||
|
&& install_time >= package_json_time
|
||||||
|
&& install_time >= package_lock_json_time
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!("Installing npm packages...");
|
||||||
|
let install = || utils::npm(["ci", "--include=dev", "--prefer-offline", "--no-audit", "--no-fund"]).dir(&frontend).run();
|
||||||
|
if install().is_err() {
|
||||||
|
eprintln!("Failed to install npm packages. Wiping `frontend/node_modules` and retrying...");
|
||||||
|
let _ = std::fs::remove_dir_all(&node_modules);
|
||||||
|
install()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::fs::write(×tamp_path, "").map_err(|e| Error::Io(e, format!("writing '{}'", timestamp_path.display())))?;
|
||||||
|
eprintln!("Finished installing npm packages.");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_wasm(release: bool, native: bool) -> Result<(), Error> {
|
pub fn build_wasm(release: bool, native: bool) -> Result<(), Error> {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
pub mod branding;
|
||||||
pub mod cmd;
|
pub mod cmd;
|
||||||
pub mod frontend;
|
pub mod frontend;
|
||||||
pub mod requirements;
|
pub mod requirements;
|
||||||
|
|||||||
@@ -87,6 +87,10 @@ fn run_task(task: &Task) -> Result<(), Error> {
|
|||||||
|
|
||||||
requirements::check(task)?;
|
requirements::check(task)?;
|
||||||
|
|
||||||
|
if !matches!(task.target, Target::Cli) {
|
||||||
|
branding::setup()?;
|
||||||
|
}
|
||||||
|
|
||||||
match (&task.action, &task.target, &task.profile) {
|
match (&task.action, &task.target, &task.profile) {
|
||||||
(Action::Run, Target::Web, Profile::Debug | Profile::Default) => frontend::watch(false)?,
|
(Action::Run, Target::Web, Profile::Debug | Profile::Default) => frontend::watch(false)?,
|
||||||
(Action::Run, Target::Web, Profile::Release) => frontend::watch(true)?,
|
(Action::Run, Target::Web, Profile::Release) => frontend::watch(true)?,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ fn requirements(task: &Task) -> Vec<Requirement> {
|
|||||||
command: "rustc",
|
command: "rustc",
|
||||||
args: &["--print", "target-libdir", "--target", "wasm32-unknown-unknown"],
|
args: &["--print", "target-libdir", "--target", "wasm32-unknown-unknown"],
|
||||||
check: Check::Matches(&|out| std::path::Path::new(out.trim()).is_dir()),
|
check: Check::Matches(&|out| std::path::Path::new(out.trim()).is_dir()),
|
||||||
name: "Rust (Wasm Target)",
|
name: "Rust - Wasm Target",
|
||||||
install: "rustup target add wasm32-unknown-unknown".into(),
|
install: "rustup target add wasm32-unknown-unknown".into(),
|
||||||
skip: Some(&|task| matches!(task.target, Target::Cli)),
|
skip: Some(&|task| matches!(task.target, Target::Cli)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|||||||
Reference in New Issue
Block a user