Skip to content

Commit

Permalink
WIP: Add JustfileKind to Search: Path or Stdin
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcin Drzymala committed Jun 10, 2024
1 parent 2b3bed9 commit 5b0c7ef
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 23 deletions.
170 changes: 149 additions & 21 deletions src/search.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,60 @@
use {super::*, std::path::Component};
use {
super::*,
std::{
io::{stdin, Read},
path::{Component, Display},
},
};

const DEFAULT_JUSTFILE_NAME: &str = JUSTFILE_NAMES[0];
pub(crate) const JUSTFILE_NAMES: &[&str] = &["justfile", ".justfile"];
const PROJECT_ROOT_CHILDREN: &[&str] = &[".bzr", ".git", ".hg", ".svn", "_darcs"];

pub(crate) struct Search {
pub(crate) justfile: PathBuf,
pub(crate) justfile: JustfileKind,
pub(crate) working_directory: PathBuf,
}

#[derive(Debug, Clone)]
pub enum JustfileKind {
Path { path: PathBuf },
Stdin { data: String },
}

impl JustfileKind {
pub fn to_str(&self) -> Option<&str> {
match self {
JustfileKind::Path { path } => path.to_str(),
JustfileKind::Stdin { .. } => None,
}
}

pub fn display(&self) -> Display<'_> {
match self {
JustfileKind::Path { path } => path.display(),
JustfileKind::Stdin { .. } => Path::new("<STDIN>").display(),
}
}

pub fn parent(&self) -> Option<&Path> {
match self {
JustfileKind::Path { path } => path.parent(),
JustfileKind::Stdin { .. } => None,
}
}
}

impl PartialEq<PathBuf> for JustfileKind {
fn eq(&self, other: &PathBuf) -> bool {
match self {
JustfileKind::Path { path } => path == other,
JustfileKind::Stdin { .. } => false,
}
}
}

impl Search {
/// Search for a Justfile
pub(crate) fn find(
search_config: &SearchConfig,
invocation_directory: &Path,
Expand All @@ -19,19 +64,21 @@ impl Search {
SearchConfig::FromSearchDirectory { search_directory } => {
let search_directory = Self::clean(invocation_directory, search_directory);

let justfile = Self::justfile(&search_directory)?;
let path = Self::justfile(&search_directory)?;
let justfile = JustfileKind::Path { path: path.clone() };

let working_directory = Self::working_directory_from_justfile(&justfile)?;
let working_directory = Self::working_directory_from_justfile(&path)?;

Ok(Self {
justfile,
working_directory,
})
}
SearchConfig::WithJustfile { justfile } => {
let justfile = Self::clean(invocation_directory, justfile);
let path = Self::clean(invocation_directory, justfile);
let justfile = JustfileKind::Path { path: path.clone() };

let working_directory = Self::working_directory_from_justfile(&justfile)?;
let working_directory = Self::working_directory_from_justfile(&path)?;

Ok(Self {
justfile,
Expand All @@ -41,24 +88,65 @@ impl Search {
SearchConfig::WithJustfileAndWorkingDirectory {
justfile,
working_directory,
} => Ok(Self {
justfile: Self::clean(invocation_directory, justfile),
working_directory: Self::clean(invocation_directory, working_directory),
}),
} => {
let path = Self::clean(invocation_directory, justfile);
let justfile = JustfileKind::Path { path };

Ok(Self {
justfile,
working_directory: Self::clean(invocation_directory, working_directory),
})
}
SearchConfig::WithStdin => {
let working_directory = PathBuf::from(invocation_directory);

let mut data = String::new();
if let Err(err) = stdin().read_to_string(&mut data) {
return Err(SearchError::Io {
directory: working_directory,
io_error: err,
});
}
let justfile = JustfileKind::Stdin { data };

Ok(Self {
justfile,
working_directory,
})
}
SearchConfig::WithStdinAndWorkingDirectory { working_directory } => {
let working_directory = working_directory.to_owned();

let mut data = String::new();
if let Err(err) = stdin().read_to_string(&mut data) {
return Err(SearchError::Io {
directory: working_directory,
io_error: err,
});
}
let justfile = JustfileKind::Stdin { data };

Ok(Self {
justfile,
working_directory,
})
}
}
}

pub(crate) fn find_next(starting_dir: &Path) -> SearchResult<Self> {
let justfile = Self::justfile(starting_dir)?;
let path = Self::justfile(starting_dir)?;
let justfile = JustfileKind::Path { path: path.clone() };

let working_directory = Self::working_directory_from_justfile(&justfile)?;
let working_directory = Self::working_directory_from_justfile(&path)?;

Ok(Self {
justfile,
working_directory,
})
}

/// Search for a Justfile when running "init" subcommand
pub(crate) fn init(
search_config: &SearchConfig,
invocation_directory: &Path,
Expand All @@ -67,7 +155,8 @@ impl Search {
SearchConfig::FromInvocationDirectory => {
let working_directory = Self::project_root(invocation_directory)?;

let justfile = working_directory.join(DEFAULT_JUSTFILE_NAME);
let path = working_directory.join(DEFAULT_JUSTFILE_NAME);
let justfile = JustfileKind::Path { path };

Ok(Self {
justfile,
Expand All @@ -80,7 +169,8 @@ impl Search {

let working_directory = Self::project_root(&search_directory)?;

let justfile = working_directory.join(DEFAULT_JUSTFILE_NAME);
let path = working_directory.join(DEFAULT_JUSTFILE_NAME);
let justfile = JustfileKind::Path { path };

Ok(Self {
justfile,
Expand All @@ -89,9 +179,10 @@ impl Search {
}

SearchConfig::WithJustfile { justfile } => {
let justfile = Self::clean(invocation_directory, justfile);
let path = Self::clean(invocation_directory, justfile);

let working_directory = Self::working_directory_from_justfile(&justfile)?;
let working_directory = Self::working_directory_from_justfile(&path)?;
let justfile = JustfileKind::Path { path };

Ok(Self {
justfile,
Expand All @@ -102,14 +193,51 @@ impl Search {
SearchConfig::WithJustfileAndWorkingDirectory {
justfile,
working_directory,
} => Ok(Self {
justfile: Self::clean(invocation_directory, justfile),
working_directory: Self::clean(invocation_directory, working_directory),
}),
} => {
let path = Self::clean(invocation_directory, justfile);
let justfile = JustfileKind::Path { path };
let working_directory = Self::clean(invocation_directory, working_directory);
Ok(Self {
justfile,
working_directory,
})
}

SearchConfig::WithStdin => {
let working_directory = Self::project_root(invocation_directory)?;
let mut data = String::new();
if let Err(err) = io::stdin().read_to_string(&mut data) {
return Err(SearchError::Io {
directory: working_directory,
io_error: err,
});
}
let justfile = JustfileKind::Stdin { data };
Ok(Self {
justfile,
working_directory,
})
}

SearchConfig::WithStdinAndWorkingDirectory { working_directory } => {
let working_directory = working_directory.to_owned();
let mut data = String::new();
if let Err(err) = io::stdin().read_to_string(&mut data) {
return Err(SearchError::Io {
directory: working_directory,
io_error: err,
});
}
let justfile = JustfileKind::Stdin { data };
Ok(Self {
justfile,
working_directory,
})
}
}
}

pub(crate) fn justfile(directory: &Path) -> SearchResult<PathBuf> {
fn justfile(directory: &Path) -> SearchResult<PathBuf> {
for directory in directory.ancestors() {
let mut candidates = BTreeSet::new();

Expand Down
5 changes: 3 additions & 2 deletions src/testing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use {super::*, pretty_assertions::assert_eq};
use {self::search::JustfileKind, super::*, pretty_assertions::assert_eq};

pub(crate) fn compile(src: &str) -> Justfile {
Compiler::test_compile(src).expect("expected successful compilation")
Expand All @@ -17,7 +17,8 @@ pub(crate) fn config(args: &[&str]) -> Config {

pub(crate) fn search(config: &Config) -> Search {
let working_directory = config.invocation_directory.clone();
let justfile = working_directory.join("justfile");
let path = working_directory.join("justfile");
let justfile = JustfileKind::Path { path };

Search {
justfile,
Expand Down

0 comments on commit 5b0c7ef

Please sign in to comment.