Skip to content

Commit ff15572

Browse files
committed
Allow using specific revisions in lib install --git-url (arduino#1113)
This is done by providing the desired revision in the fragment, e.g. `…/Library.git#0.1.0`. When set, this disables the clone depth limit so all remote references will be available.
1 parent 64bc4dc commit ff15572

File tree

2 files changed

+64
-6
lines changed

2 files changed

+64
-6
lines changed

arduino/libraries/librariesmanager/install.go

+32-6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/codeclysm/extract/v3"
3131
"github.com/sirupsen/logrus"
3232
"gopkg.in/src-d/go-git.v4"
33+
"gopkg.in/src-d/go-git.v4/plumbing"
3334
)
3435

3536
type alreadyInstalledError struct{}
@@ -190,7 +191,7 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
190191
return fmt.Errorf(tr("User directory not set"))
191192
}
192193

193-
libraryName, err := parseGitURL(gitURL)
194+
libraryName, ref, err := parseGitURL(gitURL)
194195
if err != nil {
195196
logrus.
196197
WithError(err).
@@ -218,9 +219,13 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
218219
WithField("git url", gitURL).
219220
Trace("Installing library")
220221

221-
_, err = git.PlainClone(installPath.String(), false, &git.CloneOptions{
222+
depth := 1
223+
if ref != "" {
224+
depth = 0
225+
}
226+
repo, err := git.PlainClone(installPath.String(), false, &git.CloneOptions{
222227
URL: gitURL,
223-
Depth: 1,
228+
Depth: depth,
224229
Progress: os.Stdout,
225230
})
226231
if err != nil {
@@ -230,6 +235,25 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
230235
return err
231236
}
232237

238+
if ref != "" {
239+
if h, err := repo.ResolveRevision(ref); err != nil {
240+
logrus.
241+
WithError(err).
242+
Warnf("Resolving revision %s", ref)
243+
return err
244+
} else if w, err := repo.Worktree(); err != nil {
245+
logrus.
246+
WithError(err).
247+
Warn("Finding worktree")
248+
return err
249+
} else if err := w.Checkout(&git.CheckoutOptions{Hash: plumbing.NewHash(h.String())}); err != nil {
250+
logrus.
251+
WithError(err).
252+
Warnf("Checking out %s", h)
253+
return err
254+
}
255+
}
256+
233257
if err := validateLibrary(installPath); err != nil {
234258
// Clean up installation directory since this is not a valid library
235259
installPath.RemoveAll()
@@ -243,8 +267,9 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
243267

244268
// parseGitURL tries to recover a library name from a git URL.
245269
// Returns an error in case the URL is not a valid git URL.
246-
func parseGitURL(gitURL string) (string, error) {
270+
func parseGitURL(gitURL string) (string, plumbing.Revision, error) {
247271
var res string
272+
var rev plumbing.Revision
248273
if strings.HasPrefix(gitURL, "git@") {
249274
// We can't parse these as URLs
250275
i := strings.LastIndex(gitURL, "/")
@@ -254,10 +279,11 @@ func parseGitURL(gitURL string) (string, error) {
254279
} else if parsed, err := url.Parse(gitURL); parsed.String() != "" && err == nil {
255280
i := strings.LastIndex(parsed.Path, "/")
256281
res = strings.TrimSuffix(parsed.Path[i+1:], ".git")
282+
rev = plumbing.Revision(parsed.Fragment)
257283
} else {
258-
return "", fmt.Errorf(tr("invalid git url"))
284+
return "", "", fmt.Errorf(tr("invalid git url"))
259285
}
260-
return res, nil
286+
return res, rev, nil
261287
}
262288

263289
// validateLibrary verifies the dir contains a valid library, meaning it has either

test/test_lib.py

+32
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,38 @@ def test_install_with_git_url(run_command, data_dir, downloads_dir):
347347
# Verifies library remains installed
348348
assert lib_install_dir.exists()
349349

350+
def test_install_with_git_url_fragment_as_branch(run_command, data_dir, downloads_dir):
351+
# Initialize configs to enable --git-url flag
352+
env = {
353+
"ARDUINO_DATA_DIR": data_dir,
354+
"ARDUINO_DOWNLOADS_DIR": downloads_dir,
355+
"ARDUINO_SKETCHBOOK_DIR": data_dir,
356+
"ARDUINO_ENABLE_UNSAFE_LIBRARY_INSTALL": "true",
357+
}
358+
assert run_command(["config", "init", "--dest-dir", "."], custom_env=env)
359+
360+
lib_install_dir = Path(data_dir, "libraries", "WiFi101")
361+
# Verifies library is not already installed
362+
assert not lib_install_dir.exists()
363+
364+
git_url = "https://github.com/arduino-libraries/WiFi101.git"
365+
366+
# Test that a bad ref fails
367+
res = run_command(["lib", "install", "--git-url", git_url + "#x-ref-does-not-exist"])
368+
assert res.failed
369+
370+
# Verifies library is installed in expected path
371+
res = run_command(["lib", "install", "--git-url", git_url + "#0.16.0"])
372+
assert res.ok
373+
assert lib_install_dir.exists()
374+
375+
# Reinstall library at an existing ref
376+
assert run_command(["lib", "install", "--git-url", git_url + "#master"])
377+
assert res.ok
378+
379+
# Verifies library remains installed
380+
assert lib_install_dir.exists()
381+
350382

351383
def test_install_with_zip_path(run_command, data_dir, downloads_dir):
352384
# Initialize configs to enable --zip-path flag

0 commit comments

Comments
 (0)