Repository: edgedb/edgedb-cli
Pull request #1478 (2025-02-17 10:17:53)

Remove duplicated `branching` command group
For the repl backslash commands, we had a separate `Branching` cmd struct. This was implemented via being in the `Common` cmd (which contains all "common" commands that can be executed in repl backslash or as normal CLI command).

But this meant that we also had CLI command named `branching`:
```
# gel branching current

# gel branch current
```

???

So I've removed `Branching` struct in favor of `Common::Branch`, renamed `\branching` to `\branch` and cleaned-up a lot of code duplication and generalization.


Patch:
diff --git a/src/branch/mod.rs b/src/branch/mod.rs
index 10137a8..921ee8e 100644
--- a/src/branch/mod.rs
+++ b/src/branch/mod.rs
@@ -11,28 +11,20 @@ pub mod switch;
 pub mod wipe;
 
 use crate::branding::BRANDING;
-use crate::commands::parser::BranchingCmd;
 use crate::commands::Options;
 use crate::connect::{Connection, Connector};
 use crate::options::ConnectionOptions;
-use crate::portable;
 
-#[tokio::main(flavor = "current_thread")]
-pub async fn run(options: &Options, cmd: &Command) -> anyhow::Result<CommandResult> {
-    do_run(&cmd.subcommand, options, None, cmd.conn.instance.as_ref()).await
-}
-
-pub async fn do_run(
+pub async fn run(
     cmd: &Subcommand,
     options: &Options,
-    connection: Option<&mut Connection>,
-    instance_arg: Option<&portable::options::InstanceName>,
+    conn: Option<&mut Connection>,
 ) -> anyhow::Result<CommandResult> {
-    let context = context::Context::new(instance_arg).await?;
+    let context = context::Context::new(options.instance_name.as_ref()).await?;
 
     let mut connector: Connector = options.conn_params.clone();
 
-    // commands that don't need existing connection
+    // commands that don't need connection
     match &cmd {
         Subcommand::Switch(switch) => return switch::run(switch, &context, &mut connector).await,
         Subcommand::Wipe(wipe) => {
@@ -42,25 +34,25 @@ pub async fn do_run(
         _ => {}
     }
 
-    // ensure connected
-    let mut conn;
-    let conn_ref = if let Some(c) = connection {
-        c
+    // connect
+    let mut conn_cell;
+    let conn = if let Some(conn) = conn {
+        conn
     } else {
-        conn = Some(connector.connect().await?);
-        conn.as_mut().unwrap()
+        conn_cell = options.conn_params.connect().await?;
+        &mut conn_cell
     };
 
-    verify_server_can_use_branches(conn_ref).await?;
+    verify_server_can_use_branches(conn).await?;
 
     match cmd {
-        Subcommand::Current(cmd) => current::run(cmd, &context, conn_ref).await?,
-        Subcommand::Create(cmd) => create::run(cmd, &context, conn_ref).await?,
-        Subcommand::Drop(cmd) => drop::main(cmd, &context, conn_ref).await?,
-        Subcommand::List(cmd) => list::main(cmd, &context, conn_ref).await?,
-        Subcommand::Rename(cmd) => return rename::run(cmd, &context, conn_ref, options).await,
-        Subcommand::Rebase(cmd) => rebase::main(cmd, &context, conn_ref, options).await?,
-        Subcommand::Merge(cmd) => merge::main(cmd, &context, conn_ref, options).await?,
+        Subcommand::Current(cmd) => current::run(cmd, &context, conn).await?,
+        Subcommand::Create(cmd) => create::run(cmd, &context, conn).await?,
+        Subcommand::Drop(cmd) => drop::main(cmd, &context, conn).await?,
+        Subcommand::List(cmd) => list::main(cmd, &context, conn).await?,
+        Subcommand::Rename(cmd) => return rename::run(cmd, &context, conn, options).await,
+        Subcommand::Rebase(cmd) => rebase::main(cmd, &context, conn, options).await?,
+        Subcommand::Merge(cmd) => merge::main(cmd, &context, conn, options).await?,
 
         // handled earlier
         Subcommand::Switch(_) | Subcommand::Wipe(_) => unreachable!(),
@@ -107,16 +99,3 @@ pub async fn verify_server_can_use_branches(connection: &mut Connection) -> anyh
 
     Ok(())
 }
-
-impl From<BranchingCmd> for Subcommand {
-    fn from(cmd: BranchingCmd) -> Self {
-        match cmd {
-            BranchingCmd::Create(args) => Subcommand::Create(args),
-            BranchingCmd::Drop(args) => Subcommand::Drop(args),
-            BranchingCmd::Wipe(args) => Subcommand::Wipe(args),
-            BranchingCmd::List(args) => Subcommand::List(args),
-            BranchingCmd::Switch(args) => Subcommand::Switch(args),
-            BranchingCmd::Rename(args) => Subcommand::Rename(args),
-        }
-    }
-}
diff --git a/src/commands/backslash.rs b/src/commands/backslash.rs
index 67bc862..5bee26f 100644
--- a/src/commands/backslash.rs
+++ b/src/commands/backslash.rs
@@ -67,6 +67,7 @@ Editing
                             Defaults to vi (Notepad in Windows).
 
 Connection
+  \b, \branch ...           Branch commands
   \c, \connect [DBNAME]     Connect to database/branch DBNAME
 
 Settings
@@ -342,8 +343,8 @@ impl CommandCache {
         aliases.insert("quit", &["exit"]);
         aliases.insert("?", &["help"]);
         aliases.insert("h", &["help"]);
-        aliases.insert("branch", &["branching"]);
-        aliases.insert("b", &["branching"]);
+        aliases.insert("branch", &["branch"]);
+        aliases.insert("b", &["branch"]);
         let mut setting_cmd = None;
         let commands: BTreeMap<_, _> = clap
             .get_subcommands_mut()
@@ -577,11 +578,13 @@ pub async fn execute(
     use ExecuteResult::*;
     use Setting::*;
 
-    let options = Options {
+    let mut options = Options {
         command_line: false,
         styler: Some(Styler::new()),
         conn_params: prompt.conn_params.clone(),
+        instance_name: None,
     };
+    options.infer_instance_name()?;
     match cmd {
         Help => {
             print!("{HELP}");
@@ -589,8 +592,8 @@ pub async fn execute(
         }
         Common(ref cmd) => {
             prompt.soft_reconnect().await?;
-            let cli = prompt.connection.as_mut().expect("connection established");
-            let result = execute::common(cli, cmd, &options).await?;
+            let conn = prompt.connection.as_mut().expect("connection established");
+            let result = execute::common(Some(conn), cmd, &options).await?;
 
             if let Some(branch) = result.new_branch {
                 prompt.try_connect(&branch).await?;
diff --git a/src/commands/cli.rs b/src/commands/cli.rs
index eb2a6af..248457b 100644
--- a/src/commands/cli.rs
+++ b/src/commands/cli.rs
@@ -1,5 +1,6 @@
 use is_terminal::IsTerminal;
 
+use crate::cli;
 use crate::cli::directory_check;
 use crate::cloud::main::cloud_main;
 use crate::commands;
@@ -11,7 +12,6 @@ use crate::options::{Command, Options};
 use crate::portable;
 use crate::print::style::Styler;
 use crate::watch;
-use crate::{branch, cli};
 
 #[tokio::main(flavor = "current_thread")]
 async fn common_cmd(
@@ -19,8 +19,7 @@ async fn common_cmd(
     cmdopt: commands::Options,
     cmd: &Common,
 ) -> Result<(), anyhow::Error> {
-    let mut conn = cmdopt.conn_params.connect().await?;
-    commands::execute::common(&mut conn, cmd, &cmdopt).await?;
+    commands::execute::common(None, cmd, &cmdopt).await?;
     Ok(())
 }
 
@@ -74,11 +73,6 @@ pub fn main(options: &Options) -> Result<(), anyhow::Error> {
         Command::UI(c) => commands::show_ui(c, options),
         Command::Cloud(c) => cloud_main(c, &options.cloud_options),
         Command::Watch(c) => watch::run(options, c),
-        Command::Branch(c) => {
-            let opts = init_command_opts(options)?;
-            branch::run(&opts, c)?;
-            Ok(())
-        }
         Command::HashPassword(cmd) => {
             println!("{}", portable::password_hash(&cmd.password));
             Ok(())
@@ -94,6 +88,7 @@ fn init_command_opts(options: &Options) -> Result<commands::Options, anyhow::Err
         } else {
             None
         },
+        instance_name: options.conn_options.instance.clone(),
         conn_params: options.block_on_create_connector()?,
     })
 }
diff --git a/src/commands/execute.rs b/src/commands/execute.rs
index 4e5d2b1..441ade4 100644
--- a/src/commands/execute.rs
+++ b/src/commands/execute.rs
@@ -12,16 +12,35 @@ use crate::migrations::options::MigrationCmd;
 use crate::print;
 
 pub async fn common(
-    cli: &mut Connection,
+    conn: Option<&mut Connection>,
     cmd: &Common,
     options: &Options,
 ) -> Result<branch::CommandResult, anyhow::Error> {
     use Common::*;
+
+    // match commands that don't need connection
+    match cmd {
+        Branch(cmd) => {
+            return branch::run(&cmd.subcommand, options, conn).await;
+        }
+        _ => {}
+    }
+
+    // connect
+    let mut conn_cell;
+    let conn = if let Some(conn) = conn {
+        conn
+    } else {
+        conn_cell = options.conn_params.connect().await?;
+        &mut conn_cell
+    };
+
+    // match other
     match cmd {
         List(c) => match &c.subcommand {
             ListCmd::Aliases(c) => {
                 commands::list_aliases(
-                    cli,
+                    conn,
                     options,
                     &c.pattern,
                     c.system,
@@ -31,11 +50,11 @@ pub async fn common(
                 .await?;
             }
             ListCmd::Casts(c) => {
-                commands::list_casts(cli, options, &c.pattern, c.case_sensitive).await?;
+                commands::list_casts(conn, options, &c.pattern, c.case_sensitive).await?;
             }
             ListCmd::Indexes(c) => {
                 commands::list_indexes(
-                    cli,
+                    conn,
                     options,
                     &c.pattern,
                     c.system,
@@ -45,37 +64,37 @@ pub async fn common(
                 .await?;
             }
             ListCmd::Databases => {
-                commands::list_databases(cli, options).await?;
+                commands::list_databases(conn, options).await?;
             }
             ListCmd::Branches => {
-                commands::list_branches(cli, options).await?;
+                commands::list_branches(conn, options).await?;
             }
             ListCmd::Scalars(c) => {
-                commands::list_scalar_types(cli, options, &c.pattern, c.system, c.case_sensitive)
+                commands::list_scalar_types(conn, options, &c.pattern, c.system, c.case_sensitive)
                     .await?;
             }
             ListCmd::Types(c) => {
-                commands::list_object_types(cli, options, &c.pattern, c.system, c.case_sensitive)
+                commands::list_object_types(conn, options, &c.pattern, c.system, c.case_sensitive)
                     .await?;
             }
             ListCmd::Modules(c) => {
-                commands::list_modules(cli, options, &c.pattern, c.case_sensitive).await?;
+                commands::list_modules(conn, options, &c.pattern, c.case_sensitive).await?;
             }
             ListCmd::Roles(c) => {
-                commands::list_roles(cli, options, &c.pattern, c.case_sensitive).await?;
+                commands::list_roles(conn, options, &c.pattern, c.case_sensitive).await?;
             }
         },
         Analyze(c) => {
-            analyze::command(cli, c).await?;
+            analyze::command(conn, c).await?;
         }
-        Pgaddr => match cli.get_server_param::<PostgresAddress>() {
+        Pgaddr => match conn.get_server_param::<PostgresAddress>() {
             Some(addr) => {
                 // < 6.x
                 println!("{}", serde_json::to_string_pretty(addr)?);
             }
             None => {
                 // >= 6.x
-                match cli.get_server_param::<PostgresDsn>() {
+                match conn.get_server_param::<PostgresDsn>() {
                     Some(addr) => {
                         println!("{}", addr.0);
                     }
@@ -84,67 +103,64 @@ pub async fn common(
             }
         },
         Psql => {
-            commands::psql(cli, options).await?;
+            commands::psql(conn, options).await?;
         }
         Describe(c) => match &c.subcommand {
             DescribeCmd::Object(c) => {
-                commands::describe(cli, options, &c.name, c.verbose).await?;
+                commands::describe(conn, options, &c.name, c.verbose).await?;
             }
             DescribeCmd::Schema(_) => {
-                commands::describe_schema(cli, options).await?;
+                commands::describe_schema(conn, options).await?;
             }
         },
         Dump(c) => {
-            commands::dump(cli, options, c).await?;
+            commands::dump(conn, options, c).await?;
         }
         Restore(params) => {
-            commands::restore(cli, options, params).await?;
+            commands::restore(conn, options, params).await?;
         }
         Configure(c) => {
-            commands::configure(cli, options, c).await?;
+            commands::configure(conn, options, c).await?;
         }
         Database(c) => match &c.subcommand {
             DatabaseCmd::Create(c) => {
-                commands::database::create(cli, c, options).await?;
+                commands::database::create(conn, c, options).await?;
             }
             DatabaseCmd::Drop(d) => {
-                commands::database::drop(cli, d, options).await?;
+                commands::database::drop(conn, d, options).await?;
             }
             DatabaseCmd::Wipe(w) => {
-                commands::database::wipe(cli, w).await?;
+                commands::database::wipe(conn, w).await?;
             }
         },
-        Branching(cmd) => {
-            let cmd = branch::Subcommand::from(cmd.subcommand.clone());
-            return branch::do_run(&cmd, options, Some(cli), None).await;
-        }
+        Branch(_) => unreachable!(),
         Migrate(cmd) => {
-            migrations::apply::run(cmd, cli, options).await?;
+            migrations::apply::run(cmd, conn, options).await?;
         }
         Migration(m) => match &m.subcommand {
             MigrationCmd::Apply(cmd) => {
-                migrations::apply::run(cmd, cli, options).await?;
+                migrations::apply::run(cmd, conn, options).await?;
             }
             MigrationCmd::Create(cmd) => {
-                migrations::create::run(cmd, cli, options).await?;
+                migrations::create::run(cmd, conn, options).await?;
             }
             MigrationCmd::Status(params) => {
-                migrations::status(cli, options, params).await?;
+                migrations::status(conn, options, params).await?;
             }
             MigrationCmd::Log(params) => {
-                migrations::log(cli, options, params).await?;
+                migrations::log(conn, options, params).await?;
             }
             MigrationCmd::Edit(params) => {
-                migrations::edit(cli, options, params).await?;
+                migrations::edit(conn, options, params).await?;
             }
             MigrationCmd::UpgradeCheck(_) => {
                 anyhow::bail!("cannot be run in REPL mode");
             }
             MigrationCmd::Extract(params) => {
-                migrations::extract(cli, options, params).await?;
+                migrations::extract(conn, options, params).await?;
             }
             MigrationCmd::UpgradeFormat(params) => {
-                migrations::upgrade_format(cli, options, params).await?;
+                migrations::upgrade_format(conn, options, params).await?;
             }
         },
     }
diff --git a/src/commands/options.rs b/src/commands/options.rs
index 1123156..8663878 100644
--- a/src/commands/options.rs
+++ b/src/commands/options.rs
@@ -1,8 +1,24 @@
+use std::str::FromStr;
+
 use crate::connect::Connector;
+use crate::portable;
 use crate::print::style::Styler;
 
 pub struct Options {
     pub command_line: bool,
     pub styler: Option<Styler>,
     pub conn_params: Connector,
+    pub instance_name: Option<portable::options::InstanceName>,
+}
+
+impl Options {
+    pub fn infer_instance_name(&mut self) -> anyhow::Result<()> {
+        self.instance_name = self
+            .conn_params
+            .get()?
+            .instance_name()
+            .map(|x| portable::options::InstanceName::from_str(&x.to_string()))
+            .transpose()?;
+        Ok(())
+    }
 }
diff --git a/src/commands/parser.rs b/src/commands/parser.rs
index d89b57b..95bd6ad 100644
--- a/src/commands/parser.rs
+++ b/src/commands/parser.rs
@@ -1,11 +1,11 @@
 use std::path::PathBuf;
 
 use crate::branding::BRANDING_CLI_CMD;
-use crate::migrations;
 use crate::migrations::options::Migration;
 use crate::options::ConnectionOptions;
 use crate::portable::options::InstanceName;
 use crate::repl::{self, VectorLimit};
+use crate::{branch, migrations};
 
 use const_format::concatcp;
 
@@ -27,7 +27,8 @@ pub enum Common {
 
     /// Database commands
     Database(Database),
-    Branching(Branching),
+    /// Manage branches
+    Branch(branch::Command),
     /// Describe database schema or object
     Describe(Describe),
 
@@ -124,34 +125,6 @@ pub enum ListCmd {
     Types(ListTypes),
 }
 
-#[derive(clap::Args, Clone, Debug)]
-#[command(version = "help_expand", hide = true)]
-#[command(disable_version_flag = true)]
-pub struct Branching {
-    #[command(flatten)]
-    pub conn: ConnectionOptions,
-
-    #[command(subcommand)]
-    pub subcommand: BranchingCmd,
-}
-
-#[derive(clap::Subcommand, Clone, Debug)]
-pub enum BranchingCmd {
-    /// Create a new branch
-    Create(crate::branch::create::Command),
-    /// Delete a branch along with its data
-    Drop(crate::branch::drop::Command),
-    /// Delete a branch's data and reset its schema while preserving the branch
-    /// itself (its `cfg::DatabaseConfig`) and existing migration scripts
-    Wipe(crate::branch::wipe::Command),
-    /// List all branches.
-    List(crate::branch::list::Command),
-    /// Switches the current branch to a different one.
-    Switch(crate::branch::switch::Command),
-    /// Renames a branch.
-    Rename(crate::branch::rename::Command),
-}
-
 #[derive(clap::Args, Clone, Debug)]
 #[command(version = "help_expand")]
 #[command(disable_version_flag = true)]
diff --git a/src/options.rs b/src/options.rs
index b2f9914..fbc40f8 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -16,7 +16,6 @@ use edgedb_cli_derive::IntoArgs;
 
 use crate::{cli, watch};
 
-use crate::branch;
 use crate::branding::{BRANDING, BRANDING_CLI_CMD, BRANDING_CLOUD, MANIFEST_FILE_DISPLAY_NAME};
 use crate::cloud::options::CloudCommand;
 use crate::commands::parser::Common;
@@ -363,7 +362,7 @@ pub enum Command {
     Instance(portable::instance::Command),
     /// Manage local [`BRANDING`] installations
     Server(portable::server::Command),
-    /// Manage local extensions
+    /// Manage extensions of local instances
     Extension(portable::extension::Command),
     /// Generate shell completions
     #[command(name = "_gen_completions")]
@@ -381,8 +380,6 @@ pub enum Command {
     /// Start a long-running process that watches the project directory
     /// and runs scripts
     Watch(watch::Command),
-    /// Manage branches
-    Branch(branch::Command),
     /// Generate a `SCRAM-SHA-256` hash for a password.
     HashPassword(HashPasswordCommand),
 }
diff --git a/src/portable/extension.rs b/src/portable/extension.rs
index 18887fe..985ad8e 100644
--- a/src/portable/extension.rs
+++ b/src/portable/extension.rs
@@ -42,13 +42,13 @@ pub struct Command {
 
 #[derive(clap::Subcommand, Clone, Debug)]
 pub enum Subcommands {
-    /// List installed extensions for a local instance.
+    /// List installed extensions
     List(ExtensionList),
-    /// List available extensions for a local instance.
+    /// List available extensions
     ListAvailable(ExtensionListAvailable),
-    /// Install an extension for a local instance.
+    /// Install an extension
     Install(ExtensionInstall),
-    /// Uninstall an extension from a local instance.
+    /// Uninstall an extension
     Uninstall(ExtensionUninstall),
 }
 
@@ -77,7 +77,6 @@ pub struct ExtensionInstall {
     pub instance: Option<InstanceName>,
 
     /// Name of the extension to install
-    #[arg(short = 'E', long)]
     pub extension: String,
     /// Specify the channel override (stable, testing, or nightly)
     #[arg(long, hide = true)]
@@ -89,14 +88,13 @@ pub struct ExtensionInstall {
     #[arg(long, hide = true)]
     pub reinstall: bool,
 }
-/// Represents the options for uninstalling an extension from a local EdgeDB instance.
+
 #[derive(clap::Args, IntoArgs, Debug, Clone)]
 pub struct ExtensionUninstall {
     #[arg(from_global)]
     pub instance: Option<InstanceName>,
 
-    /// The name of the extension to uninstall.
-    #[arg(short = 'E', long)]
+    /// Name of the extension to uninstall
     pub extension: String,
 }
 
diff --git a/src/portable/instance/upgrade.rs b/src/portable/instance/upgrade.rs
index 3395a3b..8c6fd3b 100644
--- a/src/portable/instance/upgrade.rs
+++ b/src/portable/instance/upgrade.rs
@@ -488,6 +488,7 @@ pub async fn dump_instance(inst: &InstanceInfo, destination: &Path) -> anyhow::R
         command_line: true,
         styler: None,
         conn_params: Connector::new(Ok(config)),
+        instance_name: Some(InstanceName::Local(inst.name.clone())),
     };
     commands::dump_all(
         &mut cli,
@@ -578,6 +579,7 @@ async fn restore_instance(inst: &InstanceInfo, path: &Path) -> anyhow::Result<()
         command_line: true,
         styler: None,
         conn_params: Connector::new(Ok(cfg)),
+        instance_name: Some(InstanceName::Local(inst.name.clone())),
     };
     commands::restore_all(
         &mut cli,
diff --git a/src/portable/project/info.rs b/src/portable/project/info.rs
index 1f42dc3..b5b3cf2 100644
--- a/src/portable/project/info.rs
+++ b/src/portable/project/info.rs
@@ -5,18 +5,18 @@ use clap::ValueHint;
 use const_format::concatcp;
 use gel_tokio::get_stash_path;
 
+use crate::branding::BRANDING_CLI_CMD;
 use crate::branding::BRANDING_CLOUD;
-use crate::branding::{BRANDING_CLI_CMD, MANIFEST_FILE_DISPLAY_NAME};
 use crate::commands::ExitCode;
 use crate::portable::project;
 use crate::print::{self, msg, Highlight};
 use crate::table;
 
 pub fn run(options: &Command) -> anyhow::Result<()> {
-    let Some(project) = project::find_project(options.project_dir.as_deref())? else {
-        anyhow::bail!("`{MANIFEST_FILE_DISPLAY_NAME}` not found, unable to get project info.");
-    };
-    let stash_dir = get_stash_path(&project.root)?;
+    let ctx = project::ensure_ctx(options.project_dir.as_deref())?;
+    let schema_dir = ctx.resolve_schema_dir()?;
+
+    let stash_dir = get_stash_path(&ctx.location.root)?;
     if !stash_dir.exists() {
         msg!(
             "{} {} Run `{BRANDING_CLI_CMD} project init`.",
@@ -52,6 +52,13 @@ pub fn run(options: &Command) -> anyhow::Result<()> {
                     println!("{profile}");
                 }
             }
+            "schema-dir" => {
+                if options.json {
+                    println!("{}", serde_json::to_string(&schema_dir)?);
+                } else {
+                    println!("{}", schema_dir.display());
+                }
+            }
             _ => unreachable!(),
         }
     } else if options.json {
@@ -60,13 +67,19 @@ pub fn run(options: &Command) -> anyhow::Result<()> {
             serde_json::to_string_pretty(&JsonInfo {
                 instance_name: &instance_name,
                 cloud_profile: cloud_profile.as_deref(),
-                root: &project.root,
+                root: &ctx.location.root,
+                schema_dir: &schema_dir,
             })?
         );
     } else {
-        let root = project.root.display().to_string();
-        let mut rows: Vec<(&str, String)> =
-            vec![("Instance name", instance_name), ("Project root", root)];
+        let root = ctx.location.root.display().to_string();
+        let schema_dir = schema_dir.display().to_string();
+
+        let mut rows: Vec<(&str, String)> = vec![
+            ("Instance name", instance_name),
+            ("Project root", root),
+            ("Schema dir", schema_dir),
+        ];
         if let Some(profile) = cloud_profile.as_deref() {
             rows.push((concatcp!(BRANDING_CLOUD, " profile"), profile.to_string()));
         }
@@ -92,6 +105,7 @@ pub struct Command {
     #[arg(long, value_parser=[
         "instance-name",
         "cloud-profile",
+        "schema-dir",
     ])]
     /// Get a specific value:
     ///
@@ -106,4 +120,5 @@ struct JsonInfo<'a> {
     #[serde(skip_serializing_if = "Option::is_none")]
     cloud_profile: Option<&'a str>,
     root: &'a Path,
+    schema_dir: &'a Path,
 }
diff --git a/src/portable/project/init.rs b/src/portable/project/init.rs
index f404fc0..09bec73 100644
--- a/src/portable/project/init.rs
+++ b/src/portable/project/init.rs
@@ -1261,6 +1261,7 @@ async fn migrate_async(inst: &project::Handle<'_>, ask_for_running: bool) -> any
             command_line: true,
             styler: None,
             conn_params: Connector::new(inst.get_builder()?.build_env().await.map_err(Into::into)),
+            instance_name: Some(InstanceName::Local(inst.name.clone())),
         },
     )
     .await?;


Test patch:
diff --git a/tests/func/interactive.rs b/tests/func/interactive.rs
index 6250d14..a6fa4e7 100644
--- a/tests/func/interactive.rs
+++ b/tests/func/interactive.rs
@@ -48,7 +48,8 @@ fn create_report() {
 
     cmd.exp_string(&format!("{main}>")).unwrap();
     cmd.send_line("CREATE TYPE default::Type1;\n").unwrap();
-    cmd.exp_string("OK: CREATE").unwrap();
+    cmd.exp_string("OK: ").unwrap();
+    cmd.exp_string("CREATE").unwrap();
 }
 
 #[test]