From 08e8f4f8f7713725d488eac1bbf37263eff43932 Mon Sep 17 00:00:00 2001 From: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:22:17 -0400 Subject: [PATCH] Branches: dont require projects unless explicitly needed (#1259) * allow branching commands in non-project context * clippy * remove unused function * remove default branch from toml --- src/branch/context.rs | 52 ++++++++++++++++++++++++++++------------- src/branch/create.rs | 6 ++++- src/branch/drop.rs | 12 ++++++---- src/branch/list.rs | 4 +--- src/branch/main.rs | 4 ++-- src/branch/merge.rs | 11 +++++++-- src/branch/rebase.rs | 19 ++++++++++----- src/branch/rename.rs | 4 ++-- src/branch/switch.rs | 12 +++++++--- src/migrations/merge.rs | 4 ++-- src/portable/config.rs | 8 ------- 11 files changed, 86 insertions(+), 50 deletions(-) diff --git a/src/branch/context.rs b/src/branch/context.rs index 9f2bc1590..b51716fdc 100644 --- a/src/branch/context.rs +++ b/src/branch/context.rs @@ -1,41 +1,61 @@ use std::fs; use crate::portable::config::Config; use std::path::{Path, PathBuf}; +use crate::connect::Connection; use crate::credentials; use crate::portable::options::InstanceName; use crate::portable::project::{instance_name, stash_path}; pub struct Context { - pub project_config: Config, - pub project_branch: String, - pub branch: String, + pub project_config: Option, + pub branch: Option, - - project_dir: PathBuf, + project_dir: Option, } impl Context { - pub async fn new(project_dir: &Path) -> anyhow::Result { - let project_config = crate::portable::config::read(&project_dir.join("edgedb.toml"))?; - let project_branch = project_config.edgedb.branch.clone(); + pub async fn new(project_dir: Option<&PathBuf>) -> anyhow::Result { + let project_config = match project_dir { + Some(path) => Some(crate::portable::config::read(&path.join("edgedb.toml"))?), + None => None + }; - let path = credentials::path(&get_instance_name(project_dir)?)?; - let credentials = credentials::read(&path).await?; + let credentials = match project_dir { + Some(path) => Some(credentials::read(&credentials::path(&get_instance_name(&path)?)?).await?), + None => None + }; Ok(Context { project_config, - branch: credentials.database.unwrap_or(project_branch.clone()), - project_branch, - project_dir: PathBuf::from(project_dir), + branch: credentials.and_then(|v| v.database), + project_dir: project_dir.map(PathBuf::from) }) } - pub fn get_instance_name(&self) -> anyhow::Result { - get_instance_name(&self.project_dir) + pub async fn get_default_branch_name(&self, connection: &mut Connection) -> anyhow::Result<&str> { + let version = connection.get_version().await?.specific(); + + if version.major >= 5 { + return Ok("main") + } + + Ok("edgedb") + } + + pub fn get_instance_name(&self) -> anyhow::Result> { + Ok(match &self.project_dir { + Some(dir) => Some(get_instance_name(&dir)?), + None => None + }) } pub async fn update_branch(&self, branch: &String) -> anyhow::Result<()> { - let path = credentials::path(&self.get_instance_name()?)?; + let instance_name = match self.get_instance_name()? { + Some(i) => i, + None => return Ok(()) + }; + + let path = credentials::path(&instance_name)?; let mut credentials = credentials::read(&path).await?; diff --git a/src/branch/create.rs b/src/branch/create.rs index 8373f3b45..6a00dff9d 100644 --- a/src/branch/create.rs +++ b/src/branch/create.rs @@ -10,7 +10,11 @@ pub async fn main( ) -> anyhow::Result<()> { eprintln!("Creating branch '{}'...", options.name); - create_branch(connection, &options.name, options.from.as_ref().unwrap_or(&context.branch), options.empty, options.copy_data).await?; + let from = options.from.clone().unwrap_or(async { + anyhow::Ok(context.get_default_branch_name(connection).await?.to_string()) + }.await?); + + create_branch(connection, &options.name, &from, options.empty, options.copy_data).await?; Ok(()) } diff --git a/src/branch/drop.rs b/src/branch/drop.rs index f6d2854b3..f35bd6ae3 100644 --- a/src/branch/drop.rs +++ b/src/branch/drop.rs @@ -10,11 +10,13 @@ pub async fn main( context: &Context, connection: &mut Connection, ) -> anyhow::Result<()> { - if context.branch == options.branch { - anyhow::bail!( - "Dropping the currently active branch is not supported, please switch to a \ - different branch to drop this one with `edgedb branch switch `" - ); + if let Some(current_branch) = &context.branch { + if current_branch == &options.branch { + anyhow::bail!( + "Dropping the currently active branch is not supported, please switch to a \ + different branch to drop this one with `edgedb branch switch `" + ); + } } if !options.non_interactive { diff --git a/src/branch/list.rs b/src/branch/list.rs index b50203673..adf955ee2 100644 --- a/src/branch/list.rs +++ b/src/branch/list.rs @@ -16,10 +16,8 @@ pub async fn main( .await?; for branch in branches { - if context.branch == branch { + if context.branch.as_ref() == Some(&branch) { println!("{} - Current", branch.green()); - } else if context.project_config.edgedb.branch == branch { - println!("{} - Project default", branch.blue()); } else { println!("{}", branch); } diff --git a/src/branch/main.rs b/src/branch/main.rs index 0c56659dc..1ad9ea326 100644 --- a/src/branch/main.rs +++ b/src/branch/main.rs @@ -34,8 +34,8 @@ pub async fn branch_main(options: &Options, cmd: &BranchCommand) -> anyhow::Resu } async fn create_context() -> anyhow::Result { - let project_dir = get_project_dir(None, true).await?.expect("Missing project"); - Context::new(&project_dir).await + let project_dir = get_project_dir(None, true).await?; + Context::new(project_dir.as_ref()).await } pub async fn verify_server_can_use_branches(connection: &mut Connection) -> anyhow::Result<()> { diff --git a/src/branch/merge.rs b/src/branch/merge.rs index 3b5e54b21..f77a7e2de 100644 --- a/src/branch/merge.rs +++ b/src/branch/merge.rs @@ -7,7 +7,14 @@ use crate::migrations::merge::{apply_merge_migration_files, get_merge_migrations use crate::options::Options; pub async fn main(options: &Merge, context: &Context, source_connection: &mut Connection, cli_opts: &Options) -> anyhow::Result<()> { - if options.target_branch == context.branch { + if context.project_config.is_none() { + anyhow::bail!("Merge must be used within a project"); + } + + let current_branch = context.branch.as_ref().unwrap(); + let project_config = context.project_config.as_ref().unwrap(); + + if &options.target_branch == current_branch { anyhow::bail!("Cannot merge the current branch into its self"); } @@ -18,7 +25,7 @@ pub async fn main(options: &Merge, context: &Context, source_connection: &mut Co None => anyhow::bail!("The branch '{}' doesn't exist", options.target_branch) }; - let migration_context = migrations::Context::for_project(&context.project_config)?; + let migration_context = migrations::Context::for_project(project_config)?; let mut merge_migrations = get_merge_migrations(source_connection, &mut target_connection).await?; eprintln!("Merging {} migration(s) into '{}'...", merge_migrations.target_migrations.len(), source_connection.database()); diff --git a/src/branch/rebase.rs b/src/branch/rebase.rs index ad27ead87..401b1701c 100644 --- a/src/branch/rebase.rs +++ b/src/branch/rebase.rs @@ -10,7 +10,13 @@ use crate::{migrations, print}; use crate::branch::connections::get_connection_to_modify; pub async fn main(options: &Rebase, context: &Context, source_connection: &mut Connection, cli_opts: &Options) -> anyhow::Result<()> { - if options.target_branch == context.branch { + if context.project_config.is_none() { + anyhow::bail!("Rebase must be used within a project"); + } + + let current_branch = context.branch.as_ref().unwrap(); + + if &options.target_branch == current_branch { anyhow::bail!("Cannot rebase the current branch on top of itself"); } @@ -36,10 +42,11 @@ pub async fn main(options: &Rebase, context: &Context, source_connection: &mut C async fn rebase(branch: &String, source_connection: &mut Connection, target_connection: &mut Connection, context: &Context, cli_opts: &Options, apply_migrations: bool) -> anyhow::Result<()> { let mut migrations = get_diverging_migrations(source_connection, target_connection).await?; - + let current_branch = context.branch.as_ref().unwrap(); + let project_config = context.project_config.as_ref().unwrap(); migrations.print_status(); - let migration_context = migrations::Context::for_project(&context.project_config)?; + let migration_context = migrations::Context::for_project(project_config)?; do_rebase(&mut migrations, &migration_context).await?; if apply_migrations { @@ -47,10 +54,10 @@ async fn rebase(branch: &String, source_connection: &mut Connection, target_conn } // drop source branch - eprintln!("\nReplacing '{}' with rebased version...", &context.branch); - let status = target_connection.execute(&format!("drop branch {} force", edgeql_parser::helpers::quote_name(&context.branch)), &()).await?; + eprintln!("\nReplacing '{}' with rebased version...", current_branch); + let status = target_connection.execute(&format!("drop branch {} force", edgeql_parser::helpers::quote_name(current_branch)), &()).await?; print::completion(status); - rename_temp_to_source(branch, &context.branch, cli_opts, target_connection).await?; + rename_temp_to_source(branch, current_branch, cli_opts, target_connection).await?; eprintln!("Done!"); anyhow::Ok(()) diff --git a/src/branch/rename.rs b/src/branch/rename.rs index 51419f2ed..687227490 100644 --- a/src/branch/rename.rs +++ b/src/branch/rename.rs @@ -11,8 +11,8 @@ pub async fn main( connection: &mut Connection, cli_opts: &Options, ) -> anyhow::Result<()> { - if options.old_name == context.branch { - let mut modify_connection = get_connection_to_modify(&context.branch, &cli_opts, connection).await?; + if Some(&options.old_name) == context.branch.as_ref() || connection.database() == options.old_name { + let mut modify_connection = get_connection_to_modify(&options.old_name, &cli_opts, connection).await?; rename(&mut modify_connection.connection, &options).await?; modify_connection.clean().await?; context.update_branch(&options.new_name).await?; diff --git a/src/branch/switch.rs b/src/branch/switch.rs index 0450139a1..f1e7640f0 100644 --- a/src/branch/switch.rs +++ b/src/branch/switch.rs @@ -11,7 +11,13 @@ pub async fn main( context: &Context, connector: &mut Connector, ) -> anyhow::Result<()> { - if context.branch == options.branch { + if context.branch.is_none() { + anyhow::bail!("Cannot switch branches: No project found"); + } + + let current_branch = context.branch.as_ref().unwrap(); + + if current_branch == &options.branch { anyhow::bail!("Already on '{}'", options.branch); } @@ -29,7 +35,7 @@ pub async fn main( if !branches.contains(&options.branch) { if options.create { eprintln!("Creating '{}'...", &options.branch); - create_branch(&mut connection, &options.branch, options.from.as_ref().unwrap_or(&context.branch), options.empty, options.copy_data).await?; + create_branch(&mut connection, &options.branch, options.from.as_ref().unwrap_or(current_branch), options.empty, options.copy_data).await?; } else { anyhow::bail!("Branch '{}' doesn't exists", options.branch) } @@ -47,7 +53,7 @@ pub async fn main( eprintln!( "Switching from '{}' to '{}'", - context.branch, options.branch + current_branch, options.branch ); context.update_branch(&options.branch).await?; diff --git a/src/migrations/merge.rs b/src/migrations/merge.rs index 4ac701444..d39040622 100644 --- a/src/migrations/merge.rs +++ b/src/migrations/merge.rs @@ -6,8 +6,8 @@ use crate::migrations::{Context, migrate, migration}; use crate::migrations::create::{MigrationKey, MigrationToText, write_migration}; use crate::migrations::db_migration::{DBMigration, read_all}; use crate::migrations::migration::MigrationFile; -use crate::migrations::rebase::{fix_migration_ids}; -use crate::print; + + pub struct MergeMigrations { pub base_migrations: IndexMap, diff --git a/src/portable/config.rs b/src/portable/config.rs index 6002ae7a8..321aaa6d3 100644 --- a/src/portable/config.rs +++ b/src/portable/config.rs @@ -26,8 +26,6 @@ pub struct SrcConfig { pub struct SrcEdgedb { #[serde(default)] pub server_version: Option>, - #[serde(default)] - pub branch: Option>, #[serde(flatten)] pub extra: BTreeMap, } @@ -50,7 +48,6 @@ pub struct Config { #[derive(Debug)] pub struct Edgedb { pub server_version: Query, - pub branch: String, } #[derive(Debug)] @@ -92,11 +89,6 @@ pub fn read(path: &Path) -> anyhow::Result { channel: Channel::Stable, version: None, }), - branch: val - .edgedb - .branch - .map(|x| x.into_inner()) - .unwrap_or("main".to_string()), }, project: Project { schema_dir: val