Skip to content

Commit

Permalink
Find .butane in workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
jayvdb committed Jul 14, 2023
1 parent dcebd49 commit 77b22bc
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 4 deletions.
42 changes: 42 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions butane_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ sqlite-bundled = ["butane/sqlite-bundled"]
[dependencies]
anyhow = "1.0"
butane = { features = ["default", "pg", "sqlite"], workspace = true }
cargo_metadata = "0.15"
chrono = { workspace = true }
clap = { version = "4.1" }
quote = { workspace = true }
Expand Down
62 changes: 58 additions & 4 deletions butane_cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use butane::migrations::{
};
use butane::query::BoolExpr;
use butane::{db, db::Connection, db::ConnectionMethods, migrations};
use cargo_metadata::MetadataCommand;
use chrono::Utc;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -136,7 +137,7 @@ pub fn rollback_latest(base_dir: &Path, mut conn: Connection) -> Result<()> {
}

pub fn embed(base_dir: &Path) -> Result<()> {
let srcdir = base_dir.join("src");
let srcdir = base_dir.join("../src");
if !srcdir.exists() {
eprintln!("src directory not found");
std::process::exit(1);
Expand Down Expand Up @@ -263,10 +264,63 @@ pub fn get_migrations(base_dir: &Path) -> Result<FsMigrations> {
Ok(migrations::from_root(root))
}

/// Extract the directory of a cargo workspace member identified by PackageId
pub fn extract_package_directory(
packages: &[cargo_metadata::Package],
package_id: cargo_metadata::PackageId,
) -> Result<std::path::PathBuf> {
let pkg = packages
.iter()
.find(|p| p.id == package_id)
.ok_or(anyhow::anyhow!("No package found"))?;
// Strip 'Cargo.toml' from the manifest_path
let parent = pkg.manifest_path.parent().unwrap();
Ok(parent.to_owned().into())
}

/// Find all of the `.butane` directories in the cargo workspace
pub fn find_butane_dirs_in_workspace() -> Result<Vec<PathBuf>> {
let metadata = MetadataCommand::new().no_deps().exec()?;
let workspace_members = metadata.workspace_members;

let mut possible_directories: Vec<PathBuf> = vec![];
// Find the first workspace member with a .butane
for member in workspace_members {
let package_dir = extract_package_directory(&metadata.packages, member)?;
let member_butane_dir = package_dir.join(".butane/");

if member_butane_dir.exists() {
possible_directories.push(member_butane_dir);
}
}
Ok(possible_directories)
}

/// Find one `.butane` directory if only one exists in the cargo workspace
pub fn find_butane_dir_in_workspace() -> Result<PathBuf> {
let possible_directories = find_butane_dirs_in_workspace()?;

match possible_directories.len() {
0 => Err(anyhow::anyhow!("No .butane exists")),
1 => Ok(possible_directories[0].to_owned()),
_ => Err(anyhow::anyhow!("Multiple .butane exists")),
}
}

/// Find a .butane directory to act as the base for butane.
pub fn base_dir() -> Result<PathBuf> {
std::env::current_dir()
.map(|d| d.join(".butane"))
.map_err(|e| e.into())
let current_directory = std::env::current_dir()?;
let local_butane_dir = current_directory.join(".butane/");

if !local_butane_dir.exists() {
if let Ok(member_butane_dir) = find_butane_dir_in_workspace() {
println!("Using workspace member {:?}", member_butane_dir);
return Ok(member_butane_dir);
}
}

// Fallback to the current directory
Ok(local_butane_dir)
}

pub fn handle_error(r: Result<()>) {
Expand Down
5 changes: 5 additions & 0 deletions butane_cli/tests/cargo_metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[test]
fn find_existing_butane_dirs() {
let possible_directories = butane_cli::find_butane_dirs_in_workspace().unwrap();
assert_eq!(possible_directories.len(), 3);
}

0 comments on commit 77b22bc

Please sign in to comment.