hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 3795ae86f2cf9d5486bf810e607d7114a9dde055
parent 41833914308655b88bcb726d42772bcb9cbb8ff7
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon, 22 Nov 2021 09:32:09 +0100

hare release: implement initial release

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mcmd/hare/release.ha | 51+++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 45 insertions(+), 6 deletions(-)

diff --git a/cmd/hare/release.ha b/cmd/hare/release.ha @@ -37,6 +37,16 @@ const changelog_template: str = "# This is the changelog for your release. It ha {} version {} "; +const initial_template: str = " +# These are the release notes for the initial release of {0}. +# +# Any lines which begin with \"#\", like this one, are for your information +# only, and will be removed from the final release notes. Edit this file to your +# satisfaction, then save and close your editor. +# +{0} version {1} +"; + fn parseversion(in: str) (modversion | badversion) = { const items = strings::split(in, "."); defer free(items); @@ -71,13 +81,10 @@ fn do_release( git_runcmd("fetch")?; checkbehind()?; - const key = choosekey()?; - defer free(key); - // TODO: Detect if distance from the last tag is zero commits const lasttag = match (git_readcmd("describe", "--abbrev=0")) { case git_error => - return do_initial_release(); + return do_initial_release(next); case err: release_error => return err; case s: str => @@ -85,6 +92,9 @@ fn do_release( }; defer free(lasttag); + const key = choosekey()?; + defer free(key); + const current = parseversion(lasttag)?; const new = nextversion(current, next); const newtag = fmt::asprintf("{}.{}.{}", new.0, new.1, new.2); @@ -97,6 +107,8 @@ fn do_release( defer os::rmdirall(dir)!; const changelog = temp::named(os::cwd, dir, io::mode::WRITE)?; const clfile = changelog.0, changelog = changelog.1; + defer io::close(clfile); + defer os::remove(changelog)!; fmt::fprintfln(clfile, changelog_template, lasttag, name, newtag)?; shortlog(clfile, range)?; @@ -107,8 +119,35 @@ fn do_release( name, newtag)!; }; -fn do_initial_release() (void | release_error) = { - fmt::fatal("TODO: Tag initial release"); +fn do_initial_release(ver: (modversion | increment)) (void | release_error) = { + const ver = match (ver) { + case ver: modversion => + yield ver; + case increment => + fmt::errorln("Error: cannot increment version number without a previous version to reference.")!; + fmt::errorln("For the first release, try 'hare release 1.0.0' instead.")!; + os::exit(1); + }; + + const key = choosekey()?; + defer free(key); + const newtag = fmt::asprintf("{}.{}.{}", ver.0, ver.1, ver.2); + defer free(newtag); + + const name = path::basename(os::getcwd()); + const dir = temp::dir(); + defer os::rmdirall(dir)!; + const changelog = temp::named(os::cwd, dir, io::mode::WRITE)?; + const clfile = changelog.0, changelog = changelog.1; + defer io::close(clfile); + defer os::remove(changelog)!; + fmt::fprintfln(clfile, initial_template, name, newtag)?; + + git_runcmd("tag", "-aeF", changelog, newtag)?; + signtag(name, newtag, key)?; + fmt::printfln("Tagged {} version {}. " + "Use 'git push --follow-tags' to publish the new release.", + name, newtag)!; }; fn nextversion(