Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

g.extension: use git sparse-checkout instead of SVN #2895

Merged
merged 6 commits into from
Apr 12, 2023

Conversation

ninsbl
Copy link
Member

@ninsbl ninsbl commented Mar 17, 2023

This PR replaces svn export to fetch single addons from the official addon repository with git sparse-checkout. Thus, the dependency on SVN becomes only optional (if SVN repositories are used). See #2834
It also reduces the likelihood that the GitHub API is used (and rate limit is hit) as info about latest changes can be taken from the git logs.
Could be a first step towards also supporting installation of multiple AddOns (or all). Because of possible extented use of the introduced functionality it is implemented as a GitAdapter class.

More cleanup in existing g.extension code should be done (but that is a different PR)...

Leaving the milestone open as I do not know if it is feasible (or appropriate) to get this into 8.3...

@ninsbl ninsbl added enhancement New feature or request Python Related code is in Python labels Mar 17, 2023
@ninsbl ninsbl requested review from wenzeslaus and tmszi March 17, 2023 22:40
@nilason
Copy link
Contributor

nilason commented Mar 17, 2023

I’m glad you could make this effort to rework the add-on install! I have not tested nor reviewed the code, but in my opinion, in principle this update should be seriously considered for 8.3. Thanks!

Copy link
Member

@wenzeslaus wenzeslaus left a comment

Choose a reason for hiding this comment

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

I just did a shallow review. General code layout looks good. The Git code promising.

The gscript/grass -> gs is needed, but it makes this PR harder to navigate. It is okay to use it for the new code, i.e., have both import grass.script as gs and import grass.script as gscript.

return directory


def download_source_code_official_github(url, name, outdev, directory=None):
def download_source_code_official_github(
url, name, branch, major_grass_version=8, directory=None
Copy link
Member

Choose a reason for hiding this comment

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

Try to avoid major_grass_version=8 this would be difficult to maintain.

)
% file_url
"Unable to parse '{url}'. Trying to scan"
" git repository (may take some time)..."
Copy link
Member

Choose a reason for hiding this comment

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

It is actually a "Git repository" like before it was "Subversion repository".

url="https://github.com/osgeo/grass-addons",
working_directory=None,
official_repository_structure=True,
major_grass_version=8,
Copy link
Member

Choose a reason for hiding this comment

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

Another place which has the hardcoded major version. See all the desperate commits trying to fix version numbers around every release.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks! Yes, that was planned to be set to version extracted at the bottom of the module, forgot to plug that in...

Comment on lines 260 to 265
repo_directory = (
self.url.split("/")[-1][0:-4]
if self.url.endswith(".git")
else self.url.split("/")[-1]
)
self.local_copy = self.working_directory / repo_directory
Copy link
Member

Choose a reason for hiding this comment

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

If the repo_directory only purpose is to find the directory, you can do it ahead of time. Find the name in the URL, than use the name with git command, then you have it fully under control, can check if it already exists (but the git call can still fail if two g.extensions run in parallel).

Copy link
Member Author

Choose a reason for hiding this comment

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

Right. This is unnecessary complicated. Using a fixed directory name now. Maybe this needs reconsidering when git clone should be used for all git compatible sources...

Comment on lines 261 to 263
self.url.split("/")[-1][0:-4]
if self.url.endswith(".git")
else self.url.split("/")[-1]
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure about best practice for splitting URLs (split vs Path vs urlparse), but rsplit with max splits will be better than split.

)
branch_list = gs.decode(branch_list.communicate()[0])
return {
branch.split("/")[-1]: branch.split("\t")[0]
Copy link
Member

Choose a reason for hiding this comment

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

rsplit

Copy link
Member Author

Choose a reason for hiding this comment

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

Implemented

@ninsbl
Copy link
Member Author

ninsbl commented Mar 19, 2023

Should address also: #2186
This is however to be considered as another step towards better git support in general.

Maybe a thorough cleanup and refactoring of g.extension would be a good topic for the community sprint...

@nilason
Copy link
Contributor

nilason commented Mar 21, 2023

I did test this and installed some addons, seems to work fine. Is there any particular weak spot, that needs testing?

As I mentioned in #2717 (comment) you may try to remove the test_addons_download.py exclusion for Mac CI build.

@petrasovaa
Copy link
Contributor

Are there any concerns about the version of git? We need to specify minimum version, no?

@echoix
Copy link
Member

echoix commented Mar 21, 2023

In what git version sparse checkout started working like the extension uses? It wasn't possible before, hence why SVN was kept

@nilason
Copy link
Contributor

nilason commented Mar 21, 2023

Probably Git 2.27 should be needed (https://stackoverflow.com/a/62480045), sparse-checkout introduced in 2.25 (https://github.com/git/git/blob/e25cabbf6b34e4a6e903d65102d87055cc994778/Documentation/RelNotes/2.25.0.txt#L67)
but fixes in 2.27 may be needed. This is after a very quick check, I may be wrong.

https://repology.org/project/git/versions

@ninsbl
Copy link
Member Author

ninsbl commented Mar 22, 2023

Good points! So, Debian 10 could be problematic and CentOS < 8 will not work either, same for Ubunut 18.04.
I tested with Ubunut 20.04 which has git 2.25.1 and that seems to work fine.

What distros and older versions do we want to support with recent code?
Or do we need a fall-back solution for older systems?

MS Windows is not affected as there svn is not available either and ionly precompiled addons are used...

@wenzeslaus
Copy link
Member

...What distros and older versions do we want to support with recent code? Or do we need a fall-back solution for older systems?

I don't have a direct answer, but whatever we want to support 100% should be in the CI (if it is not there, it should be added). The limitations: We are using pre-configured VMs, so the CI environments are not completely same as default installations. We don't test every Linux distro, we just assume that what we test is a good proxy. The recent Ubuntu update in CI was not motivated by version coverage (#2730). CentOS looks like old-system test, but it actually never achieved that; it's a conda on old system test. We don't run tests on CentOS.

We are also still maintaining 7.8 right now if one needs a legacy version.

@petrasovaa
Copy link
Contributor

What distros and older versions do we want to support with recent code? Or do we need a fall-back solution for older systems?

Given that GitHub stops SVN support January 8th 2024 (in less than a year) then there is no point in keeping the current svn code. This means also 7.8 g.extension stops working next year. A fallback solution could be to clone the entire repository, no? I think at the very least this PR should check for the version (2.25 minimum I guess) and suggest to update git version instead of failing.

@ninsbl
Copy link
Member Author

ninsbl commented Mar 22, 2023

Thanks for the feedbak! It seems first versions of sparse checkout were introduced in git versions as early as 1.7:
https://github.com/git/git/blob/142430338477d9d1bb25be66267225fb58498d92/Documentation/RelNotes/1.7.0.txt
I found no earlier version than that on repology. Maybe I will try to compile 1.7.0 for a test, and if that works we do not need a fallback...
Should be possible to backport to 7.8 (and 8.2 / 8.0)...

@nilason
Copy link
Contributor

nilason commented Mar 22, 2023

Thanks for the feedbak! It seems first versions of sparse checkout were introduced in git versions as early as 1.7:
https://github.com/git/git/blob/142430338477d9d1bb25be66267225fb58498d92/Documentation/RelNotes/1.7.0.txt
I found no earlier version than that on repology. Maybe I will try to compile 1.7.0 for a test, and if that works we do not need a fallback...
Should be possible to backport to 7.8 (and 8.2 / 8.0)...

Strange, considering https://github.blog/2020-01-13-highlights-from-git-2-25/

@nilason
Copy link
Contributor

nilason commented Mar 22, 2023

From source above:

Previously, in order to use the sparse-checkout feature you needed to manually edit a file in your .git directory, change a config setting, and run an obscure plumbing command. The instructions for getting back to normal were even more complicated. The new git sparse-checkout command makes this process much easier.

@ninsbl
Copy link
Member Author

ninsbl commented Mar 24, 2023

OK, added a fall-back solution now, that uses a normal checkout for git versions < 2.25.
The fall-back solution is tested in principle locally, but due to the lack of old enough git version, I could not fully test it (meaning if it also works with e.g. git 1.6 or 1.7).

@ninsbl
Copy link
Member Author

ninsbl commented Mar 24, 2023

Here is a comparison of g.extension as of this PR:

time g.extension v.stream.order
WARNING: Extension <v.stream.order> already installed. Re-installing...
Fetching <v.stream.order> from <https://github.com/OSGeo/grass-addons> (be
patient)...
remote: Enumerating objects: 27, done.
remote: Counting objects: 100% (21/21), done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 27 (delta 1), reused 8 (delta 0), pack-reused 6
Receiving objects: 100% (27/27), 67.52 KiB | 2.50 MiB/s, done.
Resolving deltas: 100% (1/1), done.
Already on 'grass8'
Your branch is up to date with 'origin/grass8'.
Compiling...
Installing...
Updating extensions metadata file...
Updating extension modules metadata file...
Installation of <v.stream.order> successfully finished

real	0m12.353s
user	0m4.667s
sys	0m1.339s

and g.extension in GRASS GIS 8.2.1:

time g.extension v.stream.order
WARNING: Extension <v.stream.order> already installed. Re-installing...
Fetching <v.stream.order> from GRASS GIS Addons repository (be patient)...
Compiling...
Installing...
Updating extensions metadata file...
Updating extension modules metadata file...
Installation of <v.stream.order> successfully finished

real	0m10.692s
user	0m1.979s
sys	0m0.601s

By using git, the module becomes a bit more chatty, and takes 20% (or 2 seconds) longer...

A question is if it would be appropriate to get this into 8.3 or if it should be tested a bit more first...
Download tests in CI for Mac are now activated...

@nilason
Copy link
Contributor

nilason commented Mar 28, 2023

A question is if it would be appropriate to get this into 8.3 or if it should be tested a bit more first...

Personally I'd welcome it for 8.3. Note, it is RC to come, great opportunity for broader testing!

Download tests in CI for Mac are now activated...

👍

Just a note on the in-line comments on the GitAdapter::__init__ method:
there is a copy-paste typo with "containg", but I'd say most (if not all!) of the comments in that method is superfluous, the code says what need to be said.

@petrasovaa
Copy link
Contributor

I tested little bit, I am for 8.3 as well.

@ninsbl ninsbl added this to the 8.3.0 milestone Mar 29, 2023
@ninsbl
Copy link
Member Author

ninsbl commented Mar 29, 2023

Thanks for the feedback @nilason and @petrasovaa
I just added this to Milestone 8.3 and fixed the typos, though I would have no objections to remove the comments if they are considered unnecessary...

@ninsbl ninsbl merged commit a7ed30c into OSGeo:main Apr 12, 2023
@ninsbl
Copy link
Member Author

ninsbl commented Apr 12, 2023

Took the liberty to merge this as no RC is out yet and there were no objections to including it into 8.3.
Will wait with backporting until this is a bit more broadly tested...

neteler pushed a commit to nilason/grass that referenced this pull request Nov 7, 2023
* unified imports
* use git sparse checkout
* version dependent fall-back
* test on mac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Python Related code is in Python
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants