aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bdep/buildfile3
-rw-r--r--bdep/ci-parsers.cxx4
-rw-r--r--bdep/ci-parsers.hxx4
-rw-r--r--bdep/ci-types.hxx2
-rw-r--r--bdep/ci.cli10
-rw-r--r--bdep/release-parsers.cxx31
-rw-r--r--bdep/release-parsers.hxx31
-rw-r--r--bdep/release-types.hxx18
-rw-r--r--bdep/release.cli14
-rw-r--r--bdep/release.cxx190
-rw-r--r--tests/release.testscript410
11 files changed, 603 insertions, 114 deletions
diff --git a/bdep/buildfile b/bdep/buildfile
index 702058c..f7ce96b 100644
--- a/bdep/buildfile
+++ b/bdep/buildfile
@@ -147,6 +147,9 @@ if $cli.configured
cli.cxx{ci-options}: cli.options += \
--cxx-prologue "#include <bdep/ci-parsers.hxx>"
+ cli.cxx{release-options}: cli.options += \
+--cxx-prologue "#include <bdep/release-parsers.hxx>"
+
# Avoid generating CLI runtime and empty inline file for help topics.
#
cli.cxx{projects-configs}: cli.options += --suppress-cli --suppress-inline
diff --git a/bdep/ci-parsers.cxx b/bdep/ci-parsers.cxx
index 2d19c4b..5a56763 100644
--- a/bdep/ci-parsers.cxx
+++ b/bdep/ci-parsers.cxx
@@ -17,8 +17,8 @@ namespace bdep
using namespace std;
using namespace butl;
- void parser<ci_override>::
- parse (ci_override& r, bool& xs, scanner& s)
+ void parser<cmd_ci_override>::
+ parse (cmd_ci_override& r, bool& xs, scanner& s)
{
auto add = [&r] (string&& n, string&& v)
{
diff --git a/bdep/ci-parsers.hxx b/bdep/ci-parsers.hxx
index 5a8f664..943821c 100644
--- a/bdep/ci-parsers.hxx
+++ b/bdep/ci-parsers.hxx
@@ -25,10 +25,10 @@ namespace bdep
// option-specific semantics.
//
template <>
- struct parser<ci_override>
+ struct parser<cmd_ci_override>
{
static void
- parse (ci_override&, bool&, scanner&);
+ parse (cmd_ci_override&, bool&, scanner&);
};
}
}
diff --git a/bdep/ci-types.hxx b/bdep/ci-types.hxx
index 4b2ab6d..522b730 100644
--- a/bdep/ci-types.hxx
+++ b/bdep/ci-types.hxx
@@ -14,7 +14,7 @@ namespace bdep
// This type is intended for accumulating package manifest override values
// from all the override-related options (see ci-parsers.hxx for details).
//
- class ci_override: public vector<butl::manifest_name_value>
+ class cmd_ci_override: public vector<butl::manifest_name_value>
{
};
}
diff --git a/bdep/ci.cli b/bdep/ci.cli
index 928e884..ccf6ed3 100644
--- a/bdep/ci.cli
+++ b/bdep/ci.cli
@@ -141,11 +141,11 @@ namespace bdep
// will) to work, this option should come after all the options it
// aliases.
//
- ci_override --overrides |
- --override |
- --overrides-file |
- --builds |
- --build-email;
+ cmd_ci_override --overrides |
+ --override |
+ --overrides-file |
+ --builds |
+ --build-email;
string --simulate
{
diff --git a/bdep/release-parsers.cxx b/bdep/release-parsers.cxx
new file mode 100644
index 0000000..5ad8cd7
--- /dev/null
+++ b/bdep/release-parsers.cxx
@@ -0,0 +1,31 @@
+// file : bdep/release-parsers.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <bdep/release-parsers.hxx>
+
+#include <bdep/release-options.hxx> // bdep::cli namespace
+
+namespace bdep
+{
+ namespace cli
+ {
+ void parser<cmd_release_current_tag>::
+ parse (cmd_release_current_tag& r, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (!s.more ())
+ throw missing_value (o);
+
+ string v (s.next ());
+
+ if (v == "keep") r = cmd_release_current_tag::keep;
+ else if (v == "update") r = cmd_release_current_tag::update;
+ else if (v == "remove") r = cmd_release_current_tag::remove;
+ else throw invalid_value (o, v);
+
+ xs = true;
+ }
+ }
+}
diff --git a/bdep/release-parsers.hxx b/bdep/release-parsers.hxx
new file mode 100644
index 0000000..607882f
--- /dev/null
+++ b/bdep/release-parsers.hxx
@@ -0,0 +1,31 @@
+// file : bdep/release-parsers.hxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+// CLI parsers, included into the generated source files.
+//
+
+#ifndef BDEP_RELEASE_PARSERS_HXX
+#define BDEP_RELEASE_PARSERS_HXX
+
+#include <bdep/release-types.hxx>
+
+namespace bdep
+{
+ namespace cli
+ {
+ class scanner;
+
+ template <typename T>
+ struct parser;
+
+ template <>
+ struct parser<cmd_release_current_tag>
+ {
+ static void
+ parse (cmd_release_current_tag&, bool&, scanner&);
+ };
+ }
+}
+
+#endif // BDEP_RELEASE_PARSERS_HXX
diff --git a/bdep/release-types.hxx b/bdep/release-types.hxx
new file mode 100644
index 0000000..dc24ba4
--- /dev/null
+++ b/bdep/release-types.hxx
@@ -0,0 +1,18 @@
+// file : bdep/release-types.hxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BDEP_RELEASE_TYPES_HXX
+#define BDEP_RELEASE_TYPES_HXX
+
+namespace bdep
+{
+ enum class cmd_release_current_tag
+ {
+ keep,
+ update,
+ remove
+ };
+}
+
+#endif // BDEP_RELEASE_TYPES_HXX
diff --git a/bdep/release.cli b/bdep/release.cli
index 768cba1..b20edb1 100644
--- a/bdep/release.cli
+++ b/bdep/release.cli
@@ -5,6 +5,7 @@
include <set>;
include <bdep/common.cli>;
+include <bdep/release-types.hxx>;
"\section=1"
"\name=bdep-release"
@@ -44,8 +45,9 @@ namespace bdep
package's \cb{manifest} file, commits these changes (unless
\cb{--no-commit} is specified), tags this commit (unless \cb{--no-tag} is
specified), and, if \cb{--push} is specified, pushes the changes to the
- remote. Note that in this mode \cb{release} will also silently replace an
- existing tag for the same version.
+ remote. In this mode \cb{release} can be optionally instructed to update
+ an existing tag for the current version to point to the latest revision
+ (\cb{--current-tag=update}) or to remove it (\cb{--current-tag=remove}).
When releasing a revision, the project's repository index is expected to
already contain other changes since for a revision all the associated
@@ -105,6 +107,14 @@ namespace bdep
"Tag the already released version instead of releasing a new one."
}
+ cmd_release_current_tag --current-tag = cmd_release_current_tag::keep
+ {
+ "<action>",
+ "Specify what to do with an existing tag for the current version when
+ tagging a new revision. Valid values for this option are \cb{keep}
+ (default), \cb{update}, and \cb{remove}."
+ }
+
bool --push
{
"Push the committed changes and tags to the remote."
diff --git a/bdep/release.cxx b/bdep/release.cxx
index f6615ab..81a6e3a 100644
--- a/bdep/release.cxx
+++ b/bdep/release.cxx
@@ -56,7 +56,13 @@ namespace bdep
optional<standard_version> open_version;
optional<string> tag;
- bool replace_tag = false;
+
+ struct current_tag
+ {
+ string name;
+ cmd_release_current_tag action;
+ };
+ optional<current_tag> cur_tag; // Only present if tagging a revision.
};
using status = git_repository_status;
@@ -95,10 +101,11 @@ namespace bdep
// happen as part of a release or revision.
//
if (cv.snapshot () && o.force ().find ("snapshot") == o.force ().end ())
- fail << "current version " << cv << " is a snapshot"<<
+ fail << "current version " << cv << " is a snapshot" <<
info << "use --force=snapshot to tag anyway";
- // Canonical version tag without epoch or revision.
+ // Canonical version tag without epoch or revision, unless we keep/remove
+ // the current tag in the revising or tagging mode.
//
// For tagging a snapshot we need to use the actual package version
// (replacing .z with the actual snapshot information). Note: for
@@ -109,11 +116,47 @@ namespace bdep
? package_version (o, pkg.manifest.directory ())
: cv);
- prj.tag = "v" + v.string_project ();
+ auto vtag = [] (const standard_version& v, bool inc_rev)
+ {
+ return "v" + v.string_project (inc_rev);
+ };
- // Replace the existing tag only if this is a revision.
- //
- prj.replace_tag = (cv.revision != 0);
+ if (cv.revision == 0) // Tagging a release.
+ {
+ // Specifying --current-tag for the release tagging is meaningless.
+ //
+ if (o.current_tag_specified ())
+ fail << "--current-tag specified for non-revision current version "
+ << cv;
+
+ prj.tag = vtag (v, false /* inc_rev */);
+ }
+ else // Tagging a revision.
+ {
+ // Note that using --current-tag for the same version inconsistently
+ // either fails in the middle of the release (e.g. for update after
+ // remove) or succeeds but with an undesirable result (e.g. update after
+ // keep). Diagnosing such inconsistent use is quite complicated so let's
+ // ignore it for now.
+ //
+ cmd_release_current_tag ct (o.current_tag ());
+
+ // Include the revision into the tag, unless we update the current tag.
+ //
+ prj.tag = vtag (v, ct != cmd_release_current_tag::update /* inc_rev */);
+
+ // Current tag version.
+ //
+ // Note that the current tag name is only used for removal but let's
+ // always fill it in, for completeness.
+ //
+ standard_version ctv (v);
+ ctv.revision = ct != cmd_release_current_tag::update
+ ? v.revision - 1
+ : 0;
+
+ prj.cur_tag = project::current_tag {vtag (ctv, true /* inc_rev */), ct};
+ }
}
static void
@@ -460,14 +503,42 @@ namespace bdep
}
};
- // Verify that an option is specified only if it's prerequisite option
- // is also specified.
+ // Verify that an option is specified only if any of it's prerequisite
+ // options is also specified.
//
- auto require = [] (const char* opt, bool opt_specified,
- const char* prereq, bool prereq_specified)
+ auto require_any = [] (
+ const char* opt, bool opt_specified,
+ const small_vector<pair<const char*, bool>, 2>& prereqs)
{
- if (opt_specified && !prereq_specified)
- fail << opt << " requires " << prereq;
+ assert (!prereqs.empty ());
+
+ if (opt_specified)
+ {
+ for (const pair<const char*, bool>& p: prereqs)
+ {
+ // Bail out if a prerequisite is specified.
+ //
+ if (p.second)
+ return;
+ }
+
+ diag_record dr (fail);
+ dr << opt << " requires";
+
+ for (size_t i (0); i != prereqs.size (); ++i)
+ {
+ if (i != 0)
+ {
+ if (prereqs.size () > 2)
+ dr << ',';
+
+ if (i == prereqs.size () - 1)
+ dr << " or";
+ }
+
+ dr << ' ' << prereqs[i].first;
+ }
+ }
};
// Check the mode options.
@@ -499,6 +570,18 @@ namespace bdep
gopt = mopt;
verify ("--no-open", o.no_open ());
+ // The following option is only meaningful for the revising and tagging
+ // modes.
+ //
+ require_any ("--current-tag", o.current_tag_specified (),
+ {{"--revision", o.revision ()}, {"--tag", o.tag ()}});
+
+ // Specifying --current-tag is meaningless without tagging.
+ //
+ gopt = nullptr;
+ verify ("--current-tag", o.current_tag_specified ());
+ verify ("--no-tag", o.no_tag ());
+
// The following option is only meaningful for the releasing and
// revising modes.
//
@@ -534,8 +617,10 @@ namespace bdep
// Verify the --amend and --squash options.
//
- require ("--amend", o.amend (), "--revision", o.revision ());
- require ("--squash", o.squash_specified (), "--amend", o.amend ());
+ require_any ("--amend", o.amend (), {{"--revision", o.revision ()}});
+
+ require_any ("--squash", o.squash_specified (),
+ {{"--amend", o.amend ()}});
if (o.squash_specified () && o.squash () == 0)
fail << "invalid --squash value: " << o.squash ();
@@ -707,8 +792,10 @@ namespace bdep
// Verify all the packages have the same version. This is the only
// arrangement we currently (and probably ever) support. The immediate
// problem with supporting different versions (besides the extra
- // complexity, of course) is tagging. But since our tags don't include
- // revisions, we do allow variations in that.
+ // complexity, of course) is tagging. We only allow variations in
+ // revisions if the tag doesn't include the revision, which is not the
+ // case when we keep/remove a current tag in the revising and tagging
+ // modes.
//
// While at it, notice if we will end up with different revisions which
// we use below when forming the commit message.
@@ -717,12 +804,16 @@ namespace bdep
{
const package& f (prj.packages.front ());
+ bool ignore_revision (
+ !((o.revision () || o.tag()) &&
+ o.current_tag () != cmd_release_current_tag::update));
+
for (const package& p: prj.packages)
{
const auto& fv (f.current_version);
const auto& pv (p.current_version);
- if (fv.compare (pv, true /* ignore_revision */) != 0)
+ if (fv.compare (pv, ignore_revision) != 0)
{
fail << "different current package versions" <<
info << "package " << f.name << " version " << fv <<
@@ -787,7 +878,21 @@ namespace bdep
dr << " commit: " << (commit ? "yes" : "no") << '\n';
if (!o.open ()) // Does not make sense in the open mode.
- dr << " tag: " << (prj.tag ? prj.tag->c_str () : "no") << '\n';
+ {
+ dr << " tag: " << (prj.tag ? prj.tag->c_str () : "no");
+
+ const optional<project::current_tag>& ct (prj.cur_tag);
+
+ if (ct)
+ {
+ if (ct->action == cmd_release_current_tag::update)
+ dr << " (update)";
+ else if (ct->action == cmd_release_current_tag::remove)
+ dr << " (remove " << ct->name << ')';
+ }
+
+ dr << '\n';
+ }
dr << " push: " << (push ? st.upstream.c_str () : "no");
@@ -1024,13 +1129,20 @@ namespace bdep
//
// Updated tag 'v0.1.0' (was 8f689ec)
//
+ const optional<project::current_tag>& ct (prj.cur_tag);
+
run_git (git_ver,
prj.path,
"tag",
- prj.replace_tag ? "-f" : nullptr,
+ (ct && ct->action == cmd_release_current_tag::update
+ ? "-f"
+ : nullptr),
"-a",
"-m", "Tag version " + cv.string (),
*prj.tag);
+
+ if (ct && ct->action == cmd_release_current_tag::remove)
+ run_git (git_ver, prj.path, "tag", "--delete", ct->name);
}
// Open.
@@ -1074,8 +1186,8 @@ namespace bdep
{
// It would have been nice to push commits and tags using just the
// --follow-tags option. However, this doesn't work if we need to
- // replace the tag in the remote repository. Thus, we specify the
- // repository and refspecs explicitly.
+ // replace or remove the tag in the remote repository. Thus, we specify
+ // the repository and refspecs explicitly.
//
// Upstream is normally in the <remote>/<branch> form, for example
// 'origin/master'.
@@ -1111,23 +1223,37 @@ namespace bdep
}
}
- string tagspec;
+ small_vector<string, 2> tagspecs;
if (prj.tag)
{
- // Force update of the remote tag, if required.
+ // Add the new or update an existing tag.
//
- if (prj.replace_tag)
- tagspec += '+';
+ const optional<project::current_tag>& ct (prj.cur_tag);
+ {
+ string t;
- tagspec += "refs/tags/";
- tagspec += *prj.tag;
+ // Force update of the remote tag, if requested.
+ //
+ if (ct && ct->action == cmd_release_current_tag::update)
+ t += '+';
+
+ t += "refs/tags/";
+ t += *prj.tag;
+
+ tagspecs.push_back (move (t));
+ }
+
+ // Remove the current tag, if requested.
+ //
+ if (ct && ct->action == cmd_release_current_tag::remove)
+ tagspecs.push_back (":refs/tags/" + ct->name);
}
// There should always be something to push, since we are either tagging
// or committing the version change (or both).
//
- assert (!brspec.empty () || !tagspec.empty ());
+ assert (!brspec.empty () || !tagspecs.empty ());
if (*push)
{
@@ -1152,7 +1278,7 @@ namespace bdep
prj.path,
remote,
!brspec.empty () ? brspec.c_str () : nullptr,
- !tagspec.empty () ? tagspec.c_str () : nullptr);
+ tagspecs);
}
else
{
@@ -1182,8 +1308,8 @@ namespace bdep
if (!brspec.empty ())
cout << ' ' << brspec;
- if (!tagspec.empty ())
- cout << ' ' << tagspec;
+ for (const string& t: tagspecs)
+ cout << ' ' << t;
cout << endl;
}
diff --git a/tests/release.testscript b/tests/release.testscript
index 0715280..6aaf5c4 100644
--- a/tests/release.testscript
+++ b/tests/release.testscript
@@ -27,7 +27,8 @@ clone_root_rep = cp --no-cleanup -p -r $~/prj.git ./ &prj.git/***
# Set the origin repository location as a relative path, so we can copy the
# local/remote repository pair into the testscript scopes.
#
-gp = $g -C prj
+gp = $g -C prj
+log = $gp log '--pretty=format:"%d %s"'
+$gp config user.name 'Test Script'
+$gp config user.email 'testscript@example.com'
@@ -51,16 +52,17 @@ release += 2>!
gp2 = $g -C prj2
clone2 = $g clone prj.git prj2 &prj2/***
pull2 = $gp2 pull
+fetch2 = $gp2 fetch
log2 = $gp2 log '--pretty=format:"%d %s"'
: single-pkg
:
{
- test.arguments += --yes
-
: release
:
{
+ test.arguments += --yes
+
: version
:
{
@@ -382,6 +384,13 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
info: use --force=snapshot to tag anyway
EOE
+ # While at it, verify that the --current-tag is forbidden for a
+ # non-revision release.
+ #
+ $* --tag --force=snapshot --current-tag=update 2>>EOE != 0;
+ error: --current-tag specified for non-revision current version 0.2.0-a.0.z
+ EOE
+
$* --tag --force=snapshot 2>>~%EOE%;
%pushing tag v0.2.0-a.0.\.+%d
EOE
@@ -522,35 +531,274 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
test.options += -q
+$clone_root_repos
- +$* --no-open --push
+ +$* --no-open --push --yes
test.arguments += --revision
- : changes-staged
+ : current-tag
:
{
- test.arguments += --push --no-edit
-
+$clone_repos
+echo '' >+ prj/manifest
+$gp add manifest
- : normal
+ test.arguments += --push --no-edit
+
+ : update
:
{
$clone_repos;
+ sp=' ';
+
+ $* --current-tag=update <'y' 2>>~%EOE%;
+ revising:
+ package: prj
+ current: 0.1.0
+ release: 0.1.0+1
+ commit: yes
+ tag: v0.1.0 (update)
+ push: origin/master
+ %continue\? \[y/n\] Updated tag 'v0.1.0' \.+%d
+ EOE
- $* 2>>~%EOE%;
- %Updated tag 'v0.1.0' \(was \.*\)%d
+ test.arguments += --yes;
+
+ $log >>:~%EOO%;
+ % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+1%d
+ Release version 0.1.0
+ Create
+ EOO
+
+ $clone2;
+ $log2 >>:~%EOO%;
+ % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+1%d
+ Release version 0.1.0
+ Create
+ EOO
+
+ $* --current-tag=update --force=unchanged 2>>~%EOE%;
+ %Updated tag 'v0.1.0' \.+%d
+ EOE
+
+ $log >>:~%EOO%;
+ % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+2%d
+ Release version 0.1.0+1
+ Release version 0.1.0
+ Create
+ EOO
+
+ # Updates the existing local tag.
+ #
+ # Note that starting git 2.20.0 --force is also required (see git
+ # release notes for details).
+ #
+ $pull2 --tags --force;
+ $log2 >>:~%EOO%
+ % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+2%d
+ Release version 0.1.0+1
+ Release version 0.1.0
+ Create
+ EOO
+ }
+
+ : remove
+ :
+ {
+ $clone_repos;
+
+ $* --current-tag=remove <'y' 2>>~%EOE%;
+ revising:
+ package: prj
+ current: 0.1.0
+ release: 0.1.0+1
+ commit: yes
+ tag: v0.1.0+1 (remove v0.1.0)
+ push: origin/master
+ %continue\? \[y/n\] Deleted tag 'v0.1.0' \.+%d
EOE
+ test.arguments += --yes;
+
+ $log >>:~%EOO%;
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ Release version 0.1.0
+ Create
+ EOO
+
+ $* --current-tag=remove --force=unchanged 2>>~%EOE%;
+ %Deleted tag 'v0.1.0\+1' \.+%d
+ EOE
+
+ $log >>:~%EOO%;
+ % \(HEAD -> master, tag: v0.1.0\+2, \.*\) Release version 0.1.0\+2%d
+ Release version 0.1.0+1
+ Release version 0.1.0
+ Create
+ EOO
+
+ $clone2;
+ $log2 >>:~%EOO%
+ % \(HEAD -> master, tag: v0.1.0\+2, \.*\) Release version 0.1.0\+2%d
+ Release version 0.1.0+1
+ Release version 0.1.0
+ Create
+ EOO
+ }
+
+ : keep
+ :
+ {
+ $clone_repos;
+ sp = ' ';
+
+ $* --current-tag=keep <'y' 2>>:"EOE";
+ revising:
+ package: prj
+ current: 0.1.0
+ release: 0.1.0+1
+ commit: yes
+ tag: v0.1.0+1
+ push: origin/master
+ continue? [y/n]$sp
+ EOE
+
+ test.arguments += --yes;
+
+ $log >>:~%EOO%;
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ (tag: v0.1.0) Release version 0.1.0
+ Create
+ EOO
+
+ $* --current-tag=keep --force=unchanged;
+
+ $log >>:~%EOO%;
+ % \(HEAD -> master, tag: v0.1.0\+2, \.*\) Release version 0.1.0\+2%d
+ (tag: v0.1.0+1) Release version 0.1.0+1
+ (tag: v0.1.0) Release version 0.1.0
+ Create
+ EOO
+
$clone2;
$log2 >>:~%EOO%
+ % \(HEAD -> master, tag: v0.1.0\+2, \.*\) Release version 0.1.0\+2%d
+ (tag: v0.1.0+1) Release version 0.1.0+1
+ (tag: v0.1.0) Release version 0.1.0
+ Create
+ EOO
+ }
+ }
+
+ : tag
+ :
+ {
+ +$clone_repos
+
+ test.arguments += --push --no-edit --force=unchanged --yes
+
+ +$* --no-tag
+
+ +$clone2
+ +$log2 >>:~%EOO%
+ % \(HEAD -> master, origin/master, \.*\) Release version 0.1.0\+1%d
+ (tag: v0.1.0) Release version 0.1.0
+ Create
+ EOO
+
+ tag = $release --tag --push -q --yes -d prj/prj
+
+ : update
+ :
+ {
+ $clone_repos;
+
+ $tag --current-tag=update 2>>~%EOE%;
+ %Updated tag 'v0.1.0' \.+%d
+ EOE
+
+ $log >>:~%EOO%;
% \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+1%d
Release version 0.1.0
Create
EOO
+
+ $clone2;
+ $log2 >>:~%EOO%
+ % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+1%d
+ Release version 0.1.0
+ Create
+ EOO
+ }
+
+ : remove
+ :
+ {
+ $clone_repos;
+
+ $tag --current-tag=remove 2>>~%EOE%;
+ %Deleted tag 'v0.1.0' \.+%d
+ EOE
+
+ $log >>:~%EOO%;
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ Release version 0.1.0
+ Create
+ EOO
+
+ $clone2;
+ $log2 >>:~%EOO%
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ Release version 0.1.0
+ Create
+ EOO
+ }
+
+ : keep
+ :
+ {
+ $clone_repos;
+
+ $tag --current-tag=keep;
+
+ $log >>:~%EOO%;
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ (tag: v0.1.0) Release version 0.1.0
+ Create
+ EOO
+
+ $clone2;
+ $log2 >>:~%EOO%
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ (tag: v0.1.0) Release version 0.1.0
+ Create
+ EOO
+ }
+ }
+
+ : changes-staged
+ :
+ {
+ test.arguments += --push --no-edit --yes
+
+ +$clone_repos
+
+ +echo '' >+ prj/manifest
+ +$gp add manifest
+
+ : normal
+ :
+ {
+ $clone_repos;
+
+ $*;
+
+ $clone2;
+ $log2 >>:~%EOO%
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ (tag: v0.1.0) Release version 0.1.0
+ Create
+ EOO
}
: stub
@@ -565,7 +813,7 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
$clone2;
$log2 >>:~%EOO%
- % \(HEAD -> master, tag: v0, \.*\) Release version 0\+1%d
+ % \(HEAD -> master, tag: v0\+1, \.*\) Release version 0\+1%d
Create
EOO
}
@@ -586,15 +834,10 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
$release --tag --push --yes -d prj;
- # Updates the existing local tag.
- #
- # Note that starting git 2.20.0 --force is also required (see git
- # release notes for details).
- #
- $pull2 --tags --force;
+ $pull2 --tags --force; # Updates the existing local tag (see above).
$log2 >>:~%EOO%
- % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+1%d
- Release version 0.1.0
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ (tag: v0.1.0) Release version 0.1.0
Create
EOO
}
@@ -603,7 +846,7 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
: no-changes-staged
:
{
- test.arguments += --push
+ test.arguments += --push --yes
$clone_repos;
@@ -613,14 +856,12 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
info: use --force=unchanged to release anyway
EOE
- $* --force=unchanged 2>>~%EOE%;
- %Updated tag 'v0.1.0' \(was \.*\)%d
- EOE
+ $* --force=unchanged;
$clone2;
$log2 >>:~%EOO%
- % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+1%d
- Release version 0.1.0
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ (tag: v0.1.0) Release version 0.1.0
Create
EOO
}
@@ -628,6 +869,8 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
: unstaged
:
{
+ test.arguments += --yes;
+
$clone_repos;
echo '' >+ prj/manifest;
@@ -646,8 +889,8 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
$clone2;
$log2 >>:~%EOO%
- % \(HEAD -> master, tag: v0.1.0, \.*\) Release revision%d
- Release version 0.1.0
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release revision%d
+ (tag: v0.1.0) Release version 0.1.0
Create
EOO
}
@@ -655,7 +898,7 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
: amend
:
{
- test.arguments += --push --amend --no-edit
+ test.arguments += --push --amend --no-edit --yes
+$clone_repos
@@ -673,15 +916,13 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
{
$clone_repos;
- $* 2>>~%EOE%;
- %Updated tag 'v0.1.0' \(was \.*\)%d
- EOE
+ $*;
$clone2;
$log2 >>:~%EOO%;
- % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+1%d
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
Fix repositories.manifest
- Release version 0.1.0
+ (tag: v0.1.0) Release version 0.1.0
Create
EOO
@@ -705,14 +946,12 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
{
$clone_repos;
- $* --squash 2 2>>~%EOE%;
- %Updated tag 'v0.1.0' \(was \.*\)%d
- EOE
+ $* --squash 2;
$clone2;
$log2 >>:~%EOO%;
- % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+1%d
- Release version 0.1.0
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
+ (tag: v0.1.0) Release version 0.1.0
Create
EOO
@@ -738,16 +977,14 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
$gp commit -a -m 'Change manifest';
- $* 2>>~%EOE%;
- %Updated tag 'v0.1.0' \(was \.*\)%d
- EOE
+ $*;
$clone2;
$log2 >>:~%EOO%;
- % \(HEAD -> master, tag: v0.1.0, \.*\) Release version 0.1.0\+1%d
+ % \(HEAD -> master, tag: v0.1.0\+1, \.*\) Release version 0.1.0\+1%d
Fix buildfile
Fix repositories.manifest
- Release version 0.1.0
+ (tag: v0.1.0) Release version 0.1.0
Create
EOO
@@ -774,7 +1011,8 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
: open
:
{
- test.options += -q
+ test.options += -q
+ test.arguments += --yes
: unstaged
:
@@ -809,6 +1047,8 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
: no-commit
:
{
+ test.arguments += --yes
+
$clone_root_repos;
$* --no-commit;
@@ -837,6 +1077,8 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
: no-progress
:
{
+ test.arguments += --yes
+
$clone_root_repos;
$* --push --no-progress 2>>~%EOE%;
@@ -921,7 +1163,7 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
echo '' >+ prj/prj/manifest;
$gp add prj/manifest;
- $release --revision -q --yes --no-edit -d prj/prj;
+ $release --revision --current-tag=update -q --yes --no-edit -d prj/prj;
echo '' >+ prj/prj/manifest;
$gp add prj/manifest;
@@ -929,10 +1171,18 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
echo '' >+ prj/libprj/manifest;
$gp add libprj/manifest;
- $* --revision --no-edit 2>>~%EOE%;
- %Updated tag 'v0.1.0' \(was \.*\)%d
+ $* --revision --no-edit 2>>EOE != 0;
+ error: different current package versions
+ info: package prj version 0.1.0+1
+ info: package libprj version 0.1.0
+ EOE
+
+ $* --revision --current-tag=update --no-edit 2>>~%EOE%;
+ %Updated tag 'v0.1.0' \.+%d
EOE
+ # Note that the 0.1.0+1 release is not tagged as it wasn't pushed.
+ #
$clone2;
$log2 >>:~%EOO%
% \(HEAD -> master, tag: v0.1.0, \.*\) Release versions prj/0.1.0\+2, libprj/0.1.0\+1%d
@@ -946,7 +1196,7 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
:
{
+$clone_repos
- sp=' '
+ sp = ' '
: default
:
@@ -1011,9 +1261,11 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
: show-push
:
{
+ test.arguments += --show-push
+
$clone_repos;
- $* --show-push <'y' 2>>:"EOE" >>~%EOO%;
+ $* <'y' 2>>:"EOE" >>~%EOO%;
releasing:
package: prj
current: 0.1.0-a.0.z
@@ -1042,7 +1294,7 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
Create
EOO
- $* --no-tag --no-open --show-push --yes >>~%EOO%;
+ $* --no-tag --no-open --yes >>~%EOO%;
%git -C "?.+prj"? push origin master%
EOO
@@ -1056,19 +1308,37 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
Create
EOO
- $* --tag --show-push --yes >>~%EOO%;
+ $* --tag --yes >>~%EOO%;
%git -C "?\.+prj"? push origin refs/tags/v0.2.0%d
EOO
$gp push origin refs/tags/v0.2.0;
$pull2 --tags --force; # Updates the existing local tag (see above).
- $log2 >>:~%EOO%
+ $log2 >>:~%EOO%;
% \(HEAD -> master, tag: v0.2.0, \.*\) Release version 0.2.0%d
Change version to 0.2.0-a.0.z
(tag: v0.1.0) Release version 0.1.0
Create
EOO
+
+ $* --revision --current-tag=remove --force=unchanged --yes >>~%EOO% 2>>~%EOE%;
+ %git -C "?\.+prj"? push origin master refs/tags/v0.2.0\+1 :refs/tags/v0.2.0%d
+ EOO
+ %Deleted tag 'v0.2.0' \.+%d
+ EOE
+
+ $gp push origin master refs/tags/v0.2.0+1 ':refs/tags/v0.2.0';
+
+ $fetch2 --prune origin '+refs/tags/*:refs/tags/*';
+ $pull2 --tags;
+ $log2 >>:~%EOO%
+ % \(HEAD -> master, tag: v0.2.0\+1, \.*\) Release version 0.2.0\+1%d
+ Release version 0.2.0
+ Change version to 0.2.0-a.0.z
+ (tag: v0.1.0) Release version 0.1.0
+ Create
+ EOO
}
: no-tag
@@ -1122,22 +1392,22 @@ log2 = $gp2 log '--pretty=format:"%d %s"'
: options-incompatibility
:
{
- $clone_prj;
-
- $* --revision --open 2>'error: both --revision and --open specified' != 0;
- $* --revision --alpha 2>'error: both --revision and --alpha specified' != 0;
- $* --revision --no-open 2>'error: both --revision and --no-open specified' != 0;
- $* --revision --open-beta 2>'error: both --revision and --open-beta specified' != 0;
- $* --open --no-tag 2>'error: both --open and --no-tag specified' != 0;
- $* --tag --no-commit 2>'error: both --tag and --no-commit specified' != 0;
- $* --push --no-commit 2>'error: both --push and --no-commit specified' != 0;
- $* --push --show-push 2>'error: both --push and --show-push specified' != 0;
- $* --edit --no-commit 2>'error: both --no-commit and --edit specified' != 0;
-
- $* --open-base 1.2.3 --open-beta 2>'error: both --open-beta and --open-base specified' != 0;
-
- $* --amend 2>'error: --amend requires --revision' != 0;
- $* --squash 1 2>'error: --squash requires --amend' != 0;
- $* --revision --amend --squash 0 2>'error: invalid --squash value: 0' != 0;
- $* --revision --amend --no-commit 2>'error: both --amend and --no-commit specified' != 0
+ +$clone_prj
+
+ $* --revision --open 2>'error: both --revision and --open specified' != 0
+ $* --revision --alpha 2>'error: both --revision and --alpha specified' != 0
+ $* --revision --no-open 2>'error: both --revision and --no-open specified' != 0
+ $* --revision --open-beta 2>'error: both --revision and --open-beta specified' != 0
+ $* --open --no-tag 2>'error: both --open and --no-tag specified' != 0
+ $* --tag --no-commit 2>'error: both --tag and --no-commit specified' != 0
+ $* --push --no-commit 2>'error: both --push and --no-commit specified' != 0
+ $* --push --show-push 2>'error: both --push and --show-push specified' != 0
+ $* --edit --no-commit 2>'error: both --no-commit and --edit specified' != 0
+ $* --current-tag=keep 2>'error: --current-tag requires --revision or --tag' != 0
+ $* --revision --current-tag keep --no-tag 2>'error: both --current-tag and --no-tag specified' != 0
+ $* --open-base 1.2.3 --open-beta 2>'error: both --open-beta and --open-base specified' != 0
+ $* --amend 2>'error: --amend requires --revision' != 0
+ $* --squash 1 2>'error: --squash requires --amend' != 0
+ $* --revision --amend --squash 0 2>'error: invalid --squash value: 0' != 0
+ $* --revision --amend --no-commit 2>'error: both --amend and --no-commit specified' != 0
}