mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00

* Update to latest Node LTS * Add sveltekit * Split tslib into separate @generated and @tslib components SvelteKit's path aliases don't support multiple locations, so our old approach of using @tslib to refer to both ts/lib and out/ts/lib will no longer work. Instead, all generated sources and their includes are placed in a separate out/ts/generated folder, and imported via @generated instead. This also allows us to generate .ts files, instead of needing to output separate .d.ts and .js files. * Switch package.json to module type * Avoid usage of baseUrl Incompatible with SvelteKit * Move sass into ts; use relative links SvelteKit's default sass support doesn't allow overriding loadPaths * jest->vitest, graphs example working with yarn dev * most pages working in dev mode * Some fixes after rebasing * Fix/silence some svelte-check errors * Get image-occlusion working with Fabric types * Post-rebase lock changes * Editor is now checked * SvelteKit build integrated into ninja * Use the new SvelteKit entrypoint for pages like congrats/deck options/etc * Run eslint once for ts/**; fix some tests * Fix a bunch of issues introduced when rebasing over latest main * Run eslint fix * Fix remaining eslint+pylint issues; tests now all pass * Fix some issues with a clean build * Latest bufbuild no longer requires @__PURE__ hack * Add a few missed dependencies * Add yarn.bat to fix Windows build * Fix pages failing to show when ANKI_API_PORT not defined * Fix svelte-check and vitest on Windows * Set node path in ./yarn * Move svelte-kit output to ts/.svelte-kit Sadly, I couldn't figure out a way to store it in out/ if out/ is a symlink, as it breaks module resolution when SvelteKit is run. * Allow HMR inside Anki * Skip SvelteKit build when HMR is defined * Fix some post-rebase issues I should have done a normal merge instead.
270 lines
7.5 KiB
Rust
270 lines
7.5 KiB
Rust
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
use std::env;
|
|
|
|
use anyhow::Result;
|
|
use ninja_gen::action::BuildAction;
|
|
use ninja_gen::build::BuildProfile;
|
|
use ninja_gen::build::FilesHandle;
|
|
use ninja_gen::cargo::CargoBuild;
|
|
use ninja_gen::cargo::CargoClippy;
|
|
use ninja_gen::cargo::CargoFormat;
|
|
use ninja_gen::cargo::CargoTest;
|
|
use ninja_gen::cargo::RustOutput;
|
|
use ninja_gen::git::SyncSubmodule;
|
|
use ninja_gen::glob;
|
|
use ninja_gen::hash::simple_hash;
|
|
use ninja_gen::input::BuildInput;
|
|
use ninja_gen::inputs;
|
|
use ninja_gen::Build;
|
|
|
|
use crate::platform::overriden_rust_target_triple;
|
|
|
|
pub fn build_rust(build: &mut Build) -> Result<()> {
|
|
prepare_translations(build)?;
|
|
build_proto_descriptors_and_interfaces(build)?;
|
|
build_rsbridge(build)
|
|
}
|
|
|
|
fn prepare_translations(build: &mut Build) -> Result<()> {
|
|
let offline_build = env::var("OFFLINE_BUILD").is_ok();
|
|
|
|
// ensure repos are checked out
|
|
build.add_action(
|
|
"ftl:repo:core",
|
|
SyncSubmodule {
|
|
path: "ftl/core-repo",
|
|
offline_build,
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
"ftl:repo:qt",
|
|
SyncSubmodule {
|
|
path: "ftl/qt-repo",
|
|
offline_build,
|
|
},
|
|
)?;
|
|
// build anki_i18n and spit out strings.json
|
|
build.add_action(
|
|
"rslib:i18n",
|
|
CargoBuild {
|
|
inputs: inputs![
|
|
glob!["rslib/i18n/**"],
|
|
glob!["ftl/{core,core-repo,qt,qt-repo}/**"],
|
|
":ftl:repo",
|
|
],
|
|
outputs: &[
|
|
RustOutput::Data("py", "pylib/anki/_fluent.py"),
|
|
RustOutput::Data("ts", "ts/lib/generated/ftl.ts"),
|
|
],
|
|
target: None,
|
|
extra_args: "-p anki_i18n",
|
|
release_override: None,
|
|
},
|
|
)?;
|
|
|
|
build.add_action(
|
|
"ftl:bin",
|
|
CargoBuild {
|
|
inputs: inputs![glob!["ftl/**"],],
|
|
outputs: &[RustOutput::Binary("ftl")],
|
|
target: None,
|
|
extra_args: "-p ftl",
|
|
release_override: None,
|
|
},
|
|
)?;
|
|
|
|
// These don't use :group notation, as it doesn't make sense to invoke multiple
|
|
// commands as a group.
|
|
build.add_action(
|
|
"ftl-sync",
|
|
FtlCommand {
|
|
args: "sync",
|
|
deps: inputs![":ftl:repo", glob!["ftl/**"]],
|
|
},
|
|
)?;
|
|
|
|
build.add_action(
|
|
"ftl-deprecate",
|
|
FtlCommand {
|
|
args: "deprecate --ftl-roots ftl/core ftl/qt --source-roots pylib qt rslib ts --json-roots ftl/usage",
|
|
deps: inputs!["ftl/core", "ftl/qt", "pylib", "qt", "rslib", "ts"],
|
|
},
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
struct FtlCommand {
|
|
args: &'static str,
|
|
deps: BuildInput,
|
|
}
|
|
|
|
impl BuildAction for FtlCommand {
|
|
fn command(&self) -> &str {
|
|
"$ftl_bin $args"
|
|
}
|
|
|
|
fn files(&mut self, build: &mut impl FilesHandle) {
|
|
build.add_inputs("", &self.deps);
|
|
build.add_inputs("ftl_bin", inputs![":ftl:bin"]);
|
|
build.add_variable("args", self.args);
|
|
build.add_output_stamp(format!("ftl/stamp.{}", simple_hash(self.args)));
|
|
}
|
|
}
|
|
|
|
fn build_proto_descriptors_and_interfaces(build: &mut Build) -> Result<()> {
|
|
let outputs = vec![
|
|
RustOutput::Data("descriptors.bin", "rslib/proto/descriptors.bin"),
|
|
RustOutput::Data("py", "pylib/anki/_backend_generated.py"),
|
|
RustOutput::Data("ts", "ts/lib/generated/backend.ts"),
|
|
];
|
|
build.add_action(
|
|
"rslib:proto",
|
|
CargoBuild {
|
|
inputs: inputs![glob!["{proto,rslib/proto}/**"], ":protoc_binary",],
|
|
outputs: &outputs,
|
|
target: None,
|
|
extra_args: "-p anki_proto",
|
|
release_override: None,
|
|
},
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn build_rsbridge(build: &mut Build) -> Result<()> {
|
|
let features = if cfg!(target_os = "linux") {
|
|
"rustls"
|
|
} else {
|
|
"native-tls"
|
|
};
|
|
build.add_action(
|
|
"pylib:rsbridge",
|
|
CargoBuild {
|
|
inputs: inputs![
|
|
glob!["{pylib/rsbridge/**,rslib/**}"],
|
|
// declare a dependency on i18n/proto so they get built first, allowing
|
|
// things depending on them to build faster, and ensuring
|
|
// changes to the ftl files trigger a rebuild
|
|
":rslib:i18n",
|
|
":rslib:proto",
|
|
// when env vars change the build hash gets updated
|
|
"$builddir/env",
|
|
"$builddir/buildhash",
|
|
// building on Windows requires python3.lib
|
|
if cfg!(windows) {
|
|
inputs![":extract:python"]
|
|
} else {
|
|
inputs![]
|
|
}
|
|
],
|
|
outputs: &[RustOutput::DynamicLib("rsbridge")],
|
|
target: overriden_rust_target_triple(),
|
|
extra_args: &format!("-p rsbridge --features {features}"),
|
|
release_override: None,
|
|
},
|
|
)
|
|
}
|
|
|
|
pub fn check_rust(build: &mut Build) -> Result<()> {
|
|
let inputs = inputs![
|
|
glob!("{rslib/**,pylib/rsbridge/**,ftl/**,build/**,tools/workspace-hack/**}"),
|
|
"Cargo.lock",
|
|
"Cargo.toml",
|
|
"rust-toolchain.toml",
|
|
];
|
|
build.add_action(
|
|
"check:format:rust",
|
|
CargoFormat {
|
|
inputs: inputs.clone(),
|
|
check_only: true,
|
|
working_dir: Some("cargo/format"),
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
"format:rust",
|
|
CargoFormat {
|
|
inputs: inputs.clone(),
|
|
check_only: false,
|
|
working_dir: Some("cargo/format"),
|
|
},
|
|
)?;
|
|
|
|
let inputs = inputs![
|
|
inputs,
|
|
// defer tests until build has completed; ensure re-run on changes
|
|
":pylib:rsbridge"
|
|
];
|
|
|
|
build.add_action(
|
|
"check:clippy",
|
|
CargoClippy {
|
|
inputs: inputs.clone(),
|
|
},
|
|
)?;
|
|
build.add_action("check:rust_test", CargoTest { inputs })?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn check_minilints(build: &mut Build) -> Result<()> {
|
|
struct RunMinilints {
|
|
pub deps: BuildInput,
|
|
pub fix: bool,
|
|
}
|
|
|
|
impl BuildAction for RunMinilints {
|
|
fn command(&self) -> &str {
|
|
"$minilints_bin $fix $stamp"
|
|
}
|
|
|
|
fn bypass_runner(&self) -> bool {
|
|
true
|
|
}
|
|
|
|
fn files(&mut self, build: &mut impl FilesHandle) {
|
|
build.add_inputs("minilints_bin", inputs![":build:minilints"]);
|
|
build.add_inputs("", &self.deps);
|
|
build.add_variable("fix", if self.fix { "fix" } else { "check" });
|
|
build.add_output_stamp(format!("tests/minilints.{}", self.fix));
|
|
}
|
|
|
|
fn on_first_instance(&self, build: &mut Build) -> Result<()> {
|
|
build.add_action(
|
|
"build:minilints",
|
|
CargoBuild {
|
|
inputs: inputs![glob!("tools/minilints/**/*")],
|
|
outputs: &[RustOutput::Binary("minilints")],
|
|
target: None,
|
|
extra_args: "-p minilints",
|
|
release_override: Some(BuildProfile::Debug),
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
let files = inputs![
|
|
glob![
|
|
"**/*.{py,rs,ts,svelte,mjs}",
|
|
"{node_modules,qt/bundle/PyOxidizer,ts/.svelte-kit}/**"
|
|
],
|
|
"Cargo.lock"
|
|
];
|
|
|
|
build.add_action(
|
|
"check:minilints",
|
|
RunMinilints {
|
|
deps: files.clone(),
|
|
fix: false,
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
"fix:minilints",
|
|
RunMinilints {
|
|
deps: files,
|
|
fix: true,
|
|
},
|
|
)?;
|
|
Ok(())
|
|
}
|