Skip to content
This repository has been archived by the owner on Jun 17, 2024. It is now read-only.

Commit

Permalink
normalize JS paths, implement proper tie-breaker logic, and add some …
Browse files Browse the repository at this point in the history
…minimal tests
  • Loading branch information
Gankra committed Mar 27, 2023
1 parent 262b296 commit f453728
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 7 deletions.
15 changes: 15 additions & 0 deletions src/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ pub fn get_project(start_dir: &Utf8Path) -> Result<WorkspaceInfo> {

/// Find the workspace root given this starting dir (potentially walking up to ancestor dirs)
fn workspace_root(start_dir: &Utf8Path) -> Result<Utf8PathBuf> {
// We want a proper absolute path so we can compare paths to workspace roots easily.
//
// Also if someone starts the path with ./ we should trim that to avoid weirdness.
// Maybe we should be using proper `canonicalize` but then we'd need to canonicalize
// every path we get from random APIs to be consistent.
let start_dir = if let Ok(clean_dir) = start_dir.strip_prefix("./") {
clean_dir.to_owned()
} else {
start_dir.to_owned()
};
let start_dir = if start_dir.is_relative() {
Utf8PathBuf::from_path_buf(std::env::current_dir().unwrap().join(start_dir)).unwrap()
} else {
start_dir
};
for path in start_dir.ancestors() {
// NOTE: orogene also looks for node_modules, but we can't do anything if there's
// no package.json, so we can just ignore that approach?
Expand Down
30 changes: 23 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub type Result<T> = std::result::Result<T, miette::Report>;
pub mod javascript;
#[cfg(feature = "cargo-projects")]
pub mod rust;
#[cfg(test)]
mod tests;

/// Kind of workspace
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand Down Expand Up @@ -252,16 +254,30 @@ pub struct AutoIncludes {
/// Concepts of both will largely be conflated, the only distinction will be
/// the top level [`WorkspaceKind`][].
pub fn get_project(start_dir: &Utf8Path) -> Option<WorkspaceInfo> {
// FIXME: should we provide and feedback/logging here?
#![allow(clippy::vec_init_then_push)]

let mut best_project = None;
let mut max_depth = 0;
let mut projects = vec![];

// FIXME: should we provide feedback/logging here?
#[cfg(feature = "cargo-projects")]
if let Ok(project) = rust::get_project(start_dir) {
return Some(project);
}
projects.push(rust::get_project(start_dir));

#[cfg(feature = "npm-projects")]
if let Ok(project) = javascript::get_project(start_dir) {
return Some(project);
projects.push(javascript::get_project(start_dir));

// If we find multiple projects, prefer the one deeper in the file system
// (the one closer to the start_dir).
for project in projects.into_iter().flatten() {
let depth = project.workspace_dir.ancestors().count();
if depth > max_depth {
best_project = Some(project);
max_depth = depth;
}
}
None

best_project
}

/// Find auto-includeable files in a dir
Expand Down
55 changes: 55 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::WorkspaceKind;

#[cfg(feature = "cargo-projects")]
#[test]
fn test_self_detect() {
let project = crate::get_project("./".into()).unwrap();
assert_eq!(project.kind, WorkspaceKind::Rust);
assert_eq!(project.package_info.len(), 1);

let package = &project.package_info[0];
assert_eq!(package.name, "axo-project");
assert_eq!(package.binaries.len(), 1);

let binary = &package.binaries[0];
assert_eq!(binary, "axo-project");
}

#[cfg(feature = "cargo-projects")]
#[test]
fn test_cargo_new() {
let project = crate::get_project("tests/projects/cargo-new/src/".into()).unwrap();
assert_eq!(project.kind, WorkspaceKind::Rust);
assert_eq!(project.package_info.len(), 1);

let package = &project.package_info[0];
assert_eq!(package.name, "cargo-new");
assert_eq!(package.binaries.len(), 1);

let binary = &package.binaries[0];
assert_eq!(binary, "cargo-new");
}

#[cfg(feature = "npm-projects")]
#[test]
fn test_npm_init_legacy() {
let project = crate::get_project("tests/projects/npm-init-legacy".into()).unwrap();
assert_eq!(project.kind, WorkspaceKind::Javascript);
assert_eq!(project.package_info.len(), 1);

let package = &project.package_info[0];
assert_eq!(package.name, "npm-init-legacy");
assert_eq!(package.binaries.len(), 0);
}

#[cfg(feature = "npm-projects")]
#[test]
fn test_npm_create_react_app() {
let project = crate::get_project("tests/projects/npm-create-react-app/src/".into()).unwrap();
assert_eq!(project.kind, WorkspaceKind::Javascript);
assert_eq!(project.package_info.len(), 1);

let package = &project.package_info[0];
assert_eq!(package.name, "npm-create-react-app");
assert_eq!(package.binaries.len(), 0);
}

0 comments on commit f453728

Please sign in to comment.