monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-devel] Patch: RFC: adding MT/options


From: Tom Tromey
Subject: [Monotone-devel] Patch: RFC: adding MT/options
Date: 13 Sep 2003 12:55:14 -0600

Here's the first working version of my patch to add an MT/options
file.

This file is used to store some per-working-copy information.  The
idea is that, in general, you shouldn't need to use environment
variables, but instead you should be able to specify the branch and
database once at checkout.

This is similar to what cvs does.  I think the cvs lesson is
informative here -- cvs doesn't store CVS_RSH per-working-copy, which
is an endless irritation if you've ever had to use both an ssh-only
server and a kerberos-only server.

I changed some of the sub-commands to explicitly write out the options
file.  This seemed like the best approach; I tried it generically, but
having MT/options be created in response to "monotone heads" or
"monotone --help" is weird.

I'd like some feedback on this before checking it in.  This is more
invasive than my other patches have been.

I haven't tried the test suite with this patch.  I definitely won't
commit until there are no regressions; I'm assuming I'll have to make
a few test suite changes as well.

I suppose I could check this in on a new branch, since that is cheap,
but I didn't want to be on the spot for picking a new name...

Tom


--- ChangeLog
+++ ChangeLog
@@ -1,5 +1,24 @@
 2003-09-13  Tom Tromey  <address@hidden>
 
+       * app_state.hh (app_state): New field options.  Declare new
+       methods.  Include work.hh.
+       * work.cc (work_file_name): New constant.
+       (add_to_options_map): New structure.
+       (get_options_path): New function.
+       (read_options_map, write_options_map): Likewise.
+       * work.hh (options_map): New type.
+       (get_options_path, read_options_map, write_options_map): Declare.
+       * commands.cc (add, drop, commit, update, revert, checkout,
+       merge): Write options file.
+       * app_state.cc (database_key, branch_key): New constants.
+       (app_state::app_state): Read options file.
+       (app_state::set_database): New method.
+       (app_state::set_branch): Likewise.
+       (app_state::write_options): Likewise.
+       Include work.hh.
+       * monotone.cc (cpp_main): Don't set initial database name on
+       app.  Use new settor methods.
+
        * tests/t_nntp.at: If we can't find tcpserver or snntpd, skip the
        test.
        * tests/t_http.at: If we can't find boa or depot.cgi, skip the
--- monotone.cc
+++ monotone.cc
@@ -102,8 +102,6 @@
   bool stdhooks = true, rcfile = true;
   char * envstr;
 
-  app.db.set_filename("monotone.db");
-
   poptSetOtherOptionHelp(ctx(), "[OPTION...] command [ARGS...]\n");
 
   // initialize entries from $ENV
@@ -112,10 +110,10 @@
     app.signing_key = string(envstr);
 
   if ((envstr = getenv("MT_DB")) != NULL)
-    app.db.set_filename(string(envstr));
+    app.set_database(string(envstr));
 
   if ((envstr = getenv("MT_BRANCH")) != NULL)
-    app.branch_name = string(envstr);
+    app.set_branch(string(envstr));
 
 
   // read command options
@@ -149,7 +149,7 @@
              break;
 
            case OPT_DB_NAME:
-             app.db.set_filename(argstr);
+             app.set_database(argstr);
              break;
 
            case OPT_KEY_NAME:
@@ -157,7 +157,7 @@
              break;
 
            case OPT_BRANCH_NAME:
-             app.branch_name = argstr;
+             app.set_branch(string(argstr));
              break;
 
            case OPT_VERSION:
@@ -236,7 +236,7 @@
       clean_shutdown = true;
       throw;
     }
-  
+
   clean_shutdown = true;
   return ret;
 }
--- app_state.cc
+++ app_state.cc
@@ -1,8 +1,9 @@
 #include <termios.h>
 #include <iostream>
 
 #include "app_state.hh"
 #include "database.hh"
+#include "work.hh"
 
 // copyright (C) 2002, 2003 graydon hoare <address@hidden>
 // all rights reserved.
@@ -11,11 +12,51 @@
 
 using namespace std;
 
+static string const database_key("database");
+static string const branch_key("branch");
+
 app_state::app_state() 
   : branch_name(""), db("monotone.db")
 {
+  options[database_key] = string("monotone.db");
+  options[branch_key] = string("");
+  local_path o_path;
+  get_options_path(o_path);
+  if (file_exists(o_path))
+    {
+      data dat;
+      read_data(o_path, dat);
+      read_options_map(dat, options);
+
+      string dbname = options[database_key];
+      if (dbname != "monotone.db")
+       db.set_filename(dbname);
+      branch_name = options[branch_key];
+    }
 }
 
 app_state::~app_state()
 {
 }
+
+void app_state::set_database(string filename)
+{
+  options[database_key] = filename;
+  db.set_filename(filename);
+}
+
+void app_state::set_branch(string branch)
+{
+  options[branch_key] = branch;
+  branch_name = string(branch);
+}
+
+void app_state::write_options()
+{
+  local_path o_path;
+  get_options_path(o_path);
+
+  data dat;
+  write_options_map(dat, options);
+  write_data(o_path, dat);
+}
--- commands.cc
+++ commands.cc
@@ -844,6 +844,8 @@
   // small race here
   if (rewrite_work)
     put_work_set(work);
+
+  app.write_options();
 }
 
 CMD(drop, "working copy", "<pathname> [...]", "drop files from working copy")
@@ -867,6 +869,8 @@
   // small race here
   if (rewrite_work)
     put_work_set(work);
+
+  app.write_options();
 }
 
 CMD(commit, "working copy", "[log message]", "commit working copy to database")
@@ -908,7 +910,7 @@
     
   L("committing %s to branch %s\n", 
     new_id.inner()().c_str(), branchname().c_str());
-  app.branch_name = branchname();
+  app.set_branch(branchname());
 
   manifests_to_patch_set(m_old, m_new, app, ps);
 
@@ -1047,6 +1047,8 @@
   remove_work_set();
   put_manifest_map(m_new);
   P("committed %s\n", ps.m_new.inner()().c_str());
+
+  app.write_options();
 }
 
 CMD(update, "working copy", "[sort keys...]", "update working copy, relative 
to sorting keys")
@@ -1146,6 +1148,8 @@
   // is the basis of the working copy, not the working copy itself.
   put_manifest_map(m_chosen);
   P("updated to base version %s\n", m_chosen_id.inner()().c_str());
+
+  app.write_options();
 }
 
 CMD(revert, "working copy", "[<file>]...", "revert file(s) or entire working 
copy")
@@ -1228,6 +1230,8 @@
       // race
       put_work_set(work);
     }
+
+  app.write_options();
 }
 
 
@@ -1323,6 +1325,7 @@
     }
   remove_work_set();
   guard.commit();
+  app.write_options();
 }
 
 ALIAS(co, checkout, "tree", "<manifest-id>",
@@ -1420,7 +1421,9 @@
            merged.inner()().c_str());
          left = merged;
        }
-    }  
+    }
+
+  app.write_options();
 }
 
 
--- work.hh
+++ work.hh
@@ -71,4 +71,13 @@
                    manifest_map & man,
                    bool & rewrite_work);
 
+typedef map<string, string> options_map;
+
+void get_options_path(local_path & o_path);
+
+void read_options_map(data const & dat, options_map & options);
+
+void write_options_map(data & dat,
+                      options_map const & options);
+
 #endif // __WORK_HH__
--- work.cc
+++ work.cc
@@ -214,3 +214,41 @@
        i != work.adds.end(); ++i)
     paths.insert(*i);
 }
+
+// read options file
+
+string const options_file_name("options");
+
+struct add_to_options_map
+{
+  options_map & options;
+  explicit add_to_options_map(options_map & m): options(m) {}
+  bool operator()(match_results<std::string::const_iterator, 
regex::alloc_type> const & res) 
+  {
+    std::string key(res[1].first, res[1].second);
+    std::string value(res[2].first, res[2].second);
+    options[key] = value;
+    return true;
+  }
+};
+
+void get_options_path(local_path & o_path)
+{
+  o_path = (fs::path(book_keeping_dir) / fs::path(options_file_name)).string();
+  L("options path is %s\n", o_path().c_str());
+}
+
+void read_options_map(data const & dat, options_map & options)
+{
+  regex expr("^([^[:space:]]+)[[:space:]]+([^[:space:]]+)");
+  regex_grep(add_to_options_map(options), dat(), expr, match_not_dot_newline);
+}
+
+void write_options_map(data & dat, options_map const & options)
+{
+  ostringstream tmp;
+  for (options_map::const_iterator i = options.begin();
+       i != options.end(); ++i)
+    tmp << i->first << " " << i->second << endl;
+  dat = tmp.str();
+}
--- app_state.hh
+++ app_state.hh
@@ -11,6 +11,7 @@
 
 #include "database.hh"
 #include "lua.hh"
+#include "work.hh"
 
 // this class is supposed to hold all (or.. well, most) of the state of the
 // application, barring some unfortunate static objects like the debugging /
@@ -25,6 +26,12 @@
   string branch_name;
   database db;
   lua_hooks lua;
+  options_map options;
+
+  void set_branch(string name);
+  void set_database(string filename);
+  void write_options();
+
   explicit app_state();
   ~app_state();
 private:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]