aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-07-02 11:24:47 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-07-02 11:24:47 +0200
commit93a673946ca1587126b3c108476234d93a7c5c7c (patch)
tree531c8e10c1d5bdf780012e207facae6c31857f91
parent85fe1442232cc747ce4935708ecefba00ab7c101 (diff)
Try to obtain real email from environment, VCS in bdep-new
-rw-r--r--bdep/new.cli9
-rw-r--r--bdep/new.cxx12
-rw-r--r--bdep/project-email.cxx116
-rw-r--r--bdep/project-email.hxx23
4 files changed, 158 insertions, 2 deletions
diff --git a/bdep/new.cli b/bdep/new.cli
index e700985..df77717 100644
--- a/bdep/new.cli
+++ b/bdep/new.cli
@@ -245,4 +245,13 @@ namespace bdep
working directory."
}
};
+
+ "\h|ENVIRONMENT|
+
+ The \cb{BDEP_EMAIL} environment variable can be used to specify the package
+ email address. If not set, the \cb{new} command will first try to obtain
+ the email from the version control system (if used) and then from the
+ \cb{EMAIL} environment variable. If all these methods fail, a dummy
+ \cb{@example.org} email is used.
+ "
}
diff --git a/bdep/new.cxx b/bdep/new.cxx
index ab8b255..9869fe7 100644
--- a/bdep/new.cxx
+++ b/bdep/new.cxx
@@ -5,6 +5,7 @@
#include <bdep/new.hxx>
#include <bdep/project.hxx>
+#include <bdep/project-email.hxx>
#include <bdep/database.hxx>
#include <bdep/diagnostics.hxx>
@@ -172,7 +173,8 @@ namespace bdep
fail << "directory " << out << " already exists";
// Initialize the version control system. Do it before writing anything
- // ourselves in case it fails.
+ // ourselves in case it fails. Also, the email discovery may do the VCS
+ // detection.
//
if (!pkg)
{
@@ -257,6 +259,12 @@ namespace bdep
// manifest
//
+ string email;
+ {
+ optional<string> r (project_email (prj));
+ email = r ? move (*r) : "you@example.org";
+ }
+
os.open (f = out / "manifest");
os << ": 1" << endl
<< "name: " << n << endl
@@ -264,7 +272,7 @@ namespace bdep
<< "summary: " << s << " " << t << endl
<< "license: TODO" << endl
<< "url: https://example.org/" << n << endl
- << "email: you@example.org" << endl
+ << "email: " << email << endl
<< "depends: * build2 >= 0.8.0-" << endl
<< "depends: * bpkg >= 0.8.0-" << endl
<< "#depends: libhello ^1.0.0" << endl;
diff --git a/bdep/project-email.cxx b/bdep/project-email.cxx
new file mode 100644
index 0000000..20279a0
--- /dev/null
+++ b/bdep/project-email.cxx
@@ -0,0 +1,116 @@
+// file : bdep/project-email.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <bdep/project-email.hxx>
+
+#include <libbutl/filesystem.mxx>
+
+#include <bdep/diagnostics.hxx>
+
+using namespace butl;
+
+namespace bdep
+{
+ optional<string>
+ project_email (const dir_path& prj)
+ {
+ optional<string> r;
+
+ // The search order is as follows:
+ //
+ // BDEP_EMAIL
+ // <VCS>
+ // EMAIL
+ //
+ if ((r = getenv ("BDEP_EMAIL")))
+ return r;
+
+ // See if this is a VCS repository we recognize.
+ //
+
+ // .git can be either a directory or a file in case of a submodule.
+ //
+ if (entry_exists (prj / ".git",
+ true /* follow_symlinks */,
+ true /* ignore_errors */))
+ {
+ // In git the author email can be specified with the GIT_AUTHOR_EMAIL
+ // environment variable after which things fall back to the committer
+ // (GIT_COMMITTER_EMAIL and then the user.email git-config value). The
+ // resolved value can be queried with the GIT_AUTHOR_IDENT logical
+ // variable.
+ //
+ process pr;
+ bool io (false);
+ try
+ {
+ fdpipe pipe (fdopen_pipe ());
+
+ // If git cannot determine the author name/email, it fails verbosely
+ // so we suppress all diagnostics.
+ //
+ pr = start (0 /* stdin */,
+ pipe /* stdout */,
+ fdnull () /* stderr */,
+ "git",
+ "-C", prj,
+ "var",
+ "GIT_AUTHOR_IDENT");
+
+ pipe.out.close ();
+ ifdstream is (move (pipe.in), ifdstream::badbit);
+
+ // The output should be a single line in this form:
+ //
+ // NAME <EMAIL> TIME ZONE
+ //
+ // For example:
+ //
+ // John Doe <john@example.org> 1530517726 +0200
+ //
+ // The <> delimiters are there even if the email is empty so we use
+ // them as anchors.
+ //
+ string l;
+ if (!eof (getline (is, l)))
+ {
+ size_t p1, p2;
+
+ if ((p2 = l.rfind ('>' )) == string::npos ||
+ (p1 = l.rfind ('<', p2)) == string::npos)
+ fail << "no email in git-var output";
+
+ if (++p1 != p2)
+ r = string (l, p1, p2 - p1);
+ }
+
+ is.close (); // Detect errors.
+ }
+ catch (const io_error&)
+ {
+ io = true; // Presumably git failed so check that first.
+ }
+
+ if (!pr.wait ())
+ {
+ const process_exit& e (*pr.exit);
+
+ if (!e.normal ())
+ fail << "process git " << e;
+
+ r = nullopt;
+ }
+ else if (io)
+ fail << "unable to read git-var output";
+
+ if (r)
+ return r;
+ }
+
+ if ((r = getenv ("EMAIL")))
+ return r;
+
+ return r;
+ }
+}
diff --git a/bdep/project-email.hxx b/bdep/project-email.hxx
new file mode 100644
index 0000000..c630682
--- /dev/null
+++ b/bdep/project-email.hxx
@@ -0,0 +1,23 @@
+// file : bdep/project-email.hxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BDEP_PROJECT_EMAIL_HXX
+#define BDEP_PROJECT_EMAIL_HXX
+
+#include <bdep/types.hxx>
+#include <bdep/utility.hxx>
+
+namespace bdep
+{
+ // Given a project directly, try to discover the author's email address
+ // using the environment and, if project looks like a repository, its VCS.
+ //
+ // Note: if using this function in a command, don't forget to update its
+ // ENVIRONMENT section to mention BDEP_EMAIL.
+ //
+ optional<string>
+ project_email (const dir_path&);
+}
+
+#endif // BDEP_PROJECT_EMAIL_HXX