Revision: 76456
          http://sourceforge.net/p/brlcad/code/76456
Author:   starseeker
Date:     2020-07-23 22:24:52 +0000 (Thu, 23 Jul 2020)
Log Message:
-----------
Improve commit line wrapping, assign svn authors as well to commit metadata 
given map

Modified Paths:
--------------
    brlcad/trunk/misc/repowork/commit.cpp
    brlcad/trunk/misc/repowork/repowork.cpp
    brlcad/trunk/misc/repowork/repowork.h

Modified: brlcad/trunk/misc/repowork/commit.cpp
===================================================================
--- brlcad/trunk/misc/repowork/commit.cpp       2020-07-23 22:15:12 UTC (rev 
76455)
+++ brlcad/trunk/misc/repowork/commit.cpp       2020-07-23 22:24:52 UTC (rev 
76456)
@@ -396,6 +396,100 @@
     }).base(), s.end());
 }
 
+std::string
+commit_msg(git_commit_data *c)
+{
+    // TODO - the width could easily be user option, and probably should be...
+    int cwidth = 72;
+    std::string nmsg;
+
+    // Any whitespace at the end of the message, just trim it
+    if (c->s->trim_whitespace) {
+       rtrim(c->commit_msg);
+    }
+
+    if (c->s->wrap_commit_lines) {
+       // Wrap the commit messages - gitk doesn't like long one liners by
+       // default.  Don't know why the line wrap ISN'T on by default, but we
+       // might as well deal with it while we're here...
+       size_t pdelim = c->commit_msg.find("\n\n");
+       if (pdelim == std::string::npos) {
+           size_t spos = c->commit_msg.find_first_of('\n');
+           if (spos == std::string::npos) {
+               std::string wmsg = 
TextFlow::Column(c->commit_msg).width(cwidth).toString();
+               c->commit_msg = wmsg;
+           }
+       } else {
+           // Multiple paragraphs - separate them for individual consideration.
+           std::vector<std::string> paragraphs;
+           std::string paragraphs_str = c->commit_msg;
+           while (paragraphs_str.length()) {
+               std::string para = paragraphs_str.substr(0, pdelim);
+               std::string remainder = paragraphs_str.substr(pdelim+2, 
std::string::npos);
+               paragraphs_str = remainder;
+               paragraphs.push_back(para);
+               pdelim = paragraphs_str.find("\n\n");
+               if (pdelim == std::string::npos) {
+                   // That's it - last line
+                   paragraphs.push_back(paragraphs_str);
+                   paragraphs_str = std::string("");
+               }
+           }
+           bool can_wrap = true;
+           // If any of the paragraphs delimited by two returns has returns 
inside of it, we can't
+           // do anything - the message already has some sort of formatting.
+           for (size_t i = 0; i < paragraphs.size(); i++) {
+               size_t spos = paragraphs[i].find_first_of('\n');
+               if (spos != std::string::npos) {
+                   can_wrap = false;
+                   break;
+               }
+           }
+           if (can_wrap) {
+               // Wrap each paragraph individually
+               for (size_t i = 0; i < paragraphs.size(); i++) {
+                   std::string newpara = 
TextFlow::Column(paragraphs[i]).width(cwidth).toString();
+                   paragraphs[i] = newpara;
+               }
+               std::string newcommitmsg;
+               // Reassemble
+               for (size_t i = 0; i < paragraphs.size(); i++) {
+                   newcommitmsg.append(paragraphs[i]);
+                   newcommitmsg.append("\n\n");
+               }
+               rtrim(newcommitmsg);
+               c->commit_msg = newcommitmsg;
+           }
+       }
+    }
+
+    if (c->notes_string.length()) {
+       std::string nstr = c->notes_string;
+       if (c->s->trim_whitespace) rtrim(nstr);
+       if (c->s->wrap_commit_lines) {
+           size_t spos = nstr.find_first_of('\n');
+           if (spos == std::string::npos) {
+               std::string wmsg = 
TextFlow::Column(nstr).width(cwidth).toString();
+               nstr = wmsg;
+           }
+       }
+       if (c->svn_author.length()) {
+           std::string authstr = std::string("svn:author:") + c->svn_author;
+           nmsg = c->commit_msg + std::string("\n\n") + nstr + 
std::string("\n") + authstr + std::string("\n");
+       } else {
+           nmsg = c->commit_msg + std::string("\n\n") + nstr + 
std::string("\n");
+       }
+    } else {
+       if (c->s->trim_whitespace) {
+           nmsg = c->commit_msg + std::string("\n");
+       } else {
+           nmsg = c->commit_msg;
+       }
+    }
+
+    return nmsg;
+}
+
 int
 write_commit(std::ofstream &outfile, git_commit_data *c, std::ifstream &infile)
 {
@@ -433,41 +527,7 @@
     }
     outfile << "committer " << c->committer << " " << c->committer_timestamp 
<< "\n";
 
-    if (c->s->trim_whitespace) {
-       rtrim(c->commit_msg);
-    }
-    if (c->s->wrap_commit_lines) {
-       // Wrap the commit messages - gitk doesn't like long one liners by
-       // default.  Don't know why the line wrap ISN'T on by default, but we
-       // might as well deal with it while we're here...
-       //
-       // TODO - the width could easily be a parameter, and probably should
-       // be...
-       size_t spos = c->commit_msg.find_first_of('\n');
-       if (spos == std::string::npos) {
-           std::string wmsg = 
TextFlow::Column(c->commit_msg).width(72).toString();
-           c->commit_msg = wmsg;
-       }
-    }
-    std::string nmsg;
-    if (c->notes_string.length()) {
-       std::string nstr = c->notes_string;
-       if (c->s->trim_whitespace) rtrim(nstr);
-       if (c->s->wrap_commit_lines) {
-           size_t spos = nstr.find_first_of('\n');
-           if (spos == std::string::npos) {
-               std::string wmsg = TextFlow::Column(nstr).width(72).toString();
-               nstr = wmsg;
-           }
-       }
-       nmsg = c->commit_msg + std::string("\n\n") + nstr + std::string("\n");
-    } else {
-       if (c->s->trim_whitespace) {
-           nmsg = c->commit_msg + std::string("\n");
-       } else {
-           nmsg = c->commit_msg;
-       }
-    }
+    std::string nmsg = commit_msg(c);
     outfile << "data " << nmsg.length() << "\n";
     outfile << nmsg;
 

Modified: brlcad/trunk/misc/repowork/repowork.cpp
===================================================================
--- brlcad/trunk/misc/repowork/repowork.cpp     2020-07-23 22:15:12 UTC (rev 
76455)
+++ brlcad/trunk/misc/repowork/repowork.cpp     2020-07-23 22:24:52 UTC (rev 
76456)
@@ -76,6 +76,17 @@
        // Write the message to the commit's string;
        s->commits[i].notes_string = note;
 
+       // SPECIAL PURPOSE CODE - should go away eventually.
+       // For BRL-CAD specifically, this information contains
+       // the SVN id associated with the commit.  We want to
+       // use this info, so parse it out and store it.
+       std::regex svnid("svn:revision:([0-9]+).*");
+       std::smatch svnidvar;
+       if (std::regex_search(note, svnidvar, svnid)) {
+           s->commits[i].svn_id = std::string(svnidvar[1]);
+           std::cout << "Identified revision " << s->commits[i].svn_id << "\n";
+       }
+
        n.close();
     }
 
@@ -134,8 +145,56 @@
     return 0;
 }
 
+int
+git_map_svn_authors(git_fi_data *s, std::string &svn_map)
+{
+    // read map
+    std::ifstream infile(svn_map, std::ifstream::binary);
+    if (!infile.good()) {
+       std::cerr << "Could not open svn_map file: " << svn_map << "\n";
+       exit(-1);
+    }
 
+    // Create mapping of ids to svn authors
+    std::map<std::string, std::string> svn_author_map;
+    std::string line;
+    while (std::getline(infile, line)) {
+       // Skip empty lines
+       if (!line.length()) {
+           continue;
+       }
 
+       size_t spos = line.find_first_of(" ");
+       if (spos == std::string::npos) {
+           std::cerr << "Invalid svn map line!: " << line << "\n";
+           exit(-1);
+       }
+
+       std::string id = line.substr(0, spos);
+       std::string author = line.substr(spos+1, std::string::npos);
+
+       svn_author_map[id] = author;
+    }
+
+    // Iterate over the commits and assign authors.
+    for (size_t i = 0; i < s->commits.size(); i++) {
+       git_commit_data *c = &(s->commits[i]);
+       if (!c->svn_id.length()) {
+           continue;
+       }
+       if (svn_author_map.find(c->svn_id) != svn_author_map.end()) {
+           std::string svnauth = svn_author_map[c->svn_id];
+           //std::cerr << "Found SVN commit \"" << c->svn_id << "\" with 
author \"" << svnauth << "\"\n";
+           c->svn_author = svnauth;
+       }
+    }
+
+    return 0;
+}
+
+
+
+
 typedef int (*gitcmd_t)(git_fi_data *, std::ifstream &);
 
 gitcmd_t
@@ -209,6 +268,7 @@
     bool trim_whitespace = false;
     std::string repo_path;
     std::string email_map;
+    std::string svn_map;
 
     // TODO - might be good do have a "validate" option that does the fast 
import and then
     // checks every commit saved from the old repo in the new one...
@@ -217,9 +277,10 @@
        cxxopts::Options options(argv[0], " - process git fast-import files");
 
        options.add_options()
-           ("e,email-map", "Specify replacement username+email mappings (one 
map per line, format is commit-id-1;commit-id-2)", 
cxxopts::value<std::vector<std::string>>(), "path to map file")
+           ("e,email-map", "Specify replacement username+email mappings (one 
map per line, format is commit-id-1;commit-id-2)", 
cxxopts::value<std::vector<std::string>>(), "map file")
            ("n,collapse-notes", "Take any git-notes contents and append them 
to regular commit messages.", cxxopts::value<bool>(collapse_notes))
-           ("r,repo", "Original git repository path (must support running git 
log)", cxxopts::value<std::vector<std::string>>(), "relative path to Git 
repository")
+           ("r,repo", "Original git repository path (must support running git 
log)", cxxopts::value<std::vector<std::string>>(), "path to repo")
+           ("s,svn-map", "Specify svn rev -> author map (one mapping per line, 
format is commit-rev authorname)", cxxopts::value<std::vector<std::string>>(), 
"map file")
            ("t,trim-whitespace", "Trim extra spaces and end-of-line characters 
from the end of commit messages", cxxopts::value<bool>(trim_whitespace))
            ("w,wrap-commit-lines", "Wrap long commit lines to 72 cols (won't 
wrap messages already having multiple non-empty lines)", 
cxxopts::value<bool>(wrap_commit_lines))
            ("h,help", "Print help")
@@ -245,6 +306,12 @@
            email_map = ff[0];
        }
 
+       if (result.count("s"))
+       {
+           auto& ff = result["s"].as<std::vector<std::string>>();
+           svn_map = ff[0];
+       }
+
     }
     catch (const cxxopts::OptionException& e)
     {
@@ -290,6 +357,11 @@
        git_map_emails(&fi_data, email_map);
     }
 
+    if (svn_map.length()) {
+       // Handle the svn authors
+       git_map_svn_authors(&fi_data, svn_map);
+    }
+
     fi_data.wrap_commit_lines = wrap_commit_lines;
     fi_data.trim_whitespace = trim_whitespace;
 
@@ -297,15 +369,25 @@
 
     std::ifstream ifile(argv[1], std::ifstream::binary);
     std::ofstream ofile(argv[2], std::ios::out | std::ios::binary);
+    ofile << "progress Writing blobs...\n";
     for (size_t i = 0; i < fi_data.blobs.size(); i++) {
        write_blob(ofile, &fi_data.blobs[i], ifile);
+       if ( !(i % 1000) ) {
+           ofile << "progress blob " << i << " of " << fi_data.blobs.size() << 
"\n";
+       }
     }
+    ofile << "progress Writing commits...\n";
     for (size_t i = 0; i < fi_data.commits.size(); i++) {
        write_commit(ofile, &fi_data.commits[i], ifile);
+       if ( !(i % 1000) ) {
+           ofile << "progress commit " << i << " of " << 
fi_data.commits.size() << "\n";
+       }
     }
+    ofile << "progress Writing tags...\n";
     for (size_t i = 0; i < fi_data.tags.size(); i++) {
        write_tag(ofile, &fi_data.tags[i], ifile);
     }
+    ofile << "progress Done.\n";
 
     ifile.close();
     ofile.close();

Modified: brlcad/trunk/misc/repowork/repowork.h
===================================================================
--- brlcad/trunk/misc/repowork/repowork.h       2020-07-23 22:15:12 UTC (rev 
76455)
+++ brlcad/trunk/misc/repowork/repowork.h       2020-07-23 22:24:52 UTC (rev 
76456)
@@ -94,6 +94,11 @@
        // Resets are order dependent - treat them as pseudo-commits for
        // storage purpose, but they are written differently
        int reset_commit = 0;
+
+       // Special purpose entries for assigning an additional line
+       // to the existing notes-based info to id SVN usernames
+       std::string svn_id;
+       std::string svn_author;
 };
 
 class git_tag_data {

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to