Migrate subsection of vcstools' API for compatibility with bloom#43
Migrate subsection of vcstools' API for compatibility with bloom#43leander-dsouza wants to merge 18 commits into
Conversation
5730d2c to
650fcd3
Compare
659c3b8 to
5f6ce04
Compare
477c4be to
d08697b
Compare
5f6ce04 to
e47aac4
Compare
8e32c1a to
138ad9f
Compare
138ad9f to
83040dc
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #43 +/- ##
==========================================
+ Coverage 26.96% 28.11% +1.14%
==========================================
Files 31 31
Lines 2240 2465 +225
Branches 393 437 +44
==========================================
+ Hits 604 693 +89
- Misses 1576 1698 +122
- Partials 60 74 +14 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@leander-dsouza, I noticed that some implementations of |
nuclearsandwich
left a comment
There was a problem hiding this comment.
It looks good but for the one comment about the git client which I believe can be simplified dramatically.
|
|
||
| # If current version matches export version and no local changes, export directly | ||
| current_sha = self._get_current_version() | ||
| export_sha = self._get_version_sha(version) if version else current_sha |
There was a problem hiding this comment.
if we have an exact version to provide as a commit-ish->tree-ish what is the requirement to use a temp directory. git-archive does not make any changes to the working directory. I have not gone spelunking in the history but I'm willing to hypothesize that this behavior is carried over from a vcs which does not support exporting archives of snapshots without checking them out first.
git archive --format=tar.gz --output={filepath} export_sha
There was a problem hiding this comment.
Yes, you are correct, Steven.
I tried to replicate the archiving behaviour of the original implementation of the archiving process in vcstools
I have now simplified the implementation of this section, as git archive does not change the cwd.
| result['output'] = branch | ||
| return result | ||
|
|
||
| def _export_repository(self, version, basepath): |
There was a problem hiding this comment.
A handful of these are named _export_repository instead of export_repository. to match the API. Is that intentional?
There was a problem hiding this comment.
I briefly remember selectively naming the export methods for this reason.
However, I cannot find these methods in the vcstools repository. Hence, I added a commit to standardise the export repository methods across all VCS clients.
4afa4b1 to
5b27149
Compare
I remember drafting the export methods to match the vcstools repository. However, I think I was mistaken, and hence I added a commit to standardise all the export repository methods across all VCS clients. |
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
5b27149 to
1ca67bc
Compare
KmoM88
left a comment
There was a problem hiding this comment.
Hi @leander-dsouza ,
Thank you for your hard work on this!
I've left a few comments on the files above pointing out some areas where we maybe can make the API even more robust, predictable, and maintainable.
Please take a look at the comments, they are very much open for discussion, and I'd love to hear your thoughts on these approaches.
Great job!
| if os.path.exists(self.path): | ||
| if os.path.isdir(self.path): | ||
| if os.listdir(self.path): | ||
| return False | ||
| else: | ||
| return False |
There was a problem hiding this comment.
I noticed that the error handling in checkout is inconsistent when the target directory already exists and is not empty:
git.pyandhg.pyreturnFalse.svn.pyandbzr.pyraise aRuntimeError.
To keep the API unified and predictable, I recommend standardizing this behavior. Raising a descriptive exception (rather than returning False) would be the most robust approach.
What do you think?
| if os.path.exists(self.path): | ||
| if os.path.isdir(self.path): | ||
| # Check if directory is empty | ||
| if os.listdir(self.path): | ||
| return False | ||
| else: | ||
| return False |
There was a problem hiding this comment.
I noticed that the error handling in checkout is inconsistent when the target directory already exists and is not empty:
git.pyandhg.pyreturnFalse.svn.pyandbzr.pyraise aRuntimeError.
To keep the API unified and predictable, I recommend standardizing this behavior. Raising a descriptive exception (rather than returning False) would be the most robust approach.
What do you think?
| % self.__class__.type | ||
| ) | ||
|
|
||
| def checkout(self, url, version=None, verbose=False, shallow=False, timeout=None): |
There was a problem hiding this comment.
The timeout parameter is defined here in the base class, but it isn't currently used in any of the client implementations.
While the underlying command-line tools have inconsistent support for timeout flags, we can actually implement a clean, universal timeout in Python. The run_command helper in this file uses subprocess.Popen, and proc.communicate() has built-in support for a timeout parameter.
Would it be possible to pass timeout down from the clients' checkout methods to run_command and proc.communicate(timeout=timeout)?
Ref: https://docs.python.org/3/library/subprocess.html
proc = subprocess.Popen(...)
try:
outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()If implementing this is outside the scope of this PR, we should probably remove the timeout parameter from the base class and client definitions for now to keep the API contract accurate. Let me know what you think.
| result = self._run_command(cmd) | ||
| except Exception as e: | ||
| print('Branch command failed with exception: %s' % str(e)) | ||
| return False |
There was a problem hiding this comment.
Digging deeper into the error handling, I noticed that in the bzr.py checkout method, the try...except block catches a generic Exception, prints it, and then returns False.
This "swallows" the exception, meaning the calling code only knows that something failed but loses all context about why. This can lead to silent failures that are difficult to debug.
Looking at the other clients, this behavior is inconsistent:
git.pyandhg.pyfollow the same problematic pattern of swallowing exceptions.svn.pyhas notry...exceptblock at all, making it brittle to unexpected errors.
I have a suggestion for a unified solution:
Instead of managing this in each client, what if we made the shared _run_command method in VcsClientBase responsible for this?
We could wrap the call to the global run_command inside _run_command with a try...except block. If any unexpected exception occurs, _run_command itself could then raise a specific, library-wide exception (e.g., Vcs2lError).
This would give us two major benefits:
- Consistency: All clients would automatically have the same robust, exception-based error handling.
- Simplicity: We could remove the repetitive
try...exceptblocks from the git, hg, and bzr clients, making their code cleaner.
What are your thoughts on centralizing the exception handling within _run_command this way?
Note
Please refer #751 for verifying integration with bloom.
Basic Info
Description of contribution in a few bullet points
This ports over four main functions from vcstools, namely
export_repositories,checkout,get_vcs_client, andget_pathfor all the VCS clients.This is because these are the four prominent methods used in bloom as seen here.
checkoutreferenceexport_repositoriesreferenceget_vcs_clientreferenceget_pathreferenceIn addition, the corresponding integration tests have been added to both of these functions across
svn,bzr,hg, andgitclients.Breezy has been added to the CI for testing on macOS and Ubuntu.
The integration can be safely verified in #751 at bloom. All the system and unit tests pass upon merge.
Description of how this change was tested
Ran
pytestlocally to ensure all the unit and linting tests pass:pytest -s -v testSigned-off-by: Leander Stephen Desouza leanderdsouza1234@gmail.com