Skip to content

Commit 6632cb3

Browse files
committed
Add consistent --web-bundle for v1 & v2 CLI
- Promote `--web-bundle` to a top level option, in v1 & v2 CLI. - Allow `--web-bundle` to be specified in any position in v2 CLI. This makes use of `clap::Arg::global`. - Allow user overrides of `--web-bundle` by specifying it multiple times, and the last specification wins over the previous ones. This makes use of `clap::Arg::overrides_with`. By design, `tectonic -X build` is special as it never reads from the global config, but only from the local `Tectonic.toml` file, to ensure maximal reproducibility across different environments. Therefore, for `-X build`, the global `--web-bundle` option, if specified, is ignored with a warning `tt_note`.
1 parent 85b35d8 commit 6632cb3

4 files changed

Lines changed: 72 additions & 27 deletions

File tree

src/bin/tectonic/compile.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@ pub struct CompileOptions {
3636
#[structopt(takes_value(true), parse(from_os_str), long, short, name = "file_path")]
3737
bundle: Option<PathBuf>,
3838

39-
/// Use this URL to find resource files instead of the default
40-
#[structopt(takes_value(true), long, short, name = "url")]
41-
// TODO add URL validation
42-
web_bundle: Option<String>,
43-
4439
/// Use only resource files cached locally
4540
#[structopt(short = "C", long)]
4641
only_cached: bool,
@@ -95,7 +90,12 @@ pub struct CompileOptions {
9590
}
9691

9792
impl CompileOptions {
98-
pub fn execute(self, config: PersistentConfig, status: &mut dyn StatusBackend) -> Result<i32> {
93+
pub fn execute(
94+
self,
95+
config: PersistentConfig,
96+
status: &mut dyn StatusBackend,
97+
web_bundle: Option<String>,
98+
) -> Result<i32> {
9999
let unstable = UnstableOptions::from_unstable_args(self.unstable.into_iter());
100100

101101
// Default to allowing insecure since it would be super duper annoying
@@ -193,7 +193,7 @@ impl CompileOptions {
193193
}
194194
if let Some(path) = self.bundle {
195195
sess_builder.bundle(config.make_local_file_provider(path, status)?);
196-
} else if let Some(u) = self.web_bundle {
196+
} else if let Some(u) = web_bundle {
197197
sess_builder.bundle(config.make_cached_url_provider(&u, only_cached, None, status)?);
198198
} else {
199199
sess_builder.bundle(config.default_bundle(only_cached, status)?);

src/bin/tectonic/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ struct CliOptions {
5151
#[structopt(long = "color", name = "when", default_value = "auto", possible_values(&["always", "auto", "never"]))]
5252
cli_color: String,
5353

54+
/// Use this URL to find resource files instead of the default
55+
#[structopt(takes_value(true), long, short, name = "url", overrides_with = "url")]
56+
// TODO add URL validation
57+
web_bundle: Option<String>,
58+
5459
#[structopt(flatten)]
5560
compile: compile::CompileOptions,
5661
}
@@ -165,7 +170,7 @@ fn main() {
165170
// all so that we can print out the word "error:" in red. This code
166171
// parallels various bits of the `error_chain` crate.
167172

168-
if let Err(e) = args.compile.execute(config, &mut *status) {
173+
if let Err(e) = args.compile.execute(config, &mut *status, args.web_bundle) {
169174
status.report_error(&SyncError::new(e).into());
170175
process::exit(1)
171176
}

src/bin/tectonic/v2cli.rs

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ struct V2CliOptions {
6262
)]
6363
cli_color: String,
6464

65+
/// Use this URL to find resource files instead of the default
66+
#[structopt(
67+
takes_value(true),
68+
long,
69+
short,
70+
name = "url",
71+
overrides_with = "url",
72+
global(true)
73+
)]
74+
// TODO add URL validation
75+
web_bundle: Option<String>,
76+
6577
#[structopt(subcommand)]
6678
command: Commands,
6779
}
@@ -138,7 +150,7 @@ pub fn v2_main(effective_args: &[OsString]) {
138150

139151
// Now that we've got colorized output, pass off to the inner function.
140152

141-
let code = match args.command.execute(config, &mut *status) {
153+
let code = match args.command.execute(config, &mut *status, args.web_bundle) {
142154
Ok(c) => c,
143155
Err(e) => {
144156
status.report_error(&SyncError::new(e).into());
@@ -204,14 +216,19 @@ impl Commands {
204216
}
205217
}
206218

207-
fn execute(self, config: PersistentConfig, status: &mut dyn StatusBackend) -> Result<i32> {
219+
fn execute(
220+
self,
221+
config: PersistentConfig,
222+
status: &mut dyn StatusBackend,
223+
web_bundle: Option<String>,
224+
) -> Result<i32> {
208225
match self {
209-
Commands::Build(o) => o.execute(config, status),
226+
Commands::Build(o) => o.execute(config, status, web_bundle),
210227
Commands::Bundle(o) => o.execute(config, status),
211-
Commands::Compile(o) => o.execute(config, status),
228+
Commands::Compile(o) => o.execute(config, status, web_bundle),
212229
Commands::Dump(o) => o.execute(config, status),
213-
Commands::New(o) => o.execute(config, status),
214-
Commands::Init(o) => o.execute(config, status),
230+
Commands::New(o) => o.execute(config, status, web_bundle),
231+
Commands::Init(o) => o.execute(config, status, web_bundle),
215232
Commands::Show(o) => o.execute(config, status),
216233
Commands::Watch(o) => o.execute(config, status),
217234
Commands::External(args) => do_external(args),
@@ -254,7 +271,18 @@ pub struct BuildCommand {
254271
impl BuildCommand {
255272
fn customize(&self, _cc: &mut CommandCustomizations) {}
256273

257-
fn execute(self, config: PersistentConfig, status: &mut dyn StatusBackend) -> Result<i32> {
274+
fn execute(
275+
self,
276+
config: PersistentConfig,
277+
status: &mut dyn StatusBackend,
278+
web_bundle: Option<String>,
279+
) -> Result<i32> {
280+
// `--web-bundle` is not actually used for `-X build`,
281+
// so inform the user instead of ignoring silently.
282+
if let Some(url) = web_bundle {
283+
tt_note!(status, "--web-bundle {} ignored", &url);
284+
tt_note!(status, "using workspace bundle configuration");
285+
}
258286
let ws = Workspace::open_from_environment()?;
259287
let doc = ws.first_document();
260288

@@ -681,7 +709,12 @@ pub struct NewCommand {
681709
impl NewCommand {
682710
fn customize(&self, _cc: &mut CommandCustomizations) {}
683711

684-
fn execute(self, config: PersistentConfig, status: &mut dyn StatusBackend) -> Result<i32> {
712+
fn execute(
713+
self,
714+
config: PersistentConfig,
715+
status: &mut dyn StatusBackend,
716+
web_bundle: Option<String>,
717+
) -> Result<i32> {
685718
tt_note!(
686719
status,
687720
"creating new document in directory `{}`",
@@ -690,7 +723,7 @@ impl NewCommand {
690723

691724
let wc = WorkspaceCreator::new(self.path);
692725
ctry!(
693-
wc.create_defaulted(&config, status);
726+
wc.create_defaulted(config, status, web_bundle);
694727
"failed to create the new Tectonic workspace"
695728
);
696729
Ok(0)
@@ -704,7 +737,12 @@ pub struct InitCommand {}
704737
impl InitCommand {
705738
fn customize(&self, _cc: &mut CommandCustomizations) {}
706739

707-
fn execute(self, config: PersistentConfig, status: &mut dyn StatusBackend) -> Result<i32> {
740+
fn execute(
741+
self,
742+
config: PersistentConfig,
743+
status: &mut dyn StatusBackend,
744+
web_bundle: Option<String>,
745+
) -> Result<i32> {
708746
let path = env::current_dir()?;
709747
tt_note!(
710748
status,
@@ -714,7 +752,7 @@ impl InitCommand {
714752

715753
let wc = WorkspaceCreator::new(path);
716754
ctry!(
717-
wc.create_defaulted(&config, status);
755+
wc.create_defaulted(config, status, web_bundle);
718756
"failed to create the new Tectonic workspace"
719757
);
720758
Ok(0)

src/docmodel.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::{
2828
driver::{OutputFormat, PassSetting, ProcessingSessionBuilder},
2929
errors::{ErrorKind, Result},
3030
status::StatusBackend,
31-
test_util, tt_note,
31+
tt_note,
3232
unstable_opts::UnstableOptions,
3333
};
3434

@@ -111,9 +111,8 @@ impl DocumentExt for Document {
111111
}
112112
}
113113

114-
if config::is_config_test_mode_activated() {
115-
let bundle = test_util::TestBundle::default();
116-
Ok(Box::new(bundle))
114+
if let Ok(test_bundle) = config::maybe_return_test_bundle(None) {
115+
Ok(test_bundle)
117116
} else if let Ok(url) = Url::parse(&self.bundle_loc) {
118117
if url.scheme() != "file" {
119118
let mut cache = Cache::get_user_default()?;
@@ -216,22 +215,25 @@ pub trait WorkspaceCreatorExt {
216215
/// for the main document.
217216
fn create_defaulted(
218217
self,
219-
config: &config::PersistentConfig,
218+
config: config::PersistentConfig,
220219
status: &mut dyn StatusBackend,
220+
web_bundle: Option<String>,
221221
) -> Result<Workspace>;
222222
}
223223

224224
impl WorkspaceCreatorExt for WorkspaceCreator {
225225
fn create_defaulted(
226226
self,
227-
config: &config::PersistentConfig,
227+
config: config::PersistentConfig,
228228
status: &mut dyn StatusBackend,
229+
web_bundle: Option<String>,
229230
) -> Result<Workspace> {
230-
let bundle_loc = if config::is_config_test_mode_activated() {
231+
let bundle_loc = if config::is_test_bundle_wanted(web_bundle.clone()) {
231232
"test-bundle://".to_owned()
232233
} else {
234+
let unresolved_loc = web_bundle.unwrap_or(config.default_bundle_loc().to_owned());
233235
let mut gub = DefaultBackend::default();
234-
gub.resolve_url(config.default_bundle_loc(), status)?
236+
gub.resolve_url(&unresolved_loc, status)?
235237
};
236238

237239
Ok(self.create(bundle_loc)?)

0 commit comments

Comments
 (0)