Skip to content

Commit adb4863

Browse files
committed
Use the source script path directly in case it's usable
1 parent ce0df7b commit adb4863

File tree

3 files changed

+57
-76
lines changed

3 files changed

+57
-76
lines changed

src/consts.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@ pub const SCRIPT_BODY_SUB: &str = "script";
1414
/// Substitution for the script prelude.
1515
pub const SCRIPT_PRELUDE_SUB: &str = "prelude";
1616

17-
/// The template used for script file inputs.
18-
pub const FILE_TEMPLATE: &str = r#"#{script}"#;
17+
/// The template used for script file inputs that doesn't have main function.
18+
pub const FILE_NO_MAIN_TEMPLATE: &str = r#"
19+
fn main() -> Result<(), Box<dyn std::error::Error+Sync+Send>> {
20+
{#{script}}
21+
Ok(())
22+
}
23+
"#;
1924

2025
/// The template used for `--expr` input.
2126
pub const EXPR_TEMPLATE: &str = r#"

src/main.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,11 @@ fn generate_package(action: &InputAction) -> MainResult<()> {
261261

262262
info!("generating Cargo package...");
263263
let mani_path = action.manifest_path();
264-
let script_path = action.script_path();
265264

266265
overwrite_file(&mani_path, &action.manifest)?;
267-
overwrite_file(&script_path, &action.script)?;
266+
if let Some(script) = &action.script {
267+
overwrite_file(&action.script_path, script)?;
268+
}
268269

269270
info!("disarming pkg dir cleanup...");
270271
cleanup_dir.disarm();
@@ -293,7 +294,8 @@ struct InputAction {
293294
/// Directory where the package should live.
294295
pkg_path: PathBuf,
295296

296-
script_name: String,
297+
/// Path of the source code that Cargo.toml refers.
298+
script_path: PathBuf,
297299

298300
/**
299301
Is the package directory in the cache?
@@ -315,8 +317,8 @@ struct InputAction {
315317
/// The package manifest contents.
316318
manifest: String,
317319

318-
/// The script source.
319-
script: String,
320+
/// The script source in case it has to be written.
321+
script: Option<String>,
320322

321323
/// Did the user ask to run tests or benchmarks?
322324
build_kind: BuildKind,
@@ -330,10 +332,6 @@ impl InputAction {
330332
self.pkg_path.join("Cargo.toml")
331333
}
332334

333-
fn script_path(&self) -> PathBuf {
334-
self.pkg_path.join(&self.script_name)
335-
}
336-
337335
fn cargo(&self, script_args: &[String]) -> MainResult<Command> {
338336
let release_mode = !self.debug && !matches!(self.build_kind, BuildKind::Bench);
339337

@@ -359,14 +357,12 @@ impl InputAction {
359357
};
360358

361359
if matches!(self.build_kind, BuildKind::Normal) && !self.force_compile {
362-
let script_path = self.script_path();
363-
364360
match fs::File::open(&built_binary_path) {
365361
Ok(built_binary_file) => {
366362
// Use ctime instead of mtime as cargo may copy an already
367363
// built binary (with old mtime) here:
368364
let built_binary_ctime = built_binary_file.metadata()?.created()?;
369-
match (fs::File::open(script_path), fs::File::open(manifest_path)) {
365+
match (fs::File::open(&self.script_path), fs::File::open(manifest_path)) {
370366
(Ok(script_file), Ok(manifest_file)) => {
371367
let script_mtime = script_file.metadata()?.modified()?;
372368
let manifest_mtime = manifest_file.metadata()?.modified()?;
@@ -470,10 +466,11 @@ fn decide_action_for(
470466

471467
let script_name = format!("{}.rs", input.safe_name());
472468

473-
let (mani_str, script_str) = manifest::split_input(
469+
let (mani_str, script_path, script_str) = manifest::split_input(
474470
input,
475471
&deps,
476472
&prelude,
473+
&pkg_path,
477474
&bin_name,
478475
&script_name,
479476
toolchain_version.clone(),
@@ -491,7 +488,7 @@ fn decide_action_for(
491488
force_compile: args.force,
492489
execute: !args.gen_pkg_only,
493490
pkg_path,
494-
script_name,
491+
script_path,
495492
using_cache,
496493
toolchain_version,
497494
debug,

src/manifest.rs

Lines changed: 39 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use regex;
66
use self::regex::Regex;
77
use std::collections::HashMap;
88
use std::path::Path;
9+
use std::path::PathBuf;
910

1011
use crate::consts;
1112
use crate::error::{MainError, MainResult};
@@ -22,48 +23,47 @@ pub fn split_input(
2223
input: &Input,
2324
deps: &[(String, String)],
2425
prelude_items: &[String],
26+
package_path: impl AsRef<Path>,
2527
bin_name: &str,
2628
script_name: &str,
2729
toolchain: Option<String>,
28-
) -> MainResult<(String, String)> {
30+
) -> MainResult<(String, PathBuf, Option<String>)> {
2931
fn contains_main_method(source: &str) -> bool {
3032
let re_shebang: Regex =
3133
Regex::new(r#"(?m)^ *(pub )?(async )?(extern "C" )?fn main *\("#).unwrap();
3234
re_shebang.is_match(source)
3335
}
3436

35-
let (part_mani, source, template, sub_prelude) = match input {
36-
Input::File(_, _, content) => {
37+
let source_in_package = package_path.as_ref().join(script_name);
38+
let (part_mani, source_path, source, template, sub_prelude) = match input {
39+
Input::File(_, path, content) => {
3740
assert_eq!(prelude_items.len(), 0);
38-
let (content, shebang_used) = strip_shebang(content);
41+
let content = strip_shebang(content);
3942
let (manifest, source) =
4043
find_embedded_manifest(content).unwrap_or((Manifest::Toml(""), content));
4144

42-
let source = if contains_main_method(source) {
43-
if shebang_used {
44-
format!("//\n{}", source)
45-
} else {
46-
source.to_string()
47-
}
45+
if contains_main_method(content) {
46+
(manifest, path.clone(), source.to_string(), None, false)
4847
} else {
49-
format!("fn main() -> Result<(), Box<dyn std::error::Error+Sync+Send>> {{ {{\n{} }}\n Ok(())\n}}", source)
50-
};
51-
(manifest, source, consts::FILE_TEMPLATE, false)
48+
(manifest, source_in_package, content.to_string(), Some(consts::FILE_NO_MAIN_TEMPLATE), false)
49+
}
5250
}
5351
Input::Expr(content) => (
5452
Manifest::Toml(""),
53+
source_in_package,
5554
content.to_string(),
56-
consts::EXPR_TEMPLATE,
55+
Some(consts::EXPR_TEMPLATE),
5756
true,
5857
),
5958
Input::Loop(content, count) => (
6059
Manifest::Toml(""),
60+
source_in_package,
6161
content.to_string(),
62-
if *count {
62+
Some(if *count {
6363
consts::LOOP_COUNT_TEMPLATE
6464
} else {
6565
consts::LOOP_TEMPLATE
66-
},
66+
}),
6767
true,
6868
),
6969
};
@@ -83,13 +83,15 @@ pub fn split_input(
8383
subs.insert(consts::SCRIPT_PRELUDE_SUB, &prelude_str[..]);
8484
}
8585

86-
let source = templates::expand(template, &subs)?;
86+
let source = template.map(|template| templates::expand(template, &subs)).transpose()?;
8787
let part_mani = part_mani.into_toml()?;
8888
info!("part_mani: {:?}", part_mani);
8989
info!("source: {:?}", source);
9090

91+
let source_path_str = source_path.to_str().ok_or_else(|| format!("Unable to stringify {source_path:?}"))?;
92+
9193
// It's-a mergin' time!
92-
let def_mani = default_manifest(input, bin_name, script_name, toolchain);
94+
let def_mani = default_manifest(input, bin_name, source_path_str, toolchain);
9395
let dep_mani = deps_manifest(deps)?;
9496

9597
let mani = merge_manifest(def_mani, part_mani)?;
@@ -101,7 +103,7 @@ pub fn split_input(
101103
let mani_str = format!("{}", mani);
102104
info!("manifest: {}", mani_str);
103105

104-
Ok((mani_str, source))
106+
Ok((mani_str, source_path, source))
105107
}
106108

107109
#[cfg(test)]
@@ -118,7 +120,7 @@ fn test_split_input() {
118120
let toolchain = None;
119121
macro_rules! si {
120122
($i:expr) => {
121-
split_input(&$i, &[], &[], &bin_name, &script_name, toolchain.clone()).ok()
123+
split_input(&$i, &[], &[], "", &bin_name, &script_name, toolchain.clone()).ok()
122124
};
123125
}
124126

@@ -129,7 +131,7 @@ fn test_split_input() {
129131

130132
macro_rules! r {
131133
($m:expr, $r:expr) => {
132-
Some(($m.into(), $r.into()))
134+
Some(($m.into(), "main.rs".into(), $r.into()))
133135
};
134136
}
135137

@@ -151,7 +153,7 @@ name = "n"
151153
version = "0.1.0""#,
152154
STRIP_SECTION
153155
),
154-
r#"fn main() {}"#
156+
None
155157
)
156158
);
157159

@@ -174,8 +176,7 @@ name = "n"
174176
version = "0.1.0""#,
175177
STRIP_SECTION
176178
),
177-
r#"//
178-
fn main() {}"#
179+
None
179180
)
180181
);
181182

@@ -198,8 +199,7 @@ name = "n"
198199
version = "0.1.0""#,
199200
STRIP_SECTION
200201
),
201-
r#"#[thingy]
202-
fn main() {}"#
202+
None
203203
)
204204
);
205205

@@ -208,6 +208,7 @@ fn main() {}"#
208208
&f(r#"fn main() {}"#),
209209
&[],
210210
&[],
211+
"",
211212
&bin_name,
212213
"main.rs",
213214
Some("stable".to_string())
@@ -232,7 +233,7 @@ version = "0.1.0"
232233
toolchain = "stable""#,
233234
STRIP_SECTION
234235
),
235-
r#"fn main() {}"#
236+
None
236237
)
237238
);
238239

@@ -258,10 +259,7 @@ name = "n"
258259
version = "0.1.0""#,
259260
STRIP_SECTION
260261
),
261-
r#"
262-
---
263-
fn main() {}
264-
"#
262+
None
265263
)
266264
);
267265

@@ -287,11 +285,7 @@ name = "n"
287285
version = "0.1.0""#,
288286
STRIP_SECTION
289287
),
290-
r#"[dependencies]
291-
time="0.1.25"
292-
---
293-
fn main() {}
294-
"#
288+
None
295289
)
296290
);
297291

@@ -317,10 +311,7 @@ name = "n"
317311
version = "0.1.0""#,
318312
STRIP_SECTION
319313
),
320-
r#"
321-
// Cargo-Deps: time="0.1.25"
322-
fn main() {}
323-
"#
314+
None
324315
)
325316
);
326317

@@ -347,10 +338,7 @@ name = "n"
347338
version = "0.1.0""#,
348339
STRIP_SECTION
349340
),
350-
r#"
351-
// Cargo-Deps: time="0.1.25", libc="0.2.5"
352-
fn main() {}
353-
"#
341+
None
354342
)
355343
);
356344

@@ -383,29 +371,19 @@ name = "n"
383371
version = "0.1.0""#,
384372
STRIP_SECTION
385373
),
386-
r#"
387-
/*!
388-
Here is a manifest:
389-
390-
```cargo
391-
[dependencies]
392-
time = "0.1.25"
393-
```
394-
*/
395-
fn main() {}
396-
"#
374+
None
397375
)
398376
);
399377
}
400378

401379
/**
402380
Returns a slice of the input string with the leading shebang, if there is one, omitted.
403381
*/
404-
fn strip_shebang(s: &str) -> (&str, bool) {
382+
fn strip_shebang(s: &str) -> &str {
405383
let re_shebang: Regex = Regex::new(r"^#![^\[].*?(\r\n|\n)").unwrap();
406384
match re_shebang.find(s) {
407-
Some(m) => (&s[m.end()..], true),
408-
None => (s, false),
385+
Some(m) => &s[m.end()..],
386+
None => s,
409387
}
410388
}
411389

@@ -1096,7 +1074,7 @@ Generates a default Cargo manifest for the given input.
10961074
fn default_manifest(
10971075
input: &Input,
10981076
bin_name: &str,
1099-
script_name: &str,
1077+
bin_source_path: &str,
11001078
toolchain: Option<String>,
11011079
) -> toml::value::Table {
11021080
let mut package_map = toml::map::Map::new();
@@ -1144,9 +1122,10 @@ fn default_manifest(
11441122
"name".to_string(),
11451123
toml::value::Value::String(bin_name.to_string()),
11461124
);
1125+
11471126
bin_map.insert(
11481127
"path".to_string(),
1149-
toml::value::Value::String(script_name.to_string()),
1128+
toml::value::Value::String(bin_source_path.to_string()),
11501129
);
11511130

11521131
let mut mani_map = toml::map::Map::new();

0 commit comments

Comments
 (0)