Skip to content

Commit

Permalink
Interpret search paths via -L as relative to working directory (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
01mf02 authored Nov 12, 2024
1 parent 0a3ad13 commit 7792edf
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 17 deletions.
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -623,12 +623,6 @@ The interpretation of `reduce`/`foreach` in jaq has the following advantages ove
in jq, `join(x)` converts all elements of the input array to strings and intersperses them with `x`, whereas
in jaq, `join(x)` simply calculates `x0 + x + x1 + x + ... + xn`.
When all elements of the input array and `x` are strings, jq and jaq yield the same output.
* Modules:
If the `-L` command-line option is not given, the search path for modules and data files
in jq is `["~/.jq", "$ORIGIN/../lib/jq", "$ORIGIN/../lib"]`, whereas
in jaq, it is `[]`.
However, this can be emulated in jaq by setting an alias such as
`alias jaq="jaq -L ~ -L \`which jaq\`/../lib/jq -L \`which jaq\`/../lib"`.



Expand Down
23 changes: 12 additions & 11 deletions jaq-core/src/load/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ fn expand_prefix(path: &Path, pre: &str, f: impl FnOnce() -> Option<PathBuf>) ->

#[cfg(feature = "std")]
impl<'a> Import<'a, &'a str, PathBuf> {
fn meta_paths(&self) -> Vec<PathBuf> {
fn meta_paths(&self) -> impl Iterator<Item = PathBuf> + '_ {
let paths = self.meta.as_ref().and_then(|meta| {
let v = meta.obj_key("search")?;
let iter = if let Term::Arr(Some(a)) = v {
Expand All @@ -236,7 +236,7 @@ impl<'a> Import<'a, &'a str, PathBuf> {
};
Some(iter.map(|s| Path::new(*s).to_path_buf()))
});
paths.into_iter().flatten().collect()
paths.into_iter().flatten()
}

/// Try to find a file with given extension in the given search paths.
Expand All @@ -257,16 +257,17 @@ impl<'a> Import<'a, &'a str, PathBuf> {
use std::env;
let home = || env::var_os(home).map(PathBuf::from);
let origin = || env::current_exe().ok()?.parent().map(PathBuf::from);
let expand = |path: &PathBuf| {
let home = expand_prefix(path, "~", home);
let orig = expand_prefix(path, "$ORIGIN", origin);
home.or(orig).unwrap_or_else(|| path.clone())
};

self.meta_paths()
.iter()
.chain(paths)
.map(|path| {
let home = expand_prefix(path, "~", home);
let orig = expand_prefix(path, "$ORIGIN", origin);
let path = home.as_ref().or(orig.as_ref()).unwrap_or(path);
parent.join(path).join(&rel)
})
// search paths given in the metadata are relative to the parent file, whereas
// search paths given on the command-line (`paths`, via `-L`) are not
let meta = self.meta_paths().map(|p| parent.join(expand(&p)));
meta.chain(paths.iter().map(expand))
.map(|path| path.join(&rel))
.filter_map(|path| path.canonicalize().ok())
.find(|path| path.is_file())
.ok_or_else(|| "file not found".into())
Expand Down
6 changes: 6 additions & 0 deletions jaq/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,12 @@ fn parse(
use compile::Compiler;
use load::{import, Arena, File, Loader};

let paths = if paths.is_empty() {
&["~/.jq", "$ORIGIN/../lib/jq", "$ORIGIN/../lib"].map(|x| x.into())
} else {
paths
};

let vars: Vec<_> = vars.iter().map(|v| format!("${v}")).collect();
let arena = Arena::default();
let loader = Loader::new(jaq_std::defs().chain(jaq_json::defs())).with_std_read(paths);
Expand Down

0 comments on commit 7792edf

Please sign in to comment.