aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
authorGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2009-09-23 20:58:20 -0400
committerGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2009-09-23 20:58:20 -0400
commit51db7ab0dfcf9120589241db6183456971ba89c4 (patch)
tree92849594e26b5c232aa606e9848ad80e02dfbc28 /scripts
parentb347075936236a74417fe7cb4739399ffb2f7eca (diff)
add eigen_gen_credits script
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/eigen_gen_credits21
-rw-r--r--scripts/eigen_gen_credits.cpp209
2 files changed, 230 insertions, 0 deletions
diff --git a/scripts/eigen_gen_credits b/scripts/eigen_gen_credits
new file mode 100755
index 000000000..ec31da33c
--- /dev/null
+++ b/scripts/eigen_gen_credits
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# this script must be run from the eigen2/ directory.
+# when running hg churn from the scripts/ subdir, i hit a divide-by-zero error in hg churn.
+#
+# like this:
+# cd eigen2
+# scripts/eigen_gen_credits
+
+# configuration
+USER='bjacob'
+
+wget http://eigen.tuxfamily.org/index.php?title=ContributorsInfo -O online-info.out -o wget.log
+hg churn -r 37: --changesets -t {author} > churn-changesets.out
+hg churn -r 37: -t {author} > churn-changedlines.out
+
+g++ scripts/eigen_gen_credits.cpp -o e
+
+./e > credits.out
+
+rsync credits.out $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/credits.out || (echo "upload failed"; exit 1)
diff --git a/scripts/eigen_gen_credits.cpp b/scripts/eigen_gen_credits.cpp
new file mode 100644
index 000000000..4f86c7c9d
--- /dev/null
+++ b/scripts/eigen_gen_credits.cpp
@@ -0,0 +1,209 @@
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <map>
+#include <list>
+
+using namespace std;
+
+// this function takes a line that may contain a name and/or email address,
+// and returns just the name, while fixing the "bad cases".
+std::string contributor_name(const std::string& line)
+{
+ string result;
+ size_t position_of_email_address = line.find_first_of('<');
+ if(position_of_email_address != string::npos)
+ {
+ // there is an e-mail address.
+
+ // Hauke once committed as "John Smith", fix that.
+ if(line.find("hauke.heibel") != string::npos)
+ result = "Hauke Heibel";
+ else
+ {
+ // just remove the e-mail address
+ result = line.substr(0, position_of_email_address);
+ }
+ }
+ else
+ {
+ // there is no e-mail address.
+
+ if(line.find("convert-repo") != string::npos)
+ result = "";
+ else
+ result = line;
+ }
+
+ // remove trailing spaces
+ size_t length = result.length();
+ while(length >= 1 && result[length-1] == ' ') result.erase(--length);
+
+ return result;
+}
+
+// parses hg churn output to generate a contributors map.
+map<string,int> contributors_map_from_churn_output(const char *filename)
+{
+ map<string,int> contributors_map;
+
+ string line;
+ ifstream churn_out;
+ churn_out.open(filename, ios::in);
+ while(!getline(churn_out,line).eof())
+ {
+ // remove the histograms "******" that hg churn may draw at the end of some lines
+ size_t first_star = line.find_first_of('*');
+ if(first_star != string::npos) line.erase(first_star);
+
+ // remove trailing spaces
+ size_t length = line.length();
+ while(length >= 1 && line[length-1] == ' ') line.erase(--length);
+
+ // now the last space indicates where the number starts
+ size_t last_space = line.find_last_of(' ');
+
+ // get the number (of changesets or of modified lines for each contributor)
+ int number;
+ istringstream(line.substr(last_space+1)) >> number;
+
+ // get the name of the contributor
+ line.erase(last_space);
+ string name = contributor_name(line);
+
+ map<string,int>::iterator it = contributors_map.find(name);
+ // if new contributor, insert
+ if(it == contributors_map.end())
+ contributors_map.insert(pair<string,int>(name, number));
+ // if duplicate, just add the number
+ else
+ it->second += number;
+ }
+ churn_out.close();
+
+ return contributors_map;
+}
+
+struct contributor
+{
+ string name;
+ int changedlines;
+ int changesets;
+ string url;
+ string misc;
+
+ contributor() : changedlines(0), changesets(0) {}
+
+ bool operator < (const contributor& other)
+ {
+ return changedlines > other.changedlines;
+ }
+};
+
+void add_online_info_into_contributors_list(list<contributor>& contributors_list, const char *filename)
+{
+ string line;
+ ifstream churn_out;
+ churn_out.open(filename, ios::in);
+ while(!getline(churn_out,line).eof())
+ {
+ string hgname, realname, url, misc;
+
+ size_t last_bar = line.find_last_of('|');
+ if(last_bar == string::npos) continue;
+ if(last_bar < line.length())
+ misc = line.substr(last_bar+1);
+ line.erase(last_bar);
+
+ last_bar = line.find_last_of('|');
+ if(last_bar == string::npos) continue;
+ if(last_bar < line.length())
+ url = line.substr(last_bar+1);
+ line.erase(last_bar);
+
+ last_bar = line.find_last_of('|');
+ if(last_bar == string::npos) continue;
+ if(last_bar < line.length())
+ realname = line.substr(last_bar+1);
+ line.erase(last_bar);
+
+ hgname = line;
+
+ // remove the example line
+ if(hgname.find("MercurialName") != string::npos) continue;
+
+ list<contributor>::iterator it;
+ for(it=contributors_list.begin(); it != contributors_list.end() && it->name != hgname; ++it)
+ {}
+
+ if(it == contributors_list.end())
+ {
+ contributor c;
+ c.name = realname;
+ c.url = url;
+ c.misc = misc;
+ contributors_list.push_back(c);
+ }
+ else
+ {
+ it->name = realname;
+ it->url = url;
+ it->misc = misc;
+ }
+ }
+}
+
+ostream& operator<<(ostream& stream, const contributor& c)
+{
+ stream << c.name << "|" << c.changedlines << "|" << c.changesets << "|" << c.url << "|" << c.misc;
+}
+
+int main()
+{
+ // parse the hg churn output files
+ map<string,int> contributors_map_for_changedlines = contributors_map_from_churn_output("churn-changedlines.out");
+ map<string,int> contributors_map_for_changesets = contributors_map_from_churn_output("churn-changesets.out");
+
+ // merge into the contributors list
+ list<contributor> contributors_list;
+ map<string,int>::iterator it;
+ for(it=contributors_map_for_changedlines.begin(); it != contributors_map_for_changedlines.end(); ++it)
+ {
+ contributor c;
+ c.name = it->first;
+ c.changedlines = it->second;
+ c.changesets = contributors_map_for_changesets.find(it->first)->second;
+ contributors_list.push_back(c);
+ }
+
+ add_online_info_into_contributors_list(contributors_list, "online-info.out");
+
+ contributors_list.sort();
+
+ cout << "{| cellpadding=\"5\"\n";
+ cout << "!\n";
+ cout << "! Lines changed\n(changesets)\n";
+ cout << "! Misc\n";
+
+ list<contributor>::iterator itc;
+ int i = 0;
+ for(itc=contributors_list.begin(); itc != contributors_list.end(); ++itc)
+ {
+ if(itc->name.length() == 0) continue;
+ if(i%2) cout << "|-\n";
+ else cout << "|- style=\"background:#FFFFD0\"\n";
+ if(itc->url.length())
+ cout << "| [" << itc->url << " " << itc->name << "]\n";
+ else
+ cout << "| " << itc->name << "\n";
+ if(itc->changedlines)
+ cout << "| " << itc->changedlines << " (" << itc->changesets << ")\n";
+ else
+ cout << "| (no own changesets) \n";
+ cout << "| " << itc->misc << "\n";
+ i++;
+ }
+ cout << "|}" << endl;
+}