Rev 2: Work out some containing functions, etc. in http://bazaar.launchpad.net/~jameinel/my_nick

John Arbash Meinel john at arbash-meinel.com
Thu May 20 07:47:32 BST 2010


At http://bazaar.launchpad.net/~jameinel/my_nick

------------------------------------------------------------
revno: 2
revision-id: john at arbash-meinel.com-20100520064722-chcm3m2m63qg9zh3
parent: john at arbash-meinel.com-20100520031122-ci7ob9mvdziz1z94
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: my_nick
timestamp: Thu 2010-05-20 01:47:22 -0500
message:
  Work out some containing functions, etc.
  
  This seems to work for checkouts as well as regular bzrdir, and such.
  It doesn't yet handle all the particularls of url encoding, though.
-------------- next part --------------
=== modified file 'my_nick.cpp'
--- a/my_nick.cpp	2010-05-20 03:11:22 +0000
+++ b/my_nick.cpp	2010-05-20 06:47:22 +0000
@@ -3,10 +3,178 @@
  */
 
 #include <iostream>
-
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+
+string
+dirname(string const path)
+{
+    size_t last_slash = path.rfind('/');
+    if (last_slash == path.size() - 1) {
+        last_slash = path.rfind('/', last_slash-1);
+    }
+    if (last_slash == string::npos) {
+        return string("");
+    }
+    string newpath = path.substr(0, last_slash);
+    // cerr << "\"" << path << "\"" << " => \"" << newpath << "\"\n";
+    return newpath;
+}
+
+bool
+has_file(string const path)
+{
+    fstream format_file(path.c_str(), ios_base::in);
+    if (format_file.fail()) {
+        return false;
+    }
+    format_file.close();
+    return true;
+}
+
+bool
+is_bzrdir(string path)
+{
+    return has_file(path + "/.bzr/branch-format");
+}
+
+bool
+is_branch(string path)
+{
+    return has_file(path + "/.bzr/branch/format");
+}
+
+bool
+is_repository(string path)
+{
+    return has_file(path + "/.bzr/repository/format");
+}
+
+string
+is_checkout_of(string const path)
+{
+    string location_path(path + "/.bzr/branch/location");
+    int length;
+    // If path is a checkout, give the URL it is a checkout of
+    ifstream location_file(location_path.c_str(), ios::binary);
+    if (location_file.fail()) {
+        return string("");
+    }
+    location_file.seekg(0, ios::end);
+    length = location_file.tellg();
+    location_file.seekg(0, ios::beg);
+    char * buffer = new char [length];
+    location_file.read(buffer, length);
+    location_file.close();
+
+    string location(buffer, length);
+    return location;
+}
+
+string
+find_containing_bzrdir(string const path)
+{
+    string remaining = path;
+    while (!remaining.empty()) {
+        if (is_bzrdir(remaining)) {
+            return remaining;
+        }
+        remaining = dirname(remaining);
+    }
+    return string("");
+}
+
+string
+file_url_to_path(string const url)
+{
+    // We really should be decoding the URL escaped path, but for now, we just
+    // cheat
+    string path = url.substr(7, string::npos);
+    if (path[2] == ':') {
+        // Assume this is a windows style path
+        path = url.substr(8, string::npos);
+    }
+    return path;
+}
+
+/**
+ * Given a location_url, try to find its short name.
+ */
+string
+checkout_to_short(string const location_url)
+{
+    if (location_url.empty()) {
+        return string("");
+    }
+    if (location_url.substr(0, 8) != "file:///") {
+        // Not a local URL, just grab the tail
+        size_t last_slash;
+        size_t end;
+        size_t colon;
+        string pre;
+        last_slash = location_url.rfind('/');
+        if (last_slash >= location_url.size()-1) {
+            end = last_slash;
+            last_slash = location_url.rfind('/', last_slash-1);
+        } else {
+            end = location_url.size();
+        }
+        colon = location_url.find(':');
+        if (colon == string::npos) {
+            pre = "<remote>";
+        } else {
+            pre = location_url.substr(0, colon+1);
+        }
+        return pre + location_url.substr(last_slash+1, end-last_slash-1);
+    }
+    string path = file_url_to_path(location_url);
+    string parent_dir = dirname(path);
+    size_t last = path.size();
+    if (path[last-1] == '/') {
+        last--;
+    }
+    if (!is_repository(path)) {
+        // Not a branch+repo, so get the containing repo
+        parent_dir = find_containing_bzrdir(parent_dir);
+    }
+    // This should be the containing repository
+    return path.substr(parent_dir.size()+1, last - parent_dir.size() - 1);
+}
 
 int
 main(int argc, char **argv)
 {
+    for (int i = 1; i < argc; ++i) {
+        string path(argv[i]);
+        cout << "Path: " << path;
+        if (is_bzrdir(path)) {
+            cout << " has a bzrdir and";
+            if (is_branch(path)) {
+                cout << " is a branch";
+                string location;
+                location = is_checkout_of(path);
+                if (!location.empty()) {
+                    cout << " which is a checkout of "
+                        << checkout_to_short(location);
+                }
+            } else {
+                cout << " is not a branch";
+            }
+            if (is_repository(path)) {
+                cout << " and is a repository";
+            }
+        } else {
+            cout << " has no bzrdir";
+            string containing = find_containing_bzrdir(path);
+            if (!containing.empty()) {
+                cout << " but has containing bzrdir: "
+                    << find_containing_bzrdir(path);
+            }
+        }
+        cout << endl;
+    }
     return 0;
 }



More information about the bazaar-commits mailing list