re-org section placement; minor test name fixups after renames
What changed, and why it matters
This commit simply moves a block of existing code (the git shell command helpers) to a different location in the same file and renames a couple of test methods. No behavior changes, no security fixes, and no new vulnerabilities are introduced.
No action required; this is a non-functional refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff is a pure refactor: the VersionUtils git-shell methods are relocated earlier in src/seedsigner/helpers/version.py, and the corresponding test class TestVersionUtils_GitShell is relocated earlier in tests/test_version.py. One test is renamed from test__get_version_name_from_env_var to test__get_version_name_from_seedsigner_os_env_var, and another from test__get_short_commit_hash_from_git_shell to test__get_full_commit_hash_from_git_shell to match the actual method name. Logic, decorators (@not_allowed_in_seedsigner_os), and command strings are unchanged.
Changed components
src/seedsigner/helpers/version.pytests/test_version.pyInspect captured patch +188 / −186
diff --git a/src/seedsigner/helpers/version.py b/src/seedsigner/helpers/version.py
index 967f284..20335a5 100644
--- a/src/seedsigner/helpers/version.py
+++ b/src/seedsigner/helpers/version.py
@@ -427,6 +427,72 @@ class VersionUtils:
+ """ *************************************************************************************
+ Get data via shell `git` commands.
+
+ These calls shouldn't be dangerous, but we definitely don't want them being run in
+ SeedSigner OS regardless so we apply the decorator restriction.
+ ************************************************************************************* """
+ @classmethod
+ @not_allowed_in_seedsigner_os
+ def _get_version_name_from_git_shell_branch(cls) -> str | None:
+ branch_name = os.popen("git branch --show-current 2> /dev/null").read()
+ return branch_name.strip() if branch_name else None
+
+
+ @classmethod
+ @not_allowed_in_seedsigner_os
+ def _get_version_name_from_git_shell_tag(cls) -> str | None:
+ # Only return a value if the current commit exactly corresponds with a tag.
+ # (`--points-at` defaults to the current HEAD)
+ tag_name = os.popen(f"git tag --points-at 2> /dev/null").read()
+ return tag_name.strip() if tag_name else None
+
+
+ @classmethod
+ @not_allowed_in_seedsigner_os
+ def _get_full_commit_hash_from_git_shell(cls) -> str | None:
+ """
+ Attempts to get the current git commit hash via shell `git` commands.
+ """
+ commit_hash = os.popen("git rev-parse HEAD").read()
+ return commit_hash.strip() if commit_hash else None
+
+
+ @classmethod
+ @not_allowed_in_seedsigner_os
+ def _get_version_name_from_git_shell(cls) -> str | None:
+ """
+ Attempts to get the version name via shell `git` commands.
+ """
+ return (
+ cls._get_version_name_from_git_shell_branch() or
+ cls._get_version_name_from_git_shell_tag() or
+ cls._get_full_commit_hash_from_git_shell()
+ )
+
+
+ @classmethod
+ @not_allowed_in_seedsigner_os
+ def _get_version_fork_from_git_shell(cls) -> str | None:
+ """
+ Attempts to get the fork owner name via shell `git` commands.
+ """
+ # We expect to at least have a remote named "origin"
+ remote_url = os.popen("git remote get-url origin 2> /dev/null").read().strip()
+ return cls._parse_git_remote_url(remote_url) if remote_url else None
+
+
+ @classmethod
+ @not_allowed_in_seedsigner_os
+ def _get_version_timestamp_from_git_shell(cls) -> datetime | None:
+ version_timestamp = os.popen("git log -1 --format=%cI").read().strip()
+ if version_timestamp:
+ # Parse the timestamp, ensure that it's in UTC, and omit tz info
+ return datetime.fromisoformat(version_timestamp).astimezone(timezone.utc).replace(tzinfo=None)
+
+
+
""" *************************************************************************************
Reading directly from local .git/ or src/ files.
@@ -647,72 +713,6 @@ class VersionUtils:
- """ *************************************************************************************
- Get data via shell `git` commands.
-
- These calls shouldn't be dangerous, but we definitely don't want them being run in
- SeedSigner OS regardless so we apply the decorator restriction.
- ************************************************************************************* """
- @classmethod
- @not_allowed_in_seedsigner_os
- def _get_version_name_from_git_shell_branch(cls) -> str | None:
- branch_name = os.popen("git branch --show-current 2> /dev/null").read()
- return branch_name.strip() if branch_name else None
-
-
- @classmethod
- @not_allowed_in_seedsigner_os
- def _get_version_name_from_git_shell_tag(cls) -> str | None:
- # Only return a value if the current commit exactly corresponds with a tag.
- # (`--points-at` defaults to the current HEAD)
- tag_name = os.popen(f"git tag --points-at 2> /dev/null").read()
- return tag_name.strip() if tag_name else None
-
-
- @classmethod
- @not_allowed_in_seedsigner_os
- def _get_full_commit_hash_from_git_shell(cls) -> str | None:
- """
- Attempts to get the current git commit hash via shell `git` commands.
- """
- commit_hash = os.popen("git rev-parse HEAD").read()
- return commit_hash.strip() if commit_hash else None
-
-
- @classmethod
- @not_allowed_in_seedsigner_os
- def _get_version_name_from_git_shell(cls) -> str | None:
- """
- Attempts to get the version name via shell `git` commands.
- """
- return (
- cls._get_version_name_from_git_shell_branch() or
- cls._get_version_name_from_git_shell_tag() or
- cls._get_full_commit_hash_from_git_shell()
- )
-
-
- @classmethod
- @not_allowed_in_seedsigner_os
- def _get_version_fork_from_git_shell(cls) -> str | None:
- """
- Attempts to get the fork owner name via shell `git` commands.
- """
- # We expect to at least have a remote named "origin"
- remote_url = os.popen("git remote get-url origin 2> /dev/null").read().strip()
- return cls._parse_git_remote_url(remote_url) if remote_url else None
-
-
- @classmethod
- @not_allowed_in_seedsigner_os
- def _get_version_timestamp_from_git_shell(cls) -> datetime | None:
- version_timestamp = os.popen("git log -1 --format=%cI").read().strip()
- if version_timestamp:
- # Parse the timestamp, ensure that it's in UTC, and omit tz info
- return datetime.fromisoformat(version_timestamp).astimezone(timezone.utc).replace(tzinfo=None)
-
-
-
""" *************************************************************************************
External http GET call to github.
************************************************************************************* """
diff --git a/tests/test_version.py b/tests/test_version.py
index 8a09d50..726a517 100644
--- a/tests/test_version.py
+++ b/tests/test_version.py
@@ -283,7 +283,7 @@ class TestVersionUtils_VersionFile(VersionBaseTest):
assert VersionUtils._read_version_file() is None
- def test__get_version_name_from_env_var(self):
+ def test__get_version_name_from_seedsigner_os_env_var(self):
assert os.environ.get(VersionUtils.ENV_VAR__SEEDSIGNER_OS_BUILDER__VERSION_NAME) is None
assert VersionUtils._get_version_name_from_seedsigner_os_env_var() is None
@@ -401,6 +401,119 @@ class TestVersionUtils_GithubActions(VersionBaseTest):
+class TestVersionUtils_GitShell(VersionBaseTest):
+ def test_local_dev_with_git_shell_calls(self):
+ """
+ Test the high-level basic public calls. Does just the minimal necessary mocking
+ since all the downstream helper methods are tested in detail elsewhere.
+
+ When running in a local dev environment with access to `git` shell commands,
+ the version data should be pulled from those commands.
+
+ Note that in local dev we use the last modified timestamp from the source files
+ rather than from git.
+ """
+ with mock.patch.multiple(
+ "seedsigner.helpers.version.VersionUtils",
+ _get_version_name_from_git_shell=Mock(return_value=TEST__VERSION_BRANCH),
+ _get_version_fork_from_git_shell=Mock(return_value=TEST__VERSION_FORK),
+ _get_last_modified_timestamp_from_src_files=Mock(return_value=TEST__VERSION_TIMESTAMP),
+ _get_full_commit_hash_from_git_shell=Mock(return_value=TEST__SHORT_COMMIT_HASH),
+ ):
+ assert VersionUtils.get_version_name() == TEST__VERSION_BRANCH
+ assert VersionUtils.get_version_fork() == TEST__VERSION_FORK
+ assert VersionUtils.get_version_timestamp() == TEST__VERSION_TIMESTAMP
+ assert VersionUtils.get_short_commit_hash() == TEST__SHORT_COMMIT_HASH
+
+
+ def test__get_version_name_from_git_shell(self):
+ """
+ Test that _get_version_name_from_git_shell returns the expected name depending on
+ the current git state
+ """
+ # Default mock_popen return empty string; simulates no `git` shell command available
+ # or no local git data.
+ result = VersionUtils._get_version_name_from_git_shell()
+ assert result is None
+
+ # If we're on a branch, should return the branch name
+ with mock.patch.multiple(
+ "seedsigner.helpers.version.VersionUtils",
+ _get_version_name_from_git_shell_branch=Mock(return_value=TEST__VERSION_BRANCH),
+ _get_version_name_from_git_shell_tag=Mock(return_value=TEST__VERSION_TAG),
+ _get_full_commit_hash_from_git_shell=Mock(return_value=TEST__FULL_COMMIT_HASH),
+ ):
+ result = VersionUtils._get_version_name_from_git_shell()
+ assert result == TEST__VERSION_BRANCH
+
+ # If we're on a tag, the detached HEAD state wipes out the branch name
+ with mock.patch.multiple(
+ "seedsigner.helpers.version.VersionUtils",
+ _get_version_name_from_git_shell_branch=Mock(return_value=None),
+ _get_version_name_from_git_shell_tag=Mock(return_value=TEST__VERSION_TAG),
+ _get_full_commit_hash_from_git_shell=Mock(return_value=TEST__FULL_COMMIT_HASH),
+ ):
+ result = VersionUtils._get_version_name_from_git_shell()
+ assert result == TEST__VERSION_TAG
+
+ # Similarly, if we're detached at a specific commit hash
+ with mock.patch.multiple(
+ "seedsigner.helpers.version.VersionUtils",
+ _get_version_name_from_git_shell_branch=Mock(return_value=None),
+ _get_version_name_from_git_shell_tag=Mock(return_value=None),
+ _get_full_commit_hash_from_git_shell=Mock(return_value=TEST__FULL_COMMIT_HASH),
+ ):
+ result = VersionUtils._get_version_name_from_git_shell()
+ assert result == TEST__FULL_COMMIT_HASH
+
+
+ def test__get_version_fork_from_git_shell(self, mock_popen: Mock):
+ """
+ Test that _get_version_fork_from_git_shell returns the expected repo owner from
+ the remote url.
+ """
+ remote_url = "https://github.com/SeedSigner/seedsigner.git"
+ expected_fork = "SeedSigner"
+
+ mock_popen.return_value.read.return_value = remote_url
+ result = VersionUtils._get_version_fork_from_git_shell()
+ assert result == expected_fork
+
+
+ def test__get_version_timestamp_from_git_shell(self, mock_popen: Mock):
+ """
+ Test that _get_version_timestamp_from_git_shell returns the expected datetime.
+ """
+ # Should gracefully handle no `git` shell command available or no local git data.
+ mock_popen.return_value.read.return_value = ""
+ assert VersionUtils._get_version_timestamp_from_git_shell() is None
+
+ # Initial timestamp has timezone info
+ hour = 14
+ tz_offset = 1
+ test_local_isoformat = f"2025-12-20T{hour:02}:00:00-{tz_offset:02}:00"
+ mock_popen.return_value.read.return_value = test_local_isoformat
+
+ # But the final result will be UTC
+ expected_datetime = datetime.fromisoformat(f"2025-12-20T{hour + tz_offset:02}:00:00")
+ assert VersionUtils._get_version_timestamp_from_git_shell() == expected_datetime
+
+ # And UTC-to-UTC should be unchanged
+ mock_popen.return_value.read.return_value = expected_datetime.isoformat() + "+00:00"
+ assert VersionUtils._get_version_timestamp_from_git_shell() == expected_datetime
+
+
+ def test__get_full_commit_hash_from_git_shell(self, mock_popen: Mock):
+ """
+ Test that _get_full_commit_hash_from_git_shell returns the expected short commit hash.
+ """
+ mock_popen.return_value.read.return_value = TEST__SHORT_COMMIT_HASH
+
+ result = VersionUtils._get_full_commit_hash_from_git_shell()
+ assert result == TEST__SHORT_COMMIT_HASH
+
+
+
class TestVersionUtils_DotGitFiles(VersionBaseTest):
def test_local_dev_with_dot_git_dir_parsing(self, mock_popen: Mock):
"""
@@ -542,8 +655,9 @@ class TestVersionUtils_DotGitFiles(VersionBaseTest):
def test__get_commit_hash_from_git_HEAD(self):
- # _get_commit_hash_from_git_HEAD is a trivial convenience function that relies on _read_git_HEAD_file which we've already tested.
- # Just verify the expected outputs here.
+ # _get_commit_hash_from_git_HEAD is a trivial convenience function that relies on
+ # _read_git_HEAD_file which we've already tested. Just verify the expected outputs
+ # here.
with mock.patch.object(VersionUtils, '_read_git_HEAD_file', return_value=(None, TEST__SHORT_COMMIT_HASH)):
assert VersionUtils._get_full_commit_hash_from_git_HEAD() == TEST__SHORT_COMMIT_HASH
@@ -579,7 +693,7 @@ class TestVersionUtils_DotGitFiles(VersionBaseTest):
_parse_git_remote_url should return the expected repo owner from various
git remote url formats.
"""
- # Might be called with no remote url or unrecognized format
+ # Might be called with no remote url. Should also handle unrecognized formats.
for url in [None, "", "what/is/this"]:
assert VersionUtils._parse_git_remote_url(url) is None
@@ -661,119 +775,6 @@ class TestVersionUtils_DotGitFiles(VersionBaseTest):
-class TestVersionUtils_GitShell(VersionBaseTest):
- def test_local_dev_with_git_shell_calls(self):
- """
- Test the high-level basic public calls. Does just the minimal necessary mocking
- since all the downstream helper methods are tested in detail elsewhere.
-
- When running in a local dev environment with access to `git` shell commands,
- the version data should be pulled from those commands.
-
- Note that in local dev we use the last modified timestamp from the source files
- rather than from git.
- """
- with mock.patch.multiple(
- "seedsigner.helpers.version.VersionUtils",
- _get_version_name_from_git_shell=Mock(return_value=TEST__VERSION_BRANCH),
- _get_version_fork_from_git_shell=Mock(return_value=TEST__VERSION_FORK),
- _get_last_modified_timestamp_from_src_files=Mock(return_value=TEST__VERSION_TIMESTAMP),
- _get_full_commit_hash_from_git_shell=Mock(return_value=TEST__SHORT_COMMIT_HASH),
- ):
- assert VersionUtils.get_version_name() == TEST__VERSION_BRANCH
- assert VersionUtils.get_version_fork() == TEST__VERSION_FORK
- assert VersionUtils.get_version_timestamp() == TEST__VERSION_TIMESTAMP
- assert VersionUtils.get_short_commit_hash() == TEST__SHORT_COMMIT_HASH
-
-
- def test__get_version_name_from_git_shell(self):
- """
- Test that _get_version_name_from_git_shell returns the expected name depending on
- the current git state
- """
- # Default mock_popen return empty string; simulates no `git` shell command available
- # or no local git data.
- result = VersionUtils._get_version_name_from_git_shell()
- assert result is None
-
- # If we're on a branch, should return the branch name
- with mock.patch.multiple(
- "seedsigner.helpers.version.VersionUtils",
- _get_version_name_from_git_shell_branch=Mock(return_value=TEST__VERSION_BRANCH),
- _get_version_name_from_git_shell_tag=Mock(return_value=TEST__VERSION_TAG),
- _get_full_commit_hash_from_git_shell=Mock(return_value=TEST__FULL_COMMIT_HASH),
- ):
- result = VersionUtils._get_version_name_from_git_shell()
- assert result == TEST__VERSION_BRANCH
-
- # If we're on a tag, the detached HEAD state wipes out the branch name
- with mock.patch.multiple(
- "seedsigner.helpers.version.VersionUtils",
- _get_version_name_from_git_shell_branch=Mock(return_value=None),
- _get_version_name_from_git_shell_tag=Mock(return_value=TEST__VERSION_TAG),
- _get_full_commit_hash_from_git_shell=Mock(return_value=TEST__FULL_COMMIT_HASH),
- ):
- result = VersionUtils._get_version_name_from_git_shell()
- assert result == TEST__VERSION_TAG
-
- # Similarly, if we're detached at a specific commit hash
- with mock.patch.multiple(
- "seedsigner.helpers.version.VersionUtils",
- _get_version_name_from_git_shell_branch=Mock(return_value=None),
- _get_version_name_from_git_shell_tag=Mock(return_value=None),
- _get_full_commit_hash_from_git_shell=Mock(return_value=TEST__FULL_COMMIT_HASH),
- ):
- result = VersionUtils._get_version_name_from_git_shell()
- assert result == TEST__FULL_COMMIT_HASH
-
-
- def test__get_version_fork_from_git_shell(self, mock_popen: Mock):
- """
- Test that _get_version_fork_from_git_shell returns the expected repo owner from
- the remote url.
- """
- remote_url = "https://github.com/SeedSigner/seedsigner.git"
- expected_fork = "SeedSigner"
-
- mock_popen.return_value.read.return_value = remote_url
- result = VersionUtils._get_version_fork_from_git_shell()
- assert result == expected_fork
-
-
- def test__get_version_timestamp_from_git_shell(self, mock_popen: Mock):
- """
- Test that _get_version_timestamp_from_git_shell returns the expected datetime.
- """
- # Should gracefully handle no `git` shell command available or no local git data.
- mock_popen.return_value.read.return_value = ""
- assert VersionUtils._get_version_timestamp_from_git_shell() is None
-
- # Initial timestamp has timezone info
- hour = 14
- tz_offset = 1
- test_local_isoformat = f"2025-12-20T{hour:02}:00:00-{tz_offset:02}:00"
- mock_popen.return_value.read.return_value = test_local_isoformat
-
- # But the final result will be UTC
- expected_datetime = datetime.fromisoformat(f"2025-12-20T{hour + tz_offset:02}:00:00")
- assert VersionUtils._get_version_timestamp_from_git_shell() == expected_datetime
-
- # And UTC-to-UTC should be unchanged
- mock_popen.return_value.read.return_value = expected_datetime.isoformat() + "+00:00"
- assert VersionUtils._get_version_timestamp_from_git_shell() == expected_datetime
-
-
- def test__get_short_commit_hash_from_git_shell(self, mock_popen: Mock):
- """
- Test that _get_full_commit_hash_from_git_shell returns the expected short commit hash.
- """
- mock_popen.return_value.read.return_value = TEST__SHORT_COMMIT_HASH
-
- result = VersionUtils._get_full_commit_hash_from_git_shell()
- assert result == TEST__SHORT_COMMIT_HASH
-
-
-
class TestVersionUtils_Misc(VersionBaseTest):
"""
Tests for any other remaining methods in VersionUtils.
@@ -915,6 +916,9 @@ class TestNotAllowedInSeedSignerOSDecorator(BaseTest):
class TestNotVersionBaseTest(BaseTest):
+ """
+ Sanity check to verify that VersionBaseTest mocks do not affect other tests.
+ """
def test_version_file_name__not_patched(self):
"""
Ensure that outside of VersionBaseTest, the VERSIONFILE__FILENAME patch does not
@@ -925,9 +929,7 @@ class TestNotVersionBaseTest(BaseTest):
def test_mock_popen__not_patched(self):
"""
- Ensure that outside of VersionBaseTest, os.popen is not patched.
+ Ensure that os.popen is not mocked outside of VersionBaseTest.
"""
- # Call os.popen
result = os.popen("echo 'Hello, World!'")
- # The result should not be a MagicMock instance
assert not isinstance(result, mock.MagicMock)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.