monotone-commits-diffs
[Top][All Lists]
Advanced

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

[Monotone-commits-diffs] net.venge.monotone: 5bfdedba0571477ec41755bc60d


From: code
Subject: [Monotone-commits-diffs] net.venge.monotone: 5bfdedba0571477ec41755bc60db55402bb5d5f0
Date: Sat, 28 May 2011 03:13:57 +0200 (CEST)

revision:            5bfdedba0571477ec41755bc60db55402bb5d5f0
date:                2011-05-28T01:11:21
author:              address@hidden
branch:              net.venge.monotone
changelog:
* src/cmd_ws_commit.cc (get_attributes): allow the querying of
  individual attributes of a file from a stored roster
* test/func/automate_get_attributes/__driver__.lua: expand the
  test case for this use case
* doc/monotone.texi: document the change
* NEWS: note the change here as well

manifest:
format_version "1"

new_manifest [9434f35db4b78d7a9b4d7f0de0c715aad59f5b46]

old_revision [a570769b62c58e0fb571310bc231419291a55391]

patch "NEWS"
 from [710b0adc68789d90faf583d85b094f93295ac19e]
   to [8cae90559bb06b2bc77c211397218299c1660d13]

patch "doc/monotone.texi"
 from [0e40017dfe8ba652e6af4585a2ac176c8bd12dcc]
   to [eab1a08234b86089a4e1105a180425088dfc3992]

patch "src/cmd_ws_commit.cc"
 from [d9dbacb820c6d070c4952ee2b0f143e61e85631e]
   to [61d63e20d1beb1f1a02b194c4360cbd57c3c68cc]

patch "test/func/automate_get_attributes/__driver__.lua"
 from [9b89d87cc43aa1c5ba5569d495ebfa812d81305f]
   to [cd69b24a950d6c100143f4267cb9f22f3877ad75]
============================================================
--- NEWS	710b0adc68789d90faf583d85b094f93295ac19e
+++ NEWS	8cae90559bb06b2bc77c211397218299c1660d13
@@ -2,6 +2,21 @@ XXX XXX XX XX:XX:XX UTC 201X
 
         1.1 release.
 
+        Changes
+
+        New features
+
+        - 'automate atttributes' now also works without a workspace
+          and returns the attributes for a specific file from the
+          revision's manifest
+
+        Bugs fixed
+
+        Internal
+
+        Other
+
+
 Sat Mar 26 10:53:47 UTC 2011
 
         1.0 release.
============================================================
--- doc/monotone.texi	0e40017dfe8ba652e6af4585a2ac176c8bd12dcc
+++ doc/monotone.texi	eab1a08234b86089a4e1105a180425088dfc3992
@@ -7599,6 +7599,8 @@ @section Automation
 
 @itemize
 @item
+13.1 -- add the possibility to specify a revision for the operation
address@hidden
 11.0 -- removed the @command{format_version} stanza
 @item
 5.0 -- renamed from @command{attributes} to @command{get_attributes}
@@ -7610,6 +7612,8 @@ @section Automation
 
 Prints all attributes of the given file in the current workspace, and
 the attribute states.
+If a revision is given, then the attributes of the given file at that
+point in time are returned. No workspace is needed in this case.
 
 @item Sample output:
 
@@ -7637,13 +7641,13 @@ @section Automation
 
 @itemize
 @item
-'added': the attribute has just been added to the file
address@hidden: the attribute has just been added to the file
 @item
-'dropped': the attribute has just been dropped from the file
address@hidden: the attribute has just been dropped from the file
 @item
-'unchanged': the attribute has not been changed since the last revision
address@hidden: the attribute has not been changed since the last revision
 @item
-'changed': the attribute has been changed since the last revision
address@hidden: the attribute has been changed since the last revision
 @end itemize
 
 The status 'changed' can come up if an attribute foo has been dropped and
@@ -7657,6 +7661,9 @@ @section Automation
 set value of the dropped attribute for convenience (obviously this is no longer
 recorded in the current workspace).
 
+If attributes from a specific revision are queried, then all the file's
+attribute states are set to @code{unchanged}.
+
 The complete format:
 
 @verbatim
============================================================
--- src/cmd_ws_commit.cc	d9dbacb820c6d070c4952ee2b0f143e61e85631e
+++ src/cmd_ws_commit.cc	61d63e20d1beb1f1a02b194c4360cbd57c3c68cc
@@ -1319,49 +1319,65 @@ CMD(attr_set, "set", "", CMD_REF(attr), 
 //   1: file / directory name
 // Added in: 1.0
 // Renamed from attributes to get_attributes in: 5.0
+// Changed to also work without a workspace in: 13.1
 // Purpose: Prints all attributes for the specified path
 // Output format: basic_io formatted output, each attribute has its own stanza:
 //
-// 'format_version'
-//         used in case this format ever needs to change.
-//         format: ('format_version', the string "1" currently)
-//         occurs: exactly once
 // 'attr'
 //         represents an attribute entry
 //         format: ('attr', name, value), ('state', [unchanged|changed|added|dropped])
 //         occurs: zero or more times
 //
-// Error conditions: If the path has no attributes, prints only the
-//                   format version, if the file is unknown, escalates
+// Error conditions: If the path has no attributes, prints nothing,
+//                   if the file is unknown, escalates
 CMD_AUTOMATE(get_attributes, N_("PATH"),
              N_("Prints all attributes for the specified path"),
-             "",
-             options::opts::none)
+             N_("If an explicit revision is given, the file's attributes "
+                "at this specific revision are returned."),
+             options::opts::revision)
 {
-  E(!args.empty(), origin::user,
+  E(args.size() == 1, origin::user,
     F("wrong argument count"));
 
+  file_path path = file_path_external(idx(args,0));
+
   database db(app);
-  workspace work(app);
+  roster_t current, base;
 
-  // retrieve the path
-  file_path path = file_path_external(idx(args,0));
+  bool from_database;
+  if (app.opts.revision.size() == 0)
+    {
+      from_database = false;
+      workspace work(app);
 
-  roster_t base, current;
-  parent_map parents;
-  temp_node_id_source nis;
+      parent_map parents;
+      temp_node_id_source nis;
 
-  // get the base and the current roster of this workspace
-  work.get_current_roster_shape(db, nis, current);
-  work.get_parent_rosters(db, parents);
-  E(parents.size() == 1, origin::user,
-    F("this command can only be used in a single-parent workspace"));
-  base = parent_roster(parents.begin());
+      // get the base and the current roster of this workspace
+      work.get_current_roster_shape(db, nis, current);
+      work.get_parent_rosters(db, parents);
+      E(parents.size() == 1, origin::user,
+        F("this command can only be used in a single-parent workspace"));
+      base = parent_roster(parents.begin());
 
-  E(current.has_node(path), origin::user,
-    F("unknown path '%s'") % path);
+      E(current.has_node(path), origin::user,
+        F("unknown path '%s'") % path);
+    }
+  else if (app.opts.revision.size() == 1)
+    {
+      from_database = true;
+      revision_id rid;
 
-  // create the printer
+      project_t project(db);
+      complete(app.opts, app.lua, project, idx(app.opts.revision, 0)(), rid);
+      db.get_roster(rid, current);
+
+      E(current.has_node(path), origin::user,
+        F("unknown path '%s' in %s") % path % rid);
+    }
+  else
+    E(false, origin::user, F("none or only one revision must be given"));
+
   basic_io::printer pr;
 
   // the current node holds all current attributes (unchanged and new ones)
@@ -1370,62 +1386,71 @@ CMD_AUTOMATE(get_attributes, N_("PATH"),
        i != n->attrs.end(); ++i)
   {
     std::string value(i->second.second());
-    std::string state;
+    std::string state = "unchanged";
 
-    // if if the first value of the value pair is false this marks a
-    // dropped attribute
-    if (!i->second.first)
+    if (!from_database)
       {
-        // if the attribute is dropped, we should have a base roster
-        // with that node. we need to check that for the attribute as well
-        // because if it is dropped there as well it was already deleted
-        // in any previous revision
-        I(base.has_node(path));
+        // if if the first value of the value pair is false this marks a
+        // dropped attribute
+        if (!i->second.first)
+          {
+            // if the attribute is dropped, we should have a base roster
+            // with that node. we need to check that for the attribute as well
+            // because if it is dropped there as well it was already deleted
+            // in any previous revision
+            I(base.has_node(path));
 
-        const_node_t prev_node = base.get_node(path);
+            const_node_t prev_node = base.get_node(path);
 
-        // find the attribute in there
-        attr_map_t::const_iterator j = prev_node->attrs.find(i->first);
-        I(j != prev_node->attrs.end());
+            // find the attribute in there
+            attr_map_t::const_iterator j = prev_node->attrs.find(i->first);
+            I(j != prev_node->attrs.end());
 
-        // was this dropped before? then ignore it
-        if (!j->second.first) { continue; }
+            // was this dropped before? then ignore it
+            if (!j->second.first) { continue; }
 
-        state = "dropped";
-        // output the previous (dropped) value later
-        value = j->second.second();
-      }
-    // this marks either a new or an existing attribute
-    else
-      {
-        if (base.has_node(path))
+            state = "dropped";
+            // output the previous (dropped) value later
+            value = j->second.second();
+          }
+        // this marks either a new or an existing attribute
+        else
           {
-            const_node_t prev_node = base.get_node(path);
-            attr_map_t::const_iterator j =
-              prev_node->attrs.find(i->first);
+            if (base.has_node(path))
+              {
+                const_node_t prev_node = base.get_node(path);
+                attr_map_t::const_iterator j =
+                  prev_node->attrs.find(i->first);
 
-            // the attribute is new if it either hasn't been found
-            // in the previous roster or has been deleted there
-            if (j == prev_node->attrs.end() || !j->second.first)
-              {
-                state = "added";
+                // the attribute is new if it either hasn't been found
+                // in the previous roster or has been deleted there
+                if (j == prev_node->attrs.end() || !j->second.first)
+                  {
+                    state = "added";
+                  }
+                // check if the attribute's value has been changed
+                else if (i->second.second() != j->second.second())
+                  {
+                    state = "changed";
+                  }
+                else
+                  {
+                    state = "unchanged";
+                  }
               }
-            // check if the attribute's value has been changed
-            else if (i->second.second() != j->second.second())
-              {
-                state = "changed";
-              }
+            // its added since the whole node has been just added
             else
               {
-                state = "unchanged";
+                state = "added";
               }
           }
-        // its added since the whole node has been just added
-        else
-          {
-            state = "added";
-          }
       }
+    else
+      {
+        // skip previously dropped attributes in database mode
+        if (!i->second.first)
+          continue;
+      }
 
     basic_io::stanza st;
     st.push_str_triple(basic_io::syms::attr, i->first(), value);
============================================================
--- test/func/automate_get_attributes/__driver__.lua	9b89d87cc43aa1c5ba5569d495ebfa812d81305f
+++ test/func/automate_get_attributes/__driver__.lua	cd69b24a950d6c100143f4267cb9f22f3877ad75
@@ -97,3 +97,35 @@ end
     end
 end
 
+-- check that we can query arbitrary attributes from earlier revisions
+check(mtn("automate", "get_attributes", "-r", "0123456789012345678901234567890123456789", "bla"), 1, false, true)
+check(qgrep("no revision 0123456789012345678901234567890123456789 found in database", "stderr"))
+
+rev = base_revision()
+check(mtn("automate", "get_attributes", "foo", "-r", rev), 1, false, true)
+check(qgrep("unknown path 'foo' in " .. rev, "stderr"))
+
+check(mtn("automate", "get_attributes", "testfile", "-r", rev), 0, true, false)
+
+parsed = parse_basic_io(readfile("stdout"))
+check(table.getn(parsed) == 6)
+
+lastkey = ""
+checked = {}
+for _,l in pairs(parsed) do
+    if l.name == "attr" then
+        lastkey = l.values[1]
+        val = l.values[2]
+        if lastkey == "key1" then check(val == "persists")
+        elseif lastkey == "key3" then check(val == "has_been_changed")
+        elseif lastkey == "key4" then check(val == "has_been_added")
+        else check(false) end
+    end
+    if l.name == "state" then
+        check(l.values[1] == "unchanged")
+        checked[lastkey] = true
+    end
+end
+
+check(checked["key1"] and checked["key3"] and checked["key4"])
+

reply via email to

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