feat: add package related arguments to typstExtraArgs (#833)

This commit is contained in:
Myriad-Dreamin 2024-11-16 17:16:56 +08:00 committed by GitHub
parent d2afe78fee
commit 8e36f25cf2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 76 additions and 20 deletions

View file

@ -124,6 +124,7 @@ pub fn run_with_sources<T>(source: &str, f: impl FnOnce(&mut LspUniverse, PathBu
}; };
let mut world = LspUniverseBuilder::build( let mut world = LspUniverseBuilder::build(
EntryState::new_rooted(root.as_path().into(), None), EntryState::new_rooted(root.as_path().into(), None),
Default::default(),
Arc::new( Arc::new(
LspUniverseBuilder::resolve_fonts(CompileFontArgs { LspUniverseBuilder::resolve_fonts(CompileFontArgs {
ignore_system_fonts: true, ignore_system_fonts: true,
@ -131,8 +132,7 @@ pub fn run_with_sources<T>(source: &str, f: impl FnOnce(&mut LspUniverse, PathBu
}) })
.unwrap(), .unwrap(),
), ),
Default::default(), LspUniverseBuilder::resolve_package(None, None),
None,
) )
.unwrap(); .unwrap();
let sources = source.split("-----"); let sources = source.split("-----");

View file

@ -65,6 +65,22 @@ pub struct CompileFontArgs {
pub ignore_system_fonts: bool, pub ignore_system_fonts: bool,
} }
/// Arguments related to where packages are stored in the system.
#[derive(Debug, Clone, Parser, Default, PartialEq, Eq)]
pub struct CompilePackageArgs {
/// Custom path to local packages, defaults to system-dependent location
#[clap(long = "package-path", env = "TYPST_PACKAGE_PATH", value_name = "DIR")]
pub package_path: Option<PathBuf>,
/// Custom path to package cache, defaults to system-dependent location
#[clap(
long = "package-cache-path",
env = "TYPST_PACKAGE_CACHE_PATH",
value_name = "DIR"
)]
pub package_cache_path: Option<PathBuf>,
}
/// Common arguments of compile, watch, and query. /// Common arguments of compile, watch, and query.
#[derive(Debug, Clone, Parser, Default)] #[derive(Debug, Clone, Parser, Default)]
pub struct CompileOnceArgs { pub struct CompileOnceArgs {
@ -89,6 +105,10 @@ pub struct CompileOnceArgs {
#[clap(flatten)] #[clap(flatten)]
pub font: CompileFontArgs, pub font: CompileFontArgs,
/// Package related arguments.
#[clap(flatten)]
pub package: CompilePackageArgs,
/// The document's creation date formatted as a UNIX timestamp. /// The document's creation date formatted as a UNIX timestamp.
/// ///
/// For more information, see <https://reproducible-builds.org/specs/source-date-epoch/>. /// For more information, see <https://reproducible-builds.org/specs/source-date-epoch/>.
@ -104,26 +124,26 @@ pub struct CompileOnceArgs {
/// Path to CA certificate file for network access, especially for /// Path to CA certificate file for network access, especially for
/// downloading typst packages. /// downloading typst packages.
#[clap(long = "cert", env = "TYPST_CERT", value_name = "CERT_PATH")] #[clap(long = "cert", env = "TYPST_CERT", value_name = "CERT_PATH")]
pub certification: Option<PathBuf>, pub cert: Option<PathBuf>,
} }
impl CompileOnceArgs { impl CompileOnceArgs {
/// Get a universe instance from the given arguments. /// Get a universe instance from the given arguments.
pub fn resolve(&self) -> anyhow::Result<LspUniverse> { pub fn resolve(&self) -> anyhow::Result<LspUniverse> {
let entry = self.entry()?.try_into()?; let entry = self.entry()?.try_into()?;
let fonts = LspUniverseBuilder::resolve_fonts(self.font.clone())?;
let inputs = self let inputs = self
.inputs .inputs
.iter() .iter()
.map(|(k, v)| (Str::from(k.as_str()), Value::Str(Str::from(v.as_str())))) .map(|(k, v)| (Str::from(k.as_str()), Value::Str(Str::from(v.as_str()))))
.collect(); .collect();
let cert_path = self.certification.clone(); let fonts = LspUniverseBuilder::resolve_fonts(self.font.clone())?;
let package = LspUniverseBuilder::resolve_package(self.cert.clone(), Some(&self.package));
LspUniverseBuilder::build( LspUniverseBuilder::build(
entry, entry,
Arc::new(fonts),
Arc::new(LazyHash::new(inputs)), Arc::new(LazyHash::new(inputs)),
cert_path, Arc::new(fonts),
package,
) )
.context("failed to create universe") .context("failed to create universe")
} }
@ -185,15 +205,15 @@ impl LspUniverseBuilder {
/// See [`LspCompilerFeat`] for instantiation details. /// See [`LspCompilerFeat`] for instantiation details.
pub fn build( pub fn build(
entry: EntryState, entry: EntryState,
font_resolver: Arc<FontResolverImpl>,
inputs: ImmutDict, inputs: ImmutDict,
cert_path: Option<PathBuf>, font_resolver: Arc<FontResolverImpl>,
package_registry: HttpsRegistry,
) -> ZResult<LspUniverse> { ) -> ZResult<LspUniverse> {
Ok(LspUniverse::new_raw( Ok(LspUniverse::new_raw(
entry, entry,
Some(inputs), Some(inputs),
Vfs::new(SystemAccessModel {}), Vfs::new(SystemAccessModel {}),
HttpsRegistry::new(cert_path), package_registry,
font_resolver, font_resolver,
)) ))
} }
@ -209,6 +229,14 @@ impl LspUniverseBuilder {
})?; })?;
Ok(searcher.into()) Ok(searcher.into())
} }
/// Resolve package registry from given options.
pub fn resolve_package(
cert_path: Option<PathBuf>,
args: Option<&CompilePackageArgs>,
) -> HttpsRegistry {
HttpsRegistry::new(cert_path, args)
}
} }
/// Parses key/value pairs split by the first equal sign. /// Parses key/value pairs split by the first equal sign.

View file

@ -10,6 +10,8 @@ use reflexo_typst::ImmutPath;
use typst_kit::download::{DownloadState, Downloader}; use typst_kit::download::{DownloadState, Downloader};
use typst_kit::package::PackageStorage; use typst_kit::package::PackageStorage;
use crate::CompilePackageArgs;
/// The https package registry for tinymist. /// The https package registry for tinymist.
pub struct HttpsRegistry { pub struct HttpsRegistry {
/// The path at which local packages (`@local` packages) are stored. /// The path at which local packages (`@local` packages) are stored.
@ -53,9 +55,21 @@ impl std::ops::Deref for HttpsRegistry {
impl HttpsRegistry { impl HttpsRegistry {
/// Create a new registry. /// Create a new registry.
pub fn new(cert_path: Option<PathBuf>) -> Self { pub fn new(cert_path: Option<PathBuf>, package_args: Option<&CompilePackageArgs>) -> Self {
let local_dir = OnceLock::new();
if let Some(dir) = package_args.and_then(|args| args.package_path.as_deref()) {
let _ = local_dir.set(Some(dir.into()));
}
let cache_dir = OnceLock::new();
if let Some(dir) = package_args.and_then(|args| args.package_cache_path.as_deref()) {
let _ = cache_dir.set(Some(dir.into()));
}
Self { Self {
cert_path, cert_path,
local_dir,
cache_dir,
..Default::default() ..Default::default()
} }
} }

View file

@ -133,11 +133,15 @@ impl LanguageState {
let compile_handle = handle.clone(); let compile_handle = handle.clone();
let cache = self.cache.clone(); let cache = self.cache.clone();
let cert_path = self.compile_config().determine_certification_path(); let cert_path = self.compile_config().determine_certification_path();
let package = self.compile_config().determine_package_opts();
self.client.handle.spawn_blocking(move || { self.client.handle.spawn_blocking(move || {
// Create the world // Create the world
let font_resolver = font_resolver.wait().clone(); let font_resolver = font_resolver.wait().clone();
let verse = LspUniverseBuilder::build(entry_.clone(), font_resolver, inputs, cert_path) let package_registry =
LspUniverseBuilder::resolve_package(cert_path.clone(), Some(&package));
let verse =
LspUniverseBuilder::build(entry_.clone(), inputs, font_resolver, package_registry)
.expect("incorrect options"); .expect("incorrect options");
// Create the actor // Create the actor

View file

@ -553,8 +553,9 @@ impl CompileConfig {
root_dir: command.root, root_dir: command.root,
inputs: Arc::new(LazyHash::new(inputs)), inputs: Arc::new(LazyHash::new(inputs)),
font: command.font, font: command.font,
package: command.package,
creation_timestamp: command.creation_timestamp, creation_timestamp: command.creation_timestamp,
cert: command.certification, cert: command.cert,
}); });
} }
@ -700,6 +701,14 @@ impl CompileConfig {
opts opts
} }
/// Determines the package options.
pub fn determine_package_opts(&self) -> CompilePackageArgs {
if let Some(extras) = &self.typst_extra_args {
return extras.package.clone();
}
CompilePackageArgs::default()
}
/// Determines the font resolver. /// Determines the font resolver.
pub fn determine_fonts(&self) -> Deferred<Arc<FontResolverImpl>> { pub fn determine_fonts(&self) -> Deferred<Arc<FontResolverImpl>> {
// todo: on font resolving failure, downgrade to a fake font book // todo: on font resolving failure, downgrade to a fake font book
@ -857,6 +866,8 @@ pub struct CompileExtraOpts {
pub inputs: ImmutDict, pub inputs: ImmutDict,
/// Additional font paths. /// Additional font paths.
pub font: CompileFontArgs, pub font: CompileFontArgs,
/// Package related arguments.
pub package: CompilePackageArgs,
/// The creation timestamp for various output. /// The creation timestamp for various output.
pub creation_timestamp: Option<chrono::DateTime<chrono::Utc>>, pub creation_timestamp: Option<chrono::DateTime<chrono::Utc>>,
/// Path to certification file /// Path to certification file

View file

@ -10,20 +10,19 @@ use typst_syntax::Source;
use super::*; use super::*;
fn conv_(s: &str, for_docs: bool) -> EcoString { fn conv_(s: &str, for_docs: bool) -> EcoString {
static FONT_RESOLVER: LazyLock<Result<Arc<FontResolverImpl>>> = LazyLock::new(|| { static FONT_RESOLVER: LazyLock<Arc<FontResolverImpl>> = LazyLock::new(|| {
Ok(Arc::new( Arc::new(
LspUniverseBuilder::resolve_fonts(CompileFontArgs::default()) LspUniverseBuilder::resolve_fonts(CompileFontArgs::default())
.map_err(|e| format!("{e:?}"))?, .expect("cannot resolve default fonts"),
)) )
}); });
let font_resolver = FONT_RESOLVER.clone();
let cwd = std::env::current_dir().unwrap(); let cwd = std::env::current_dir().unwrap();
let main = Source::detached(s); let main = Source::detached(s);
let mut universe = LspUniverseBuilder::build( let mut universe = LspUniverseBuilder::build(
EntryState::new_rooted(cwd.as_path().into(), Some(main.id())), EntryState::new_rooted(cwd.as_path().into(), Some(main.id())),
font_resolver.unwrap(),
Default::default(), Default::default(),
FONT_RESOLVER.clone(),
Default::default(), Default::default(),
) )
.unwrap(); .unwrap();