Skip to content

tools: add repo-version to print a package version from git references#1009

Open
illwieckz wants to merge 1 commit intomasterfrom
illwieckz/git-version/sync
Open

tools: add repo-version to print a package version from git references#1009
illwieckz wants to merge 1 commit intomasterfrom
illwieckz/git-version/sync

Conversation

@illwieckz
Copy link
Copy Markdown
Member

@illwieckz illwieckz commented Jan 2, 2024

This is an extraction and a port to Python of the printVersion function from the release-scripts/build-release script, the produced version string is usable for dpk archives, but also fr other things like unizip or the symbols zip for which we expect to have the same version string of the game dpk.

This is a standalone re-implementation of what is done in Urcheon for computing dpk version strings.

This is usable in two ways:

Without argument:

tools/repo-version/repo-version

This prints the version string for the current directory.

With argument:

tools/repo-version/repo-version 'path/to/some/other/repository'

This prints the version string for the given repository path passed as argument.

This script is stored in Dæmon repository because I want a common place for it. We may even use it when doing nightly builds of the engine only, or things like that.

@slipher
Copy link
Copy Markdown
Member

slipher commented Jan 2, 2024

Without argument:

tools/git-version/git-version

This prints the version string for the repository the script is stored,

With argument:

tools/git-version/git-version 'path/to/some/other/repository'

This prints the version string for the given repository path passed as argument.

I would find the no-argument behavior surprising, expecting it to use the current directory rather than Daemon's directory.

@illwieckz
Copy link
Copy Markdown
Member Author

I would find the no-argument behavior surprising, expecting it to use the current directory rather than Daemon's directory.

Hmm, right, this would also remove the need for a wrapper in Unvanquished repo.

@illwieckz illwieckz force-pushed the illwieckz/git-version/sync branch from 09fe590 to f0ede7a Compare April 6, 2024 17:47
@illwieckz
Copy link
Copy Markdown
Member Author

I would find the no-argument behavior surprising, expecting it to use the current directory rather than Daemon's directory.

Now using the current directory.

@illwieckz illwieckz force-pushed the illwieckz/git-version/sync branch from f0ede7a to f7420aa Compare April 6, 2024 18:00
@illwieckz illwieckz changed the title tools: add git-version to print a package version from git references tools: add repo-version to print a package version from git references Apr 7, 2024
@illwieckz illwieckz force-pushed the illwieckz/git-version/sync branch 2 times, most recently from 9c2562c to 7ab89e6 Compare April 7, 2024 01:46
@illwieckz
Copy link
Copy Markdown
Member Author

illwieckz commented Apr 7, 2024

My original code was purposed to also handles the cases when:

  • the directory is not a Git repository yet
  • there is no commit yet
  • there is no tag yet

And to provide fallbacks to them.

The reason why I want that is that such permissivity is useful in Urcheon, and at some point I want this code to be exactly the same in Urcheon (I'll replace current Urcheon version code with this one, as it is more mature and less convoluted).

So I finally made the script erroring on Git errors, and made it not sending Git error message to /dev/null, by default. But I also added options to ignore and silence errors, so I can merge this back in Urcheon later.

We may want to check for the directory always being a repository in the Unvanquished release script, so having this code aborting on error and printing errors is fine. Same if one day we wire it into cmake to embed the result as internal game version string.


parser = argparse.ArgumentParser(description="Print repository version string")

parser.add_argument("-p", "--permissive", dest="is_permissive", help="ignore Git errors", action="store_true")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would you want to ignore/silence Git errors? It would seem the script can't do anything useful if Git doesn't work.

Copy link
Copy Markdown
Member Author

@illwieckz illwieckz Apr 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Git doesn't work, and if the script is allowed to continue, it produces a version string using current date with same syntax (using 0 as fallback tag and commit).

By using similar code in Urcheon I can generate versioned dpkdir of a work-in-progress folder even before committing the very first changes, and the fallback version string is compatible with what will be produced once there is a git repository, and once there is a git tag.

Example:

  • 0-20240408-050944+dirty: not a git repository yet, or git repository but no commit yet (date is world date).
  • 0-20240408-051101-2bdab49: git repository with committed data but not tag (date is latest commit date).
  • 0-20240408-051101-2bdab49+dirty: git repository with committed data but not tag, with uncommitted change (date is latest commit date).
  • 0.54.1: git repository, tag is current commit.
  • 0.54.1+dirty: git repository, tag is current commit, with uncommitted change.
  • 0.54.1-20240408-051101-2bdab49: git repository, untagged commits since latest tag (date is latest commit date).
  • 0.54.1-20240408-051101-2bdab49+dirty: git repository, untagged commits since latest tag, with uncommitted change (date is latest commit date).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to mention that “Git not working“ is assumed to mean “This directory is not a git repository”, not that Git is not installed. I may add a dedicated check for when Git is not installed at all (like by calling git -v).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script now tests if Git is available and working. The --permissive option can only continue on the fallback compute if Git is failing because the directory is not a git repository yet (the reason why there is a fallback).

@illwieckz illwieckz changed the title tools: add repo-version to print a package version from git references tools: add dir-version to print a package version from git references Apr 8, 2024
@illwieckz illwieckz force-pushed the illwieckz/git-version/sync branch 3 times, most recently from 0c435e4 to 480e4bd Compare April 8, 2024 07:59
@illwieckz
Copy link
Copy Markdown
Member Author

illwieckz commented Apr 8, 2024

I renamed the tool to dir-version, because it prints a version string for a given directory, either being a git repository or not, either being a subdir of the repository or not.

I finally ported and improved the complete dirt detection code from Urcheon.

  • It reports the version as dirty if there are uncommitted and untracked files in the directory.
  • It doesn't report the version as dirty if the modified file is outside of the directory the script is computing a version from, even if the directory is from the same git repository.

The second feature means doing this dir-version Unvanquished/pkg/unvanquished_src.dpkdir doesn't report the version as dirty if there is a change outside of this directory, despite this directory being part of the same Unvanquished/ repository.

I added a --whole option to force looking for dirt in the whole repository the directory is part of. For example that will report dirt from Unvanquished/src and other places fromUnvanquished when doing dir-version Unvanquished/pkg/unvanquished_src.dpkdir.

@illwieckz illwieckz force-pushed the illwieckz/git-version/sync branch 2 times, most recently from 052017d to 8136de3 Compare April 8, 2024 08:40
def isDirtyGit(self):
if self.is_whole:
# Git prints the Git repository root directory.
git_show_toplevel_string, git_show_toplevel_returncode = \
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be easier to omit the git diff final argument instead of having to look up the repository root?


parser.add_argument("-p", "--permissive", dest="is_permissive", help="ignore Git errors", action="store_true")
parser.add_argument("-q", "--quiet", dest="is_quiet", help="silence Git errors", action="store_true")
parser.add_argument("-w", "--whole", dest="is_whole", help="look for dirt in whole repository", action="store_true")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is a bad default to depend on the current directory within the repository. What is the use case for that anyway?

Copy link
Copy Markdown
Member Author

@illwieckz illwieckz Apr 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use case: https://github.com/UnvanquishedAssets/UnvanquishedTestAssets/tree/master/pkg

I can make it non-default, but I need the feature to be there.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, please make it non-default. The subdirectory use case seems second-class because tags are only made at the whole-repository scope, so it may be common to have different tags with identical content.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavior is reversed. By default it now uses the whole repository for computing dirtiness, but can only look for subdirectory dirtiness when using --local.

I'm not very happy with the local name, but current would be confusing as it may give the false idea it's for the folder the script is called from, not the given folder on command line. Suggestions welcome.

@@ -0,0 +1,151 @@
#! /usr/bin/env python3
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@illwieckz illwieckz force-pushed the illwieckz/git-version/sync branch from 8136de3 to e590eff Compare April 9, 2024 05:45
@illwieckz
Copy link
Copy Markdown
Member Author

Some things I'm still thinking about:

  • I'm not entirely happy with the name, I may rename it git-dir-version/GitDirVersion.

I'm not happy with the original git-version/GitVersion because it was confusing it may provide the version of Git itself, but I'm not happy with repo-version/RepoVersion or dir-version/DirVersion because this is a tool to compute a Git-based version (with a non-Git optional fallback) for a source directory. Git is always required even when the directory is not tracked by Git (to know it's not tracked by Git).

  • I will probably implement the integration of this new lib in some Urcheon branch before merging it there to make sure it works in Urcheon too to avoid some back and forth merge roundtrips.

  • I may add an option to provide a custom/explicit Git binary path (may be useful when integrating things like CMake to make sure we use the same Git CMake uses).

@slipher
Copy link
Copy Markdown
Member

slipher commented Apr 9, 2024

I would name the tool version-string

@illwieckz illwieckz force-pushed the illwieckz/git-version/sync branch 3 times, most recently from 373ac19 to 38d7a7b Compare April 8, 2026 17:03
@illwieckz
Copy link
Copy Markdown
Member Author

I would name the tool version-string

Now renamed version-string.

@illwieckz illwieckz changed the title tools: add dir-version to print a package version from git references tools: add version-string to print a package version from git references Apr 8, 2026
@illwieckz
Copy link
Copy Markdown
Member Author

Well, in fact I dislike version-string, as it doesn't tell the version string of what.

Actually my initial name of repo-version wasn't bad.

@illwieckz illwieckz force-pushed the illwieckz/git-version/sync branch from 38d7a7b to 817f6cf Compare April 8, 2026 17:24
@illwieckz illwieckz changed the title tools: add version-string to print a package version from git references tools: add repo-version to print a package version from git references Apr 8, 2026
@illwieckz
Copy link
Copy Markdown
Member Author

I renamed it repo-version back.

@illwieckz illwieckz force-pushed the illwieckz/git-version/sync branch 7 times, most recently from 59e11e9 to f983698 Compare April 8, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants