Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,28 @@ jobs:
- run: cmake --build build --target check
- run: sudo cmake --install build

clang_format:
name: clang-format
c_format:
name: C format
runs-on: ubuntu-22.04
steps:
- run: uname -rms
- run: echo "cloning ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}"
- run: git clone --no-checkout -- ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} wd
- run: cd wd && git fetch -- origin ${{ github.event.pull_request.head.sha }} && git checkout FETCH_HEAD
- run: cd wd && git ls-files -z '**/*.c' '**/*.h' | xargs -0 -- clang-format-15 --dry-run --style=file --Werror

py_format:
name: Python format
runs-on: ubuntu-22.04
env:
DEBIAN_FRONTEND: noninteractive
steps:
- run: uname -rms
- run: python3 --version
- run: sudo apt-get update
- run: sudo apt-get install --no-install-recommends -y black python3-isort
- run: echo "cloning ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}"
- run: git clone --no-checkout -- ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} wd
- run: cd wd && git fetch -- origin ${{ github.event.pull_request.head.sha }} && git checkout FETCH_HEAD
- run: cd wd && git ls-files -z '**/*.py' | xargs -0 -- python3 -m black --check --
- run: cd wd && git ls-files -z '**/*.py' | xargs -0 -- python3 -m isort --profile=black --check --
202 changes: 110 additions & 92 deletions libvimcat/src/make-version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,125 +5,142 @@
"""

import os
from pathlib import Path
import re
import shutil
import subprocess as sp
import sys
from pathlib import Path
from typing import Iterator, Optional


def all_versions() -> Iterator[str]:
"""
All known versions in the CHANGELOG.rst.
"""
with open(Path(__file__).parent / "../../CHANGELOG.rst", "rt") as f:
for line in f:
m = re.match(r"(v\d{4}\.\d{2}\.\d{2})$", line)
if m is not None:
yield m.group(1)
"""
All known versions in the CHANGELOG.rst.
"""
with open(
Path(__file__).parent / "../../CHANGELOG.rst", "rt", encoding="utf-8"
) as f:
for line in f:
m = re.match(r"(v\d{4}\.\d{2}\.\d{2})$", line)
if m is not None:
yield m.group(1)


def last_release() -> str:
"""
The version of the last release. This will be used as the version number if no
Git information is available.
"""
for version in all_versions():
return version
"""
The version of the last release. This will be used as the version number if no
Git information is available.
"""
for version in all_versions():
return version

return "<unknown>"

return "<unknown>"

def has_git() -> bool:
"""
Return True if we are in a Git repository and have Git.
"""
"""
Return True if we are in a Git repository and have Git.
"""

# return False if we don't have Git
if shutil.which("git") is None:
return False

# return False if we don't have Git
if shutil.which("git") is None:
return False
# return False if we have no Git repository information
if not (Path(__file__).parent / "../../.git").exists():
return False

# return False if we have no Git repository information
if not (Path(__file__).parent / "../../.git").exists():
return False
return True

return True

def get_tag() -> Optional[str]:
"""
Find the version tag of the current Git commit, e.g. v2020.05.03, if it
exists.
"""
try:
tag = sp.check_output(["git", "describe", "--tags"], stderr=sp.DEVNULL)
except sp.CalledProcessError:
tag = None

if tag is not None:
tag = tag.decode("utf-8", "replace").strip()
if re.match(r"v[\d\.]+$", tag) is None:
# not a version tag
tag = None

return tag
"""
Find the version tag of the current Git commit, e.g. v2020.05.03, if it
exists.
"""
try:
tag = sp.check_output(["git", "describe", "--tags"], stderr=sp.DEVNULL)
except sp.CalledProcessError:
tag = None

def get_sha() -> str:
"""
Find the hash of the current Git commit.
"""
rev = sp.check_output(["git", "rev-parse", "--verify", "HEAD"])
rev = rev.decode("utf-8", "replace").strip()
if tag is not None:
tag = tag.decode("utf-8", "replace").strip()
if re.match(r"v[\d\.]+$", tag) is None:
# not a version tag
tag = None

return rev
return tag

def is_dirty() -> bool:
"""
Determine whether the current working directory has uncommitted changes.
"""
dirty = False

p = sp.run(["git", "diff", "--exit-code"], stdout=sp.DEVNULL,
stderr=sp.DEVNULL)
dirty |= p.returncode != 0
def get_sha() -> str:
"""
Find the hash of the current Git commit.
"""
rev = sp.check_output(["git", "rev-parse", "--verify", "HEAD"])
rev = rev.decode("utf-8", "replace").strip()

return rev

p = sp.run(["git", "diff", "--cached", "--exit-code"], stdout=sp.DEVNULL,
stderr=sp.DEVNULL)
dirty |= p.returncode != 0

return dirty
def is_dirty() -> bool:
"""
Determine whether the current working directory has uncommitted changes.
"""
dirty = False

p = sp.run(
["git", "diff", "--exit-code"],
stdout=sp.DEVNULL,
stderr=sp.DEVNULL,
check=False,
)
dirty |= p.returncode != 0

p = sp.run(
["git", "diff", "--cached", "--exit-code"],
stdout=sp.DEVNULL,
stderr=sp.DEVNULL,
check=False,
)
dirty |= p.returncode != 0

return dirty


def main(args: [str]) -> int:

if len(args) != 2 or args[1] == "--help":
sys.stderr.write(
f"usage: {args[0]} file\n"
" write version information as a C source file\n")
return -1
if len(args) != 2 or args[1] == "--help":
sys.stderr.write(
f"usage: {args[0]} file\n" " write version information as a C source file\n"
)
return -1

# get the contents of the old version file if it exists
old = None
if os.path.exists(args[1]):
old = Path(args[1]).read_text()
# get the contents of the old version file if it exists
old = None
if os.path.exists(args[1]):
old = Path(args[1]).read_text(encoding="utf-8")

version = None
version = None

# look for a version tag on the current commit
if version is None and has_git():
tag = get_tag()
if tag is not None:
version = f'{tag}{" (dirty)" if is_dirty() else ""}'
# look for a version tag on the current commit
if version is None and has_git():
tag = get_tag()
if tag is not None:
version = f'{tag}{" (dirty)" if is_dirty() else ""}'

# look for the commit hash as the version
if version is None and has_git():
rev = get_sha()
assert rev is not None
version = f'Git commit {rev}{" (dirty)" if is_dirty() else ""}'
# look for the commit hash as the version
if version is None and has_git():
rev = get_sha()
assert rev is not None
version = f'Git commit {rev}{" (dirty)" if is_dirty() else ""}'

# fall back to our known release version
if version is None:
version = last_release()
# fall back to our known release version
if version is None:
version = last_release()

known_versions = ", ".join(f'"{v}"' for v in reversed(list(all_versions())))
known_versions = ", ".join(f'"{v}"' for v in reversed(list(all_versions())))

new = f"""\
new = f"""\
#include <stddef.h>
#include <vimcat/version.h>

Expand All @@ -145,12 +162,13 @@ def main(args: [str]) -> int:
sizeof(KNOWN_VERSIONS) / sizeof(KNOWN_VERSIONS[0]);
"""

# If the version has changed, update the output. Otherwise we leave the old
# contents – and more importantly, the timestamp – intact.
if old != new:
Path(args[1]).write_text(new)
# If the version has changed, update the output. Otherwise we leave the old
# contents – and more importantly, the timestamp – intact.
if old != new:
Path(args[1]).write_text(new, encoding="utf-8")

return 0

return 0

if __name__ == "__main__":
sys.exit(main(sys.argv))
sys.exit(main(sys.argv))
Loading