mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00

* CONTRIBUTORS: Add myself to the contributors list * Add support for offline builds Downloading files during build time is a non-starter for FreeBSD ports (and presumably for other *BSD ports and some Linux distros as well). In order to still be able to build Anki successfully, two new environment variables have been added that can be set accordingly: * NO_VENV: If set, the Python system environment is used instead of a venv. This is necessary if there are no usable Python wheels for a platform, e.g. PyQt6. * OFFLINE_BUILD: If set, the git repository synchronization (translation files, build hash, etc.) is skipped. To successfully build Anki offline, following conditions must be met: 1. All required dependencies (node, Python, rust, yarn, etc.) must be present in the build environment. 2. The offline repositories for the translation files must be copied/linked to ftl/qt-repo and ftl/core-repo. 3. The Python pseudo venv needs to be setup: $ mkdir out/pyenv/bin $ ln -s /path/to/python out/pyenv/bin/python $ ln -s /path/to/protoc-gen-mypy out/pyenv/bin/protoc-gen-mypy 4. Create the offline cache for yarn and use its own environment variable YARN_CACHE_FOLDER to it: YARN_CACHE_FOLDER=/path/to/the/yarn/cache $ /path/to/yarn install --ignore-scripts 5. Build Anki: $ /path/to/cargo build --package runner --release --verbose --verbose $ OFFLINE_BUILD=1 \ NO_VENV=1 \ ${WRKSRC}/out/rust/release/runner build wheels
84 lines
2.5 KiB
Rust
84 lines
2.5 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 itertools::Itertools;
|
|
|
|
use super::*;
|
|
use crate::action::BuildAction;
|
|
use crate::input::BuildInput;
|
|
|
|
pub struct SyncSubmodule {
|
|
pub path: &'static str,
|
|
pub offline_build: bool,
|
|
}
|
|
|
|
impl BuildAction for SyncSubmodule {
|
|
fn command(&self) -> &str {
|
|
if self.offline_build {
|
|
"echo OFFLINE_BUILD is set, skipping git repository update for $path"
|
|
} else {
|
|
"git -c protocol.file.allow=always submodule update --init $path"
|
|
}
|
|
}
|
|
|
|
fn files(&mut self, build: &mut impl build::FilesHandle) {
|
|
if !self.offline_build {
|
|
if let Some(head) = locate_git_head() {
|
|
build.add_inputs("", head);
|
|
} else {
|
|
println!("Warning, .git/HEAD not found; submodules may be stale");
|
|
}
|
|
}
|
|
|
|
build.add_variable("path", self.path);
|
|
build.add_output_stamp(format!("git/{}", self.path));
|
|
}
|
|
|
|
fn on_first_instance(&self, build: &mut Build) -> Result<()> {
|
|
build.pool("git", 1);
|
|
Ok(())
|
|
}
|
|
|
|
fn concurrency_pool(&self) -> Option<&'static str> {
|
|
Some("git")
|
|
}
|
|
}
|
|
|
|
/// We check the mtime of .git/HEAD to detect when we should sync submodules.
|
|
/// If this repo is a submodule of another project, .git/HEAD will not exist,
|
|
/// and we fall back on .git/modules/*/HEAD in a parent folder instead.
|
|
fn locate_git_head() -> Option<BuildInput> {
|
|
let standard_path = Utf8Path::new(".git/HEAD");
|
|
if standard_path.exists() {
|
|
return Some(inputs![standard_path.to_string()]);
|
|
}
|
|
|
|
let mut folder = Utf8PathBuf::from_path_buf(
|
|
dunce::canonicalize(Utf8Path::new(".").canonicalize().unwrap()).unwrap(),
|
|
)
|
|
.unwrap();
|
|
loop {
|
|
let path = folder.join(".git").join("modules");
|
|
if path.exists() {
|
|
let heads = path
|
|
.read_dir_utf8()
|
|
.unwrap()
|
|
.filter_map(|p| {
|
|
let head = p.unwrap().path().join("HEAD");
|
|
if head.exists() {
|
|
Some(head.as_str().replace(':', "$:"))
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.collect_vec();
|
|
return Some(inputs![heads]);
|
|
}
|
|
if let Some(parent) = folder.parent() {
|
|
folder = parent.to_owned();
|
|
} else {
|
|
return None;
|
|
}
|
|
}
|
|
}
|