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