mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
617 lines
19 KiB
Rust
617 lines
19 KiB
Rust
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
use anyhow::Result;
|
|
use ninja_gen::action::BuildAction;
|
|
use ninja_gen::command::RunCommand;
|
|
use ninja_gen::glob;
|
|
use ninja_gen::hashmap;
|
|
use ninja_gen::input::BuildInput;
|
|
use ninja_gen::inputs;
|
|
use ninja_gen::node::node_archive;
|
|
use ninja_gen::node::CompileSass;
|
|
use ninja_gen::node::CompileTypescript;
|
|
use ninja_gen::node::DPrint;
|
|
use ninja_gen::node::EsbuildScript;
|
|
use ninja_gen::node::Eslint;
|
|
use ninja_gen::node::GenTypescriptProto;
|
|
use ninja_gen::node::JestTest;
|
|
use ninja_gen::node::SqlFormat;
|
|
use ninja_gen::node::SvelteCheck;
|
|
use ninja_gen::node::TypescriptCheck;
|
|
use ninja_gen::rsync::RsyncFiles;
|
|
use ninja_gen::Build;
|
|
|
|
pub fn build_and_check_web(build: &mut Build) -> Result<()> {
|
|
setup_node(build)?;
|
|
build_sass(build)?;
|
|
build_and_check_tslib(build)?;
|
|
declare_and_check_other_libraries(build)?;
|
|
build_and_check_pages(build)?;
|
|
build_and_check_editor(build)?;
|
|
build_and_check_reviewer(build)?;
|
|
build_and_check_mathjax(build)?;
|
|
check_web(build)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn setup_node(build: &mut Build) -> Result<()> {
|
|
ninja_gen::node::setup_node(
|
|
build,
|
|
node_archive(build.host_platform),
|
|
&[
|
|
"dprint",
|
|
"svelte-check",
|
|
"eslint",
|
|
"sass",
|
|
"tsc",
|
|
"tsx",
|
|
"jest",
|
|
"protoc-gen-es",
|
|
],
|
|
hashmap! {
|
|
"jquery" => vec![
|
|
"jquery/dist/jquery.min.js".into()
|
|
],
|
|
"jquery-ui" => vec![
|
|
"jquery-ui-dist/jquery-ui.min.js".into()
|
|
],
|
|
"css-browser-selector" => vec![
|
|
"css-browser-selector/css_browser_selector.min.js".into(),
|
|
],
|
|
"bootstrap-dist" => vec![
|
|
"bootstrap/dist/js/bootstrap.bundle.min.js".into(),
|
|
],
|
|
"mathjax" => MATHJAX_FILES.iter().map(|&v| v.into()).collect(),
|
|
"mdi_unthemed" => [
|
|
// saved searches
|
|
"heart-outline.svg",
|
|
// today
|
|
"clock-outline.svg",
|
|
// state
|
|
"circle.svg",
|
|
"circle-outline.svg",
|
|
// flags
|
|
"flag-variant.svg",
|
|
"flag-variant-outline.svg",
|
|
"flag-variant-off-outline.svg",
|
|
// decks
|
|
"book-outline.svg",
|
|
"book-clock-outline.svg",
|
|
"book-cog-outline.svg",
|
|
// notetypes
|
|
"newspaper.svg",
|
|
// cardtype
|
|
"application-braces-outline.svg",
|
|
// fields
|
|
"form-textbox.svg",
|
|
// tags
|
|
"tag-outline.svg",
|
|
"tag-off-outline.svg",
|
|
].iter().map(|file| format!("@mdi/svg/svg/{file}").into()).collect(),
|
|
"mdi_themed" => [
|
|
// sidebar tools
|
|
"magnify.svg",
|
|
"selection-drag.svg",
|
|
// QComboBox arrows
|
|
"chevron-up.svg",
|
|
"chevron-down.svg",
|
|
// QHeaderView arrows
|
|
"menu-up.svg",
|
|
"menu-down.svg",
|
|
// drag handle
|
|
"drag-vertical.svg",
|
|
"drag-horizontal.svg",
|
|
// checkbox
|
|
"check.svg",
|
|
"minus-thick.svg",
|
|
// QRadioButton
|
|
"circle-medium.svg",
|
|
].iter().map(|file| format!("@mdi/svg/svg/{file}").into()).collect(),
|
|
},
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn build_and_check_tslib(build: &mut Build) -> Result<()> {
|
|
build.add_action(
|
|
"ts:lib:i18n",
|
|
RunCommand {
|
|
command: ":pyenv:bin",
|
|
args: "$script $strings $out",
|
|
inputs: hashmap! {
|
|
"script" => inputs!["ts/lib/genfluent.py"],
|
|
"strings" => inputs![":rslib:i18n:strings.json"],
|
|
"" => inputs!["pylib/anki/_vendor/stringcase.py"]
|
|
},
|
|
outputs: hashmap! {
|
|
"out" => vec![
|
|
"ts/lib/ftl.js",
|
|
"ts/lib/ftl.d.ts",
|
|
"ts/lib/i18n/modules.js",
|
|
"ts/lib/i18n/modules.d.ts"
|
|
]
|
|
},
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
"ts:lib:proto",
|
|
GenTypescriptProto {
|
|
protos: inputs![glob!["proto/**/*.proto"]],
|
|
include_dirs: &["proto"],
|
|
out_dir: "out/ts/lib",
|
|
out_path_transform: |path| {
|
|
path.replace("proto/", "ts/lib/")
|
|
.replace("proto\\", "ts/lib\\")
|
|
},
|
|
py_transform_script: "pylib/tools/markpure.py",
|
|
},
|
|
)?;
|
|
// ensure _service files are generated by rslib
|
|
build.add_dependency("ts:lib:proto", inputs![":rslib:proto"]);
|
|
// the generated _service.js files import @tslib/post, and esbuild won't be able
|
|
// to import the .ts file, so we need to generate a .js file for it
|
|
build.add_action(
|
|
"ts:lib:proto",
|
|
CompileTypescript {
|
|
ts_files: "ts/lib/post.ts".into(),
|
|
out_dir: "out/ts/lib",
|
|
out_path_transform: |path| path.into(),
|
|
},
|
|
)?;
|
|
|
|
let src_files = inputs![glob!["ts/lib/**"]];
|
|
eslint(build, "lib", "ts/lib", inputs![":ts:lib", &src_files])?;
|
|
|
|
build.add_action(
|
|
"check:jest:lib",
|
|
jest_test("ts/lib", inputs![":ts:lib", &src_files], true),
|
|
)?;
|
|
|
|
build.add_dependency("ts:lib", src_files);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn jest_test(folder: &str, deps: BuildInput, jsdom: bool) -> impl BuildAction + '_ {
|
|
JestTest {
|
|
folder,
|
|
deps,
|
|
jest_rc: "ts/jest.config.js".into(),
|
|
jsdom,
|
|
}
|
|
}
|
|
|
|
fn declare_and_check_other_libraries(build: &mut Build) -> Result<()> {
|
|
for (library, inputs) in [
|
|
("sveltelib", inputs![":ts:lib", glob!("ts/sveltelib/**")]),
|
|
("domlib", inputs![":ts:lib", glob!("ts/domlib/**")]),
|
|
(
|
|
"components",
|
|
inputs![":ts:lib", ":ts:sveltelib", glob!("ts/components/**")],
|
|
),
|
|
("html-filter", inputs![glob!("ts/html-filter/**")]),
|
|
] {
|
|
let library_with_ts = format!("ts:{library}");
|
|
let folder = library_with_ts.replace(':', "/");
|
|
build.add_dependency(&library_with_ts, inputs.clone());
|
|
eslint(build, library, &folder, inputs.clone())?;
|
|
|
|
if matches!(library, "domlib" | "html-filter") {
|
|
build.add_action(
|
|
&format!("check:jest:{library}"),
|
|
jest_test(&folder, inputs, true),
|
|
)?;
|
|
}
|
|
}
|
|
|
|
eslint(
|
|
build,
|
|
"sql_format",
|
|
"ts/sql_format",
|
|
inputs![glob!("ts/sql_format/**")],
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn eslint(build: &mut Build, name: &str, folder: &str, deps: BuildInput) -> Result<()> {
|
|
let eslint_rc = inputs![".eslintrc.js"];
|
|
build.add_action(
|
|
format!("check:eslint:{name}"),
|
|
Eslint {
|
|
folder,
|
|
inputs: deps.clone(),
|
|
eslint_rc: eslint_rc.clone(),
|
|
fix: false,
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
format!("fix:eslint:{name}"),
|
|
Eslint {
|
|
folder,
|
|
inputs: deps,
|
|
eslint_rc,
|
|
fix: true,
|
|
},
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn build_and_check_pages(build: &mut Build) -> Result<()> {
|
|
build.add_dependency("ts:tag-editor", inputs![glob!["ts/tag-editor/**"]]);
|
|
|
|
let mut build_page = |name: &str, html: bool, deps: BuildInput| -> Result<()> {
|
|
let group = format!("ts:pages:{name}");
|
|
let deps = inputs![deps, glob!(format!("ts/{name}/**"))];
|
|
let extra_exts = if html { &["css", "html"][..] } else { &["css"] };
|
|
build.add_action(
|
|
&group,
|
|
EsbuildScript {
|
|
script: inputs!["ts/bundle_svelte.mjs"],
|
|
entrypoint: inputs![format!("ts/{name}/index.ts")],
|
|
output_stem: &format!("ts/{name}/{name}"),
|
|
deps: deps.clone(),
|
|
extra_exts,
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
format!("check:svelte:{name}"),
|
|
SvelteCheck {
|
|
tsconfig: inputs![format!("ts/{name}/tsconfig.json")],
|
|
inputs: deps.clone(),
|
|
},
|
|
)?;
|
|
let folder = format!("ts/{name}");
|
|
eslint(build, name, &folder, deps.clone())?;
|
|
if matches!(name, "deck-options" | "change-notetype") {
|
|
build.add_action(
|
|
&format!("check:jest:{name}"),
|
|
jest_test(&folder, deps, false),
|
|
)?;
|
|
}
|
|
|
|
Ok(())
|
|
};
|
|
build_page(
|
|
"congrats",
|
|
true,
|
|
inputs![
|
|
//
|
|
":ts:lib",
|
|
":ts:components",
|
|
":sass",
|
|
],
|
|
)?;
|
|
build_page(
|
|
"deck-options",
|
|
true,
|
|
inputs![
|
|
//
|
|
":ts:lib",
|
|
":ts:components",
|
|
":ts:sveltelib",
|
|
":sass",
|
|
],
|
|
)?;
|
|
build_page(
|
|
"graphs",
|
|
true,
|
|
inputs![
|
|
//
|
|
":ts:lib",
|
|
":ts:components",
|
|
":sass",
|
|
],
|
|
)?;
|
|
build_page(
|
|
"card-info",
|
|
true,
|
|
inputs![
|
|
//
|
|
":ts:lib",
|
|
":ts:components",
|
|
":sass",
|
|
],
|
|
)?;
|
|
build_page(
|
|
"change-notetype",
|
|
true,
|
|
inputs![
|
|
//
|
|
":ts:lib",
|
|
":ts:components",
|
|
":ts:sveltelib",
|
|
":sass",
|
|
],
|
|
)?;
|
|
build_page(
|
|
"import-csv",
|
|
true,
|
|
inputs![
|
|
//
|
|
":ts:lib",
|
|
":ts:components",
|
|
":ts:sveltelib",
|
|
":ts:tag-editor",
|
|
":sass"
|
|
],
|
|
)?;
|
|
// we use the generated .css file separately
|
|
build_page(
|
|
"editable",
|
|
false,
|
|
inputs![
|
|
//
|
|
":ts:lib",
|
|
":ts:components",
|
|
":ts:domlib",
|
|
":ts:sveltelib",
|
|
":sass"
|
|
],
|
|
)?;
|
|
build_page(
|
|
"image-occlusion",
|
|
true,
|
|
inputs![
|
|
//
|
|
":ts:lib",
|
|
":ts:components",
|
|
":ts:sveltelib",
|
|
":ts:tag-editor",
|
|
":sass"
|
|
],
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn build_and_check_editor(build: &mut Build) -> Result<()> {
|
|
let editor_deps = inputs![
|
|
//
|
|
":ts:lib",
|
|
":ts:components",
|
|
":ts:domlib",
|
|
":ts:sveltelib",
|
|
":ts:tag-editor",
|
|
":ts:html-filter",
|
|
":sass",
|
|
glob!("ts/{editable,editor}/**")
|
|
];
|
|
|
|
let mut build_editor_page = |name: &str, entrypoint: &str| -> Result<()> {
|
|
let stem = format!("ts/editor/{name}");
|
|
build.add_action(
|
|
"ts:editor",
|
|
EsbuildScript {
|
|
script: inputs!["ts/bundle_svelte.mjs"],
|
|
entrypoint: inputs![format!("ts/editor/{entrypoint}.ts")],
|
|
output_stem: &stem,
|
|
deps: editor_deps.clone(),
|
|
extra_exts: &["css"],
|
|
},
|
|
)
|
|
};
|
|
|
|
build_editor_page("browser_editor", "index_browser")?;
|
|
build_editor_page("reviewer_editor", "index_reviewer")?;
|
|
build_editor_page("note_creator", "index_creator")?;
|
|
|
|
let group = "ts/editor";
|
|
build.add_action(
|
|
"check:svelte:editor",
|
|
SvelteCheck {
|
|
tsconfig: inputs![format!("{group}/tsconfig.json")],
|
|
inputs: editor_deps.clone(),
|
|
},
|
|
)?;
|
|
eslint(build, "editor", group, editor_deps)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn build_and_check_reviewer(build: &mut Build) -> Result<()> {
|
|
let reviewer_deps = inputs![":ts:lib", glob!("ts/{reviewer,image-occlusion}/**"),];
|
|
build.add_action(
|
|
"ts:reviewer:reviewer.js",
|
|
EsbuildScript {
|
|
script: inputs!["ts/bundle_ts.mjs"],
|
|
entrypoint: "ts/reviewer/index_wrapper.ts".into(),
|
|
output_stem: "ts/reviewer/reviewer",
|
|
deps: reviewer_deps.clone(),
|
|
extra_exts: &[],
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
"ts:reviewer:reviewer.css",
|
|
CompileSass {
|
|
input: inputs!["ts/reviewer/reviewer.scss"],
|
|
output: "ts/reviewer/reviewer.css",
|
|
deps: inputs![":sass", "ts/image-occlusion/review.scss"],
|
|
load_paths: vec!["."],
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
"ts:reviewer:reviewer_extras_bundle.js",
|
|
EsbuildScript {
|
|
script: inputs!["ts/bundle_ts.mjs"],
|
|
entrypoint: "ts/reviewer/reviewer_extras.ts".into(),
|
|
output_stem: "ts/reviewer/reviewer_extras_bundle",
|
|
deps: reviewer_deps.clone(),
|
|
extra_exts: &[],
|
|
},
|
|
)?;
|
|
|
|
build.add_action(
|
|
"check:typescript:reviewer",
|
|
TypescriptCheck {
|
|
tsconfig: inputs!["ts/reviewer/tsconfig.json"],
|
|
inputs: reviewer_deps.clone(),
|
|
},
|
|
)?;
|
|
eslint(build, "reviewer", "ts/reviewer", reviewer_deps)?;
|
|
build.add_action(
|
|
"check:jest:reviewer",
|
|
jest_test("ts/reviewer", inputs![":ts:reviewer"], false),
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn check_web(build: &mut Build) -> Result<()> {
|
|
let dprint_files = inputs![glob![
|
|
"**/*.{ts,mjs,js,md,json,toml,svelte,scss}",
|
|
"target/**"
|
|
]];
|
|
build.add_action(
|
|
"check:format:dprint",
|
|
DPrint {
|
|
inputs: dprint_files.clone(),
|
|
check_only: true,
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
"format:dprint",
|
|
DPrint {
|
|
inputs: dprint_files,
|
|
check_only: false,
|
|
},
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn check_sql(build: &mut Build) -> Result<()> {
|
|
build.add_action(
|
|
"check:format:sql",
|
|
SqlFormat {
|
|
inputs: inputs![glob!["**/*.sql"]],
|
|
check_only: true,
|
|
},
|
|
)?;
|
|
build.add_action(
|
|
"format:sql",
|
|
SqlFormat {
|
|
inputs: inputs![glob!["**/*.sql"]],
|
|
check_only: false,
|
|
},
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn build_and_check_mathjax(build: &mut Build) -> Result<()> {
|
|
let files = inputs![glob!["ts/mathjax/*"]];
|
|
build.add_action(
|
|
"ts:mathjax",
|
|
EsbuildScript {
|
|
script: "ts/transform_ts.mjs".into(),
|
|
entrypoint: "ts/mathjax/index.ts".into(),
|
|
deps: files.clone(),
|
|
output_stem: "ts/mathjax/mathjax",
|
|
extra_exts: &[],
|
|
},
|
|
)?;
|
|
eslint(build, "mathjax", "ts/mathjax", files.clone())?;
|
|
build.add_action(
|
|
"check:typescript:mathjax",
|
|
TypescriptCheck {
|
|
tsconfig: "ts/mathjax/tsconfig.json".into(),
|
|
inputs: files,
|
|
},
|
|
)
|
|
}
|
|
|
|
pub const MATHJAX_FILES: &[&str] = &[
|
|
"mathjax/es5/a11y/assistive-mml.js",
|
|
"mathjax/es5/a11y/complexity.js",
|
|
"mathjax/es5/a11y/explorer.js",
|
|
"mathjax/es5/a11y/semantic-enrich.js",
|
|
"mathjax/es5/input/tex/extensions/action.js",
|
|
"mathjax/es5/input/tex/extensions/all-packages.js",
|
|
"mathjax/es5/input/tex/extensions/ams.js",
|
|
"mathjax/es5/input/tex/extensions/amscd.js",
|
|
"mathjax/es5/input/tex/extensions/autoload.js",
|
|
"mathjax/es5/input/tex/extensions/bbox.js",
|
|
"mathjax/es5/input/tex/extensions/boldsymbol.js",
|
|
"mathjax/es5/input/tex/extensions/braket.js",
|
|
"mathjax/es5/input/tex/extensions/bussproofs.js",
|
|
"mathjax/es5/input/tex/extensions/cancel.js",
|
|
"mathjax/es5/input/tex/extensions/centernot.js",
|
|
"mathjax/es5/input/tex/extensions/color.js",
|
|
"mathjax/es5/input/tex/extensions/colortbl.js",
|
|
"mathjax/es5/input/tex/extensions/colorv2.js",
|
|
"mathjax/es5/input/tex/extensions/configmacros.js",
|
|
"mathjax/es5/input/tex/extensions/enclose.js",
|
|
"mathjax/es5/input/tex/extensions/extpfeil.js",
|
|
"mathjax/es5/input/tex/extensions/gensymb.js",
|
|
"mathjax/es5/input/tex/extensions/html.js",
|
|
"mathjax/es5/input/tex/extensions/mathtools.js",
|
|
"mathjax/es5/input/tex/extensions/mhchem.js",
|
|
"mathjax/es5/input/tex/extensions/newcommand.js",
|
|
"mathjax/es5/input/tex/extensions/noerrors.js",
|
|
"mathjax/es5/input/tex/extensions/noundefined.js",
|
|
"mathjax/es5/input/tex/extensions/physics.js",
|
|
"mathjax/es5/input/tex/extensions/require.js",
|
|
"mathjax/es5/input/tex/extensions/setoptions.js",
|
|
"mathjax/es5/input/tex/extensions/tagformat.js",
|
|
"mathjax/es5/input/tex/extensions/textcomp.js",
|
|
"mathjax/es5/input/tex/extensions/textmacros.js",
|
|
"mathjax/es5/input/tex/extensions/unicode.js",
|
|
"mathjax/es5/input/tex/extensions/upgreek.js",
|
|
"mathjax/es5/input/tex/extensions/verb.js",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_AMS-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Bold.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Fraktur-Bold.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Fraktur-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Main-Bold.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Main-Italic.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Main-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Math-BoldItalic.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Math-Italic.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Math-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_SansSerif-Bold.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_SansSerif-Italic.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_SansSerif-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Script-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Size1-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Size2-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Size3-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Size4-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Typewriter-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Vector-Bold.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Vector-Regular.woff",
|
|
"mathjax/es5/output/chtml/fonts/woff-v2/MathJax_Zero.woff",
|
|
"mathjax/es5/tex-chtml.js",
|
|
"mathjax/es5/sre/mathmaps/de.json",
|
|
"mathjax/es5/sre/mathmaps/en.json",
|
|
"mathjax/es5/sre/mathmaps/es.json",
|
|
"mathjax/es5/sre/mathmaps/fr.json",
|
|
"mathjax/es5/sre/mathmaps/hi.json",
|
|
"mathjax/es5/sre/mathmaps/it.json",
|
|
"mathjax/es5/sre/mathmaps/nemeth.json",
|
|
];
|
|
|
|
pub fn copy_mathjax() -> impl BuildAction {
|
|
RsyncFiles {
|
|
inputs: inputs![":node_modules:mathjax"],
|
|
target_folder: "qt/_aqt/data/web/js/vendor/mathjax",
|
|
strip_prefix: "$builddir/node_modules/mathjax/es5",
|
|
extra_args: "",
|
|
}
|
|
}
|
|
|
|
fn build_sass(build: &mut Build) -> Result<()> {
|
|
build.add_dependency("sass", inputs![glob!("sass/**")]);
|
|
|
|
build.add_action(
|
|
"css:_root-vars",
|
|
CompileSass {
|
|
input: inputs!["sass/_root-vars.scss"],
|
|
output: "sass/_root-vars.css",
|
|
deps: inputs![glob!["sass/*"]],
|
|
load_paths: vec![],
|
|
},
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|