aboutsummaryrefslogtreecommitdiff
path: root/build2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-03-20 14:01:38 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-03-20 14:01:38 +0200
commit10ec1ac16b5ec2577b94e8311e48ee3c7db9fb78 (patch)
treec23d7edabe624448b20b835af74bcea81cdf39bd /build2
parent4cc966d1468f6ce59600517e44d4817c0905210f (diff)
Come up with better version for uncommitted snapshots
Instead of leaving it as .z we now take the date of the previous commit and increment it by a second. The main benefit of doing it this way is that once committed, the new version does not "jump back" behind .z.
Diffstat (limited to 'build2')
-rw-r--r--build2/version/init.cxx20
-rw-r--r--build2/version/module.hxx10
-rw-r--r--build2/version/snapshot-git.cxx51
-rw-r--r--build2/version/snapshot.hxx1
4 files changed, 59 insertions, 23 deletions
diff --git a/build2/version/init.cxx b/build2/version/init.cxx
index 7b8bd01..f793c98 100644
--- a/build2/version/init.cxx
+++ b/build2/version/init.cxx
@@ -163,9 +163,9 @@ namespace build2
}
// If this is the latest snapshot (i.e., the -a.1.z kind), then load the
- // snapshot sn and id (e.g., commit date and id from git). If there is
- // uncommitted stuff, then leave it as .z.
+ // snapshot number and id (e.g., commit date and id from git).
//
+ bool committed (true);
if (v.snapshot () && v.snapshot_sn == standard_version::latest_sn)
{
snapshot ss (extract_snapshot (rs));
@@ -174,7 +174,10 @@ namespace build2
{
v.snapshot_sn = ss.sn;
v.snapshot_id = move (ss.id);
+ committed = ss.committed;
}
+ else
+ committed = false;
}
// Set all the version.* variables.
@@ -215,16 +218,17 @@ namespace build2
set ("version.pre_release_string", v.string_pre_release ());
set ("version.pre_release_number", uint64_t (v.pre_release ()));
- set ("version.snapshot", v.snapshot ()); // bool
- set ("version.snapshot_sn", v.snapshot_sn); // uint64
- set ("version.snapshot_id", v.snapshot_id); // string
- set ("version.snapshot_string", v.string_snapshot ());
+ set ("version.snapshot", v.snapshot ()); // bool
+ set ("version.snapshot_sn", v.snapshot_sn); // uint64
+ set ("version.snapshot_id", v.snapshot_id); // string
+ set ("version.snapshot_string", v.string_snapshot ());
+ set ("version.snapshot_committed", committed); // bool
set ("version.revision", uint64_t (v.revision));
// Create the module.
//
- mod.reset (new module (move (v), move (ds)));
+ mod.reset (new module (move (v), committed, move (ds)));
return true; // Init first (dist.package, etc).
}
@@ -331,7 +335,7 @@ namespace build2
// Complain if this is an uncommitted snapshot.
//
- if (v.snapshot_sn == standard_version::latest_sn)
+ if (v.snapshot () && !m.committed)
fail << "distribution of uncommitted project " << rs.src_path ();
// The plan is simple, re-serialize the manifest into a temporary file
diff --git a/build2/version/module.hxx b/build2/version/module.hxx
index 190d8d7..a5a667a 100644
--- a/build2/version/module.hxx
+++ b/build2/version/module.hxx
@@ -25,13 +25,19 @@ namespace build2
static const string name;
butl::standard_version version;
+ bool committed; // Whether this is a committed snapshot.
+
dependency_constraints dependencies;
const variable* in_symbol = nullptr; // in.symbol
const variable* in_substitution = nullptr; // in.substitution
- module (butl::standard_version v, dependency_constraints d)
- : version (move (v)), dependencies (move (d)) {}
+ module (butl::standard_version v,
+ bool c,
+ dependency_constraints d)
+ : version (move (v)),
+ committed (c),
+ dependencies (move (d)) {}
};
}
}
diff --git a/build2/version/snapshot-git.cxx b/build2/version/snapshot-git.cxx
index b85b47e..751686e 100644
--- a/build2/version/snapshot-git.cxx
+++ b/build2/version/snapshot-git.cxx
@@ -31,9 +31,9 @@ namespace build2
//
{
const char* args[] {"git", "-C", d, "status", "--porcelain", nullptr};
-
- if (!run<string> (3, args, [](string& s) {return move (s);}).empty ())
- return r;
+ r.committed = run<string> (3 /* verbosity */,
+ args,
+ [](string& s) {return move (s);}).empty ();
}
// Now extract the commit id and date. One might think that would be
@@ -45,7 +45,18 @@ namespace build2
//
// Where <len> is the size of <data> and <data> is the output of:
//
- // git cat-file commit ...
+ // git cat-file commit HEAD
+ //
+ // There is also one annoying special case: new repository without any
+ // commits. In this case the above command will fail (with diagnostics
+ // and non-zero exit code) because there is no HEAD. Of course, it can
+ // also fail for other reason (like broken repository) which would be
+ // hard to distinguish. Note, however, that we just ran git status and
+ // it would have most likely failed if this were the case. So here we
+ // (reluctantly) assume that the only reason git cat-file fails is if
+ // there is no HEAD (that we equal with the "new repository" condition
+ // which is, strictly speaking, might not be the case either). So we
+ // suppress any diagnostics, and handle non-zero exit code.
//
string data;
@@ -53,14 +64,16 @@ namespace build2
"git", "-C", d, "cat-file", "commit", "HEAD", nullptr};
process pr (run_start (3 /* verbosity */,
args,
- 0 /* stdin */,
- -1 /* stdout */));
+ 0 /* stdin */,
+ -1 /* stdout */,
+ false /* error */));
+ string l;
try
{
ifdstream is (move (pr.in_ofd), ifdstream::badbit);
- for (string l; !eof (getline (is, l)); )
+ while (!eof (getline (is, l)))
{
data += l;
data += '\n'; // We assume there is always a newline.
@@ -128,16 +141,28 @@ namespace build2
// that.
}
- run_finish (args, pr);
+ if (!run_finish (args, pr, false /* error */, l))
+ {
+ // Presumably new repository without HEAD. Return uncommitted snapshot
+ // with UNIX epoch as timestamp.
+ //
+ r.sn = 19700101000000ULL;
+ r.committed = false;
+ return r;
+ }
if (r.sn == 0)
fail << "unable to extract git commit id/date for " << src_root;
- sha1 cs;
- cs.append ("commit " + to_string (data.size ())); // Includes '\0'.
- cs.append (data.c_str (), data.size ());
-
- r.id.assign (cs.string (), 12); // 12-characters abbreviated commit id.
+ if (r.committed)
+ {
+ sha1 cs;
+ cs.append ("commit " + to_string (data.size ())); // Includes '\0'.
+ cs.append (data.c_str (), data.size ());
+ r.id.assign (cs.string (), 12); // 12-characters abbreviated commit id.
+ }
+ else
+ r.sn++; // Add a second.
return r;
}
diff --git a/build2/version/snapshot.hxx b/build2/version/snapshot.hxx
index b7e6dd7..15f4b59 100644
--- a/build2/version/snapshot.hxx
+++ b/build2/version/snapshot.hxx
@@ -18,6 +18,7 @@ namespace build2
{
uint64_t sn = 0;
string id;
+ bool committed = false;
bool
empty () const {return sn == 0;}