# # # add_dir "tests/add,remove,cleanup_registered_workspaces" # # add_file "tests/add,remove,cleanup_registered_workspaces/__driver__.lua" # content [532ed9fe06a347389fe257f672d21b2129ca75b3] # # patch "cmd_db.cc" # from [fdb03428293ce0d536ee0528d53f96e546f741b0] # to [75ccf382e970ab65c43ae602d55052b7ed714ef2] # # patch "cmd_list.cc" # from [17438456f9456eeeac4965cdb0f91878daeec4fe] # to [8b509c4c27b611b7833e899a10da134c0cb9b899] # # patch "database.cc" # from [d08ea25a03b5bffcd1fccfd2e938fe67ae80b8f4] # to [8aed4b729bc627427af759ee91ebfe1ab88f6510] # # patch "database.hh" # from [4c795ebc65f3461b2efa6096a49a2e5711a5707f] # to [3f70833f9928db8ea4e9e944246318d21dcd341d] # # patch "monotone.texi" # from [28d0ecc3984cf339731dbf772a43d948c3d0a47f] # to [3c84beddd19020d3c84f2fddfb476d535ea18cac] # ============================================================ --- tests/add,remove,cleanup_registered_workspaces/__driver__.lua 532ed9fe06a347389fe257f672d21b2129ca75b3 +++ tests/add,remove,cleanup_registered_workspaces/__driver__.lua 532ed9fe06a347389fe257f672d21b2129ca75b3 @@ -0,0 +1,37 @@ + +mtn_setup() + +testname="add,remove,cleanup_registered_workspaces" + +check(mtn("ls", "vars"), 0, true, false) +check(not qgrep("database: known-workspaces", "stdout")) + +check(mtn("register-workspace"), 0, false, false) +check(mtn("ls", "vars"), 0, true, false) +check(qgrep("database: known-workspaces .+/"..testname, "stdout")) + +check(mtn("register-workspace", "foo"), 0, false, false) +check(mtn("ls", "vars"), 0, true, false) +check(qgrep("database: known-workspaces .+/"..testname, "stdout")) +check(qgrep(testname.."/foo", "stdout")) + +check(nodb_mtn("db", "init", "-d", "other.mtn"), 0, false, false) +check(nodb_mtn("setup", "-b", "bar", "-d", "other.mtn", "bar"), 0, false, false) +check(mtn("register-workspace", "bar"), 0, false, false) +check(mtn("ls", "vars"), 0, true, false) +check(qgrep(testname .. "/bar", "stdout")) + +check(mtn("register-workspace", "baz"), 0, false, false) + +check(mtn("unregister-workspace", "foo"), 0, false, false) +check(mtn("ls", "vars"), 0, true, false) +check(not qgrep(testname .. "/foo", "stdout")) + +check(mtn("cleanup-workspace-list"), 0, false, false) +check(mtn("ls", "vars"), 0, true, false) + +check(not qgrep(testname .. "/bar", "stdout")) +check(not qgrep(testname .. "/baz", "stdout")) + +check(qgrep("database: known-workspaces .+/"..testname, "stdout")) + ============================================================ --- cmd_db.cc fdb03428293ce0d536ee0528d53f96e546f741b0 +++ cmd_db.cc 75ccf382e970ab65c43ae602d55052b7ed714ef2 @@ -400,6 +400,95 @@ CMD(unset, "unset", "", CMD_REF(variable db.clear_var(k); } +CMD(register_workspace, "register-workspace", "", CMD_REF(variables), + N_("[WORKSPACE_PATH]"), + N_("Registers a new workspace for the current database"), + N_("This command adds WORKSPACE_PATH to the list of `known-workspaces'."), + options::opts::none) +{ + if (args.size() > 1) + throw usage(execid); + + E(args.size() == 1 || workspace::found, origin::user, + F("No workspace given")); + + system_path workspace; + if (args.size() == 1) + workspace = system_path(idx(args, 0)(), origin::user); + else + get_current_workspace(workspace); + + database db(app); + db.register_workspace(workspace); +} + +CMD(unregister_workspace, "unregister-workspace", "", CMD_REF(variables), + N_("[WORKSPACE_PATH]"), + N_("Unregisters an existing workspace for the current database"), + N_("This command removes WORKSPACE_PATH to the list of `known-workspaces'."), + options::opts::none) +{ + if (args.size() > 1) + throw usage(execid); + + E(args.size() == 1 || workspace::found, origin::user, + F("No workspace given")); + + system_path workspace; + if (args.size() == 1) + workspace = system_path(idx(args, 0)(), origin::user); + else + get_current_workspace(workspace); + + database db(app); + db.unregister_workspace(workspace); +} + +CMD(cleanup_workspace_list, "cleanup-workspace-list", "", CMD_REF(variables), "", + N_("Removes all invalid, registered workspace paths for the current database"), + "", + options::opts::none) +{ + if (args.size() != 0) + throw usage(execid); + + vector original_workspaces, valid_workspaces; + + database db(app); + db.get_registered_workspaces(original_workspaces); + + database_path_helper helper(app.lua); + + for (vector::const_iterator i = original_workspaces.begin(); + i != original_workspaces.end(); ++i) + { + system_path workspace_path(*i); + if (!directory_exists(workspace_path / bookkeeping_root_component)) + { + L(FL("ignoring missing workspace '%s'") % workspace_path); + continue; + } + + options workspace_opts; + workspace::get_options(workspace_path, workspace_opts); + + system_path workspace_db_path; + helper.get_database_path(workspace_opts, workspace_db_path); + + if (workspace_db_path != db.get_filename()) + { + L(FL("ignoring workspace '%s', expected database %s, " + "but has %s configured in _MTN/options") + % workspace_path % db.get_filename() % workspace_db_path); + continue; + } + + valid_workspaces.push_back(workspace_path); + } + + db.set_registered_workspaces(valid_workspaces); +} + CMD(complete, "complete", "", CMD_REF(informative), N_("(revision|file|key) PARTIAL-ID"), N_("Completes a partial identifier"), ============================================================ --- cmd_list.cc 17438456f9456eeeac4965cdb0f91878daeec4fe +++ cmd_list.cc 8b509c4c27b611b7833e899a10da134c0cb9b899 @@ -679,6 +679,11 @@ CMD(databases, "databases", "dbs", CMD_R k != workspaces.end(); ++k) { system_path workspace_path(*k); + if (!directory_exists(workspace_path / bookkeeping_root_component)) + { + L(FL("ignoring missing workspace '%s'") % workspace_path); + continue; + } options workspace_opts; workspace::get_options(workspace_path, workspace_opts); ============================================================ --- database.cc d08ea25a03b5bffcd1fccfd2e938fe67ae80b8f4 +++ database.cc 8aed4b729bc627427af759ee91ebfe1ab88f6510 @@ -4330,7 +4330,7 @@ void )) void -database::register_workspace(system_path const & path) +database::register_workspace(system_path const & workspace) { var_value val; if (var_exists(KNOWN_WORKSPACES_KEY)) @@ -4342,9 +4342,9 @@ database::register_workspace(system_path vector::iterator pos = find(workspaces.begin(), workspaces.end(), - path.as_internal()); + workspace.as_internal()); if (pos == workspaces.end()) - workspaces.push_back(path.as_internal()); + workspaces.push_back(workspace.as_internal()); string ws; join_lines(workspaces, ws); @@ -4353,7 +4353,7 @@ void } void -database::unregister_workspace(system_path const & path) +database::unregister_workspace(system_path const & workspace) { if (var_exists(KNOWN_WORKSPACES_KEY)) { @@ -4366,7 +4366,7 @@ database::unregister_workspace(system_pa vector::iterator pos = find(workspaces.begin(), workspaces.end(), - path.as_internal()); + workspace.as_internal()); if (pos != workspaces.end()) workspaces.erase(pos); @@ -4378,30 +4378,40 @@ void } void -database::get_registered_workspaces(vector & paths) +database::get_registered_workspaces(vector & workspaces) { if (var_exists(KNOWN_WORKSPACES_KEY)) { var_value val; get_var(KNOWN_WORKSPACES_KEY, val); - vector workspaces; - split_into_lines(val(), workspaces); + vector paths; + split_into_lines(val(), paths); - for (vector::const_iterator i = workspaces.begin(); - i != workspaces.end(); ++i) + for (vector::const_iterator i = paths.begin(); + i != paths.end(); ++i) { system_path workspace_path(*i, origin::database); - if (!directory_exists(workspace_path / bookkeeping_root_component)) - { - L(FL("ignoring missing workspace '%s'") % workspace_path); - continue; - } - paths.push_back(workspace_path); + workspaces.push_back(workspace_path); } } } +void +database::set_registered_workspaces(vector const & workspaces) +{ + vector paths; + for (vector::const_iterator i = workspaces.begin(); + i != workspaces.end(); ++i) + { + paths.push_back((*i).as_internal()); + } + + string ws; + join_lines(paths, ws); + set_var(KNOWN_WORKSPACES_KEY, var_value(ws, origin::internal)); +} + #undef KNOWN_WORKSPACES_KEY // branches ============================================================ --- database.hh 4c795ebc65f3461b2efa6096a49a2e5711a5707f +++ database.hh 3f70833f9928db8ea4e9e944246318d21dcd341d @@ -20,6 +20,8 @@ #include "cert.hh" #include "options.hh" +using std::vector; + class app_state; class lua_hooks; struct date_t; @@ -375,12 +377,14 @@ public: void clear_var(var_key const & key); - void register_workspace(system_path const & path); + void register_workspace(system_path const & workspace); - void unregister_workspace(system_path const & path); + void unregister_workspace(system_path const & workspace); - void get_registered_workspaces(std::vector & paths); + void get_registered_workspaces(vector & workspaces); + void set_registered_workspaces(vector const & workspaces); + // // --== Completion ==-- // ============================================================ --- monotone.texi 28d0ecc3984cf339731dbf772a43d948c3d0a47f +++ monotone.texi 3c84beddd19020d3c84f2fddfb476d535ea18cac @@ -1186,7 +1186,7 @@ @section Creating a Database Beth decides to use monotone's built-in database management functionality. monotone then expects to find managed database files in a couple of predefined -places (like f.e. @file{~/.monotone/databases} on Unix and +places (like f.e. @file{~/.monotone/databases} on Unix and @file{%APPDDATA%\monotone\databases} on Windows, this is customizable) and acts upon those by knowing only their file or basename from anywhere. @@ -6342,6 +6342,30 @@ @section Database Deletes any value associated with @var{name} in @var{domain}. See @ref{Vars} for more information. address@hidden mtn register-workspace address@hidden + +Registers the given workspace from the current database, so that it +will show up in the output of @command{list databases} (the database +has to be in a managed location for this to work). + +If no @var{workspace_path} is given, this command defaults to the +current workspace. + address@hidden mtn unregister-workspace address@hidden + +Unregisters the given workspace from the current database, so that it +will no longer show up in the output of @command{list databases}. + +If no @var{workspace_path} is given, this command defaults to the +current workspace. + address@hidden mtn cleanup-workspace-list + +Removes all invalid workspaces from the list of registered workspaces +of the current database. A workspace is considered invalid if its path +does either not contain an _MTN directory anymore or if the configured +database for this workspace is a different one. + @item mtn db init address@hidden This command initializes a new monotone database at @var{dbfile}. @@ -10741,7 +10765,7 @@ @subsection User Defaults paths for valid monotone databases and outputs details on each one. The default implementation returns a table with a single entry, address@hidden/.monotone/databases} on Unix and address@hidden/.monotone/databases} on Unix and @file{%APPDATA%\monotone\databases} on Windows. @item get_default_database_alias ()