Repository navigation
assorted: update nickel dep, set initial-env instead of writing files to disk #218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -19,51 +19,45 @@ pub(crate) async fn check_stack( | |||||||||||||||||||||||
| let mut out = Vec::new(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| use nickel_lang_core::error::report::report_as_str; | ||||||||||||||||||||||||
| use nickel_lang_core::program::{BuilderError, ProgramBuilder}; | ||||||||||||||||||||||||
| use nickel_lang_core::{error::NullReporter, eval::cache::CacheImpl, program::Program}; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // TODO: Transitioning from 'harness' => 'stack', remove after May 2026 | ||||||||||||||||||||||||
| let program_res = if stacks_dir.join(&stack).join("harness.ncl").exists() { | ||||||||||||||||||||||||
| Program::new_from_source( | ||||||||||||||||||||||||
| std::io::Cursor::new(format!( | ||||||||||||||||||||||||
| "import \"{}\"", | ||||||||||||||||||||||||
| stacks_dir | ||||||||||||||||||||||||
| .join(&stack) | ||||||||||||||||||||||||
| .join("harness.ncl") | ||||||||||||||||||||||||
| .as_os_str() | ||||||||||||||||||||||||
| .to_str() | ||||||||||||||||||||||||
| .unwrap() | ||||||||||||||||||||||||
| )), | ||||||||||||||||||||||||
| "toplevel", | ||||||||||||||||||||||||
| std::io::stderr(), | ||||||||||||||||||||||||
| NullReporter {}, | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| let entry_file = if stacks_dir.join(&stack).join("harness.ncl").exists() { | ||||||||||||||||||||||||
| stacks_dir.join(&stack).join("harness.ncl") | ||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||
| Program::new_from_source( | ||||||||||||||||||||||||
| stacks_dir.join(&stack).join("stack.ncl") | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
Comment on lines
+26
to
+30
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep stack-name diagnostics aligned with the selected entry file. Line 26-Line 30 can choose Suggested fix pub(crate) async fn check_stack(
@@
- let entry_file = if stacks_dir.join(&stack).join("harness.ncl").exists() {
- stacks_dir.join(&stack).join("harness.ncl")
+ let (entry_file, entry_filename) = if stacks_dir.join(&stack).join("harness.ncl").exists() {
+ (stacks_dir.join(&stack).join("harness.ncl"), "harness.ncl")
} else {
- stacks_dir.join(&stack).join("stack.ncl")
+ (stacks_dir.join(&stack).join("stack.ncl"), "stack.ncl")
};
@@
- out.push(check_stack_name(stack.clone(), ctx, &mut program)?);
+ out.push(check_stack_name(stack.clone(), entry_filename, ctx, &mut program)?);-fn check_stack_name(
+fn check_stack_name(
stack: String,
+ entry_filename: &str,
ctx: &CheckCtx,
program: &mut Program<CacheImpl>,
) -> Result<CheckResult, Error> {
@@
return Ok(CheckResult::stack_name_fail(format!(
- "stack defined in {}/stack.ncl has name {}",
+ "stack defined in {}/{} has name {}",
stack,
+ entry_filename,
s.as_str()
)));📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| let program_res: Result<Program<CacheImpl>, _> = ProgramBuilder::new() | ||||||||||||||||||||||||
| .add_source( | ||||||||||||||||||||||||
| std::io::Cursor::new(format!( | ||||||||||||||||||||||||
| "import \"{}\"", | ||||||||||||||||||||||||
| stacks_dir | ||||||||||||||||||||||||
| .join(&stack) | ||||||||||||||||||||||||
| .join("stack.ncl") | ||||||||||||||||||||||||
| .as_os_str() | ||||||||||||||||||||||||
| .to_str() | ||||||||||||||||||||||||
| .unwrap() | ||||||||||||||||||||||||
| entry_file.as_os_str().to_str().unwrap() | ||||||||||||||||||||||||
| )), | ||||||||||||||||||||||||
| "toplevel", | ||||||||||||||||||||||||
| std::io::stderr(), | ||||||||||||||||||||||||
| NullReporter {}, | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| .add_import_paths([ctx.stdlib_dir.clone()].iter()) | ||||||||||||||||||||||||
| .with_reporter(NullReporter {}) | ||||||||||||||||||||||||
| .with_trace(std::io::stderr()) | ||||||||||||||||||||||||
| .build(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| let mut program: Program<CacheImpl> = match program_res { | ||||||||||||||||||||||||
| Ok(p) => p, | ||||||||||||||||||||||||
| Err(e) => { | ||||||||||||||||||||||||
| let msg = match e { | ||||||||||||||||||||||||
| BuilderError::NoInputs => unreachable!(), | ||||||||||||||||||||||||
| BuilderError::Io { path, error } => match path { | ||||||||||||||||||||||||
| Some(p) => format!("{}: {}", p.display(), error), | ||||||||||||||||||||||||
| None => format!("{}", error), | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| return Ok(vec![CheckResult::parse_failure(format!( | ||||||||||||||||||||||||
| "loading failed: {}", | ||||||||||||||||||||||||
| e | ||||||||||||||||||||||||
| msg | ||||||||||||||||||||||||
| ))]); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| program.add_import_paths([ctx.stdlib_dir.clone()].iter()); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if let Err(e) = program.typecheck(nickel_lang_core::typecheck::TypecheckMode::Walk) { | ||||||||||||||||||||||||
| return Ok(vec![CheckResult::parse_failure(report_as_str( | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Does nickel-lang-core Number::try_from fail for NaN and Infinity f64 values?💡 Result:
No definitive evidence found in the searched sources that directly answers whether nickel-lang-core’s Number::try_from fails (returns Err) specifically for f64 NaN and ±Infinity. What I can say from the evidence gathered: 1) The available nickel-lang-core documentation pages in the search results don’t expose the implementation or behavior of Number::try_from for f64 NaN/Infinity (the rustdoc snippets shown are general crate docs, not the conversion implementation). 2) The search turned up Nickel issues/PRs about YAML/serialization panics and large numbers, but nothing in those results discusses NaN/Infinity handling for Number::try_from. 3) The only authoritative “NaN/Infinity” behavior I found in the evidence is about Rust f64 itself (NaN/Infinity are representable) and about Malachite float conversions, neither of which is directly tied to nickel-lang-core’s Number::try_from. If you want, I can do one more targeted search by opening the exact source file that defines nickel-lang-core::term::Number::try_from (or searching within t 8000 he nickel-lang-core crate sources for “try_from” and “Number::try_from”), then verify the NaN/Infinity branches precisely.
Citations:
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 556
🏁 Script executed:
# Look at the structure of the crates directory ls -la crates/Repository: gominimal/minimal
Length of output: 1245
🏁 Script executed:
# Check the specific crate's Cargo.toml cat crates/args/Cargo.tomlRepository: gominimal/minimal
Length of output: 388
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 2456
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 1312
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 1210
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 2194
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 6864
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 3000
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 43
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 982
🌐 Web query:
nickel-lang Number::try_from implementation f64 NaN Infinity💡 Result:
I couldn’t find (in the sources surfaced by the searches) Nickel’s specific
Number::try_fromimplementation that handlesf64inputs likeNaN,+Infinity, or-Infinity. What I can support from authoritative Nickel sources is: 1) Nickel’s user-facing number type is arbitrary-precision rationals internally, but during deserialization it goes through 64-bit floating point numbers (“Numbers are deserialized as 64-bit floating point numbers, in line with common JSON implementations”) [1]. 2) Nickel’s stdlib documentation explicitly notes that when operating withpow, if exponent/result fallbacks to float are used, the docs excludeNaNand infinity from that float conversion path [2]. So, the likely behavior ofNumber::try_from(f64)withNaN/Infinityis somewhere in Nickel’s Rust core conversions (probably involving Malachite’s float/Float conversions), but the exact match arm / error-or-success behavior forNaNandInfinityis not present in the results I retrieved. If you want, paste a link to the Rust file/line whereNumber::try_from(or theTryFrom<f64> for Numberimpl) lives in your Nickel version, and I can precisely extract and summarize how it treatsNaNand±Infinitywith line-level citations.Citations:
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 291
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 3957
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 371
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 43
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 2345
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 559
🌐 Web query:
Rust f64 parsing "NaN" "Infinity" parse method💡 Result:
In Rust, the f64::from_str method—which is invoked when calling str::parse::—fully supports parsing special floating-point values, including "NaN", "Infinity", and their signed variants [1][2]. When parsing a string to f64, the input is treated in a case-insensitive manner [1]. The parser accepts the following variations [1]: - "inf", "infinity", "+inf", "+infinity", "-inf", "-infinity" (all map to the corresponding infinity value) [1][2] - "nan", "+nan", "-nan" (all map to NaN) [1] The parsing logic follows a specific EBNF grammar [1]. If a string does not match the valid floating-point format, the method returns an Err(ParseFloatError) [1][3]. Note that these special values are only supported by the standard from_str implementation for f32 and f64; they are not supported by from_str_radix, which strictly parses numeric characters [2].
Citations:
🌐 Web query:
site:github.com/nickel-lang/nickel Number try_from f64 implementation💡 Result:
There is no standard library Number type in Rust that implements TryFrom. The TryFrom trait in Rust's standard library is designed for safe, fallible conversions between types. While specific crates or third-party libraries may define their own Number types and implement TryFrom for them, it is not a feature of the Rust standard library itself. In the context of the Nickel configuration language (which is implemented in Rust), developers may work with arbitrary-precision numbers or other custom number representations [1][2], but these are specific to that project and not a general Rust language standard [3]. If you are encountering this in code, it is likely a custom implementation within the specific codebase you are examining [1][3].
Citations:
🌐 Web query:
nickel-lang-core Number type finite nan infinity constraints💡 Result:
In Nickel, the Number type is implemented as an arbitrary-precision rational number [1][2]. Because it uses this representation, it inherently does not support IEEE 754 concepts such as NaN (Not-a-Number), positive infinity, or negative infinity [1][2]. Key characteristics of the Nickel Number type include: - Exact Arithmetic: Basic arithmetic operations (addition, subtraction, multiplication, and division) are performed on rationals and do not incur rounding errors [2]. - Conversion Behavior: While Nickel defaults to arbitrary-precision rationals, certain operations—specifically non-integral exponentiation via
std.number.pow—may convert operands to 64-bit floating-point numbers to perform the calculation [1][2]. In these specific cases, if the resulting value exceeds the range of a 64-bit float, or if the operation involves values that would typically produce NaN or infinity, the behavior is governed by floating-point arithmetic; however, these resulting values are converted back to rationals, and the language is designed to avoid IEEE 754 artifacts like NaN and infinity in its primary representation [1]. - Constraints: Since Nickel does not natively represent NaN or infinity as Number values, standard programs do not encounter them. If you need to enforce constraints such as finite range, you must define custom contracts [3][4]. For example, you can use a contract to restrict a number to a specific range (e.g.,value >= 0 && value <= 65535) [3]. In summary, Nickel's core design prioritizes precision through rationals over IEEE 754 floating-point behavior, effectively eliminating NaN and infinity from the Number type's standard domain [1][2].Citations:
🏁 Script executed:
Repository: gominimal/minimal
Length of output: 811
unwrap()onNumber::try_fromwill panic for non-finite floats.Nickel's
Numbertype represents arbitrary-precision rationals and does not support NaN, positive infinity, or negative infinity. The parsing code accepts these values—Rust'sf64::parse()successfully parses "NaN", "Infinity", and "-Infinity"—so a user can provide such input, which will then panic whenNumber::try_from(*f).unwrap()is called. Validate inputs inPrimitiveSpec::parseto reject non-finite numbers:Proposed fix
PrimitiveSpec::Number => { let f: f64 = s .parse() .map_err(|_| format!("expected a number, got `{s}`"))?; + if !f.is_finite() { + return Err(format!("expected a finite number, got `{s}`")); + } Ok(ScalarArg::Number(f)) }🤖 Prompt for AI Agents