Skip to content

Allow using specific revisions in lib install --git-url (#1113) #1776

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

Merged
merged 1 commit into from
Jul 22, 2022
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
38 changes: 32 additions & 6 deletions arduino/libraries/librariesmanager/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/codeclysm/extract/v3"
"github.com/sirupsen/logrus"
"gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing"
)

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

libraryName, err := parseGitURL(gitURL)
libraryName, ref, err := parseGitURL(gitURL)
if err != nil {
logrus.
WithError(err).
Expand Down Expand Up @@ -218,9 +219,13 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
WithField("git url", gitURL).
Trace("Installing library")

_, err = git.PlainClone(installPath.String(), false, &git.CloneOptions{
depth := 1
if ref != "" {
depth = 0
}
repo, err := git.PlainClone(installPath.String(), false, &git.CloneOptions{
URL: gitURL,
Depth: 1,
Depth: depth,
Progress: os.Stdout,
})
if err != nil {
Expand All @@ -230,6 +235,25 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {
return err
}

if ref != "" {
if h, err := repo.ResolveRevision(ref); err != nil {
logrus.
WithError(err).
Warnf("Resolving revision %s", ref)
return err
} else if w, err := repo.Worktree(); err != nil {
logrus.
WithError(err).
Warn("Finding worktree")
return err
} else if err := w.Checkout(&git.CheckoutOptions{Hash: plumbing.NewHash(h.String())}); err != nil {
logrus.
WithError(err).
Warnf("Checking out %s", h)
return err
}
}

if err := validateLibrary(installPath); err != nil {
// Clean up installation directory since this is not a valid library
installPath.RemoveAll()
Expand All @@ -243,8 +267,9 @@ func (lm *LibrariesManager) InstallGitLib(gitURL string, overwrite bool) error {

// parseGitURL tries to recover a library name from a git URL.
// Returns an error in case the URL is not a valid git URL.
func parseGitURL(gitURL string) (string, error) {
func parseGitURL(gitURL string) (string, plumbing.Revision, error) {
var res string
var rev plumbing.Revision
if strings.HasPrefix(gitURL, "git@") {
// We can't parse these as URLs
i := strings.LastIndex(gitURL, "/")
Expand All @@ -254,10 +279,11 @@ func parseGitURL(gitURL string) (string, error) {
} else if parsed, err := url.Parse(gitURL); parsed.String() != "" && err == nil {
i := strings.LastIndex(parsed.Path, "/")
res = strings.TrimSuffix(parsed.Path[i+1:], ".git")
rev = plumbing.Revision(parsed.Fragment)
} else {
return "", fmt.Errorf(tr("invalid git url"))
return "", "", fmt.Errorf(tr("invalid git url"))
}
return res, nil
return res, rev, nil
}

// validateLibrary verifies the dir contains a valid library, meaning it has either
Expand Down
30 changes: 22 additions & 8 deletions arduino/libraries/librariesmanager/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,57 @@ import (

func TestParseGitURL(t *testing.T) {
gitURL := ""
libraryName, err := parseGitURL(gitURL)
libraryName, ref, err := parseGitURL(gitURL)
require.Equal(t, "", libraryName)
require.EqualValues(t, "", ref)
require.Errorf(t, err, "invalid git url")

gitURL = "https://github.com/arduino/arduino-lib.git"
libraryName, err = parseGitURL(gitURL)
libraryName, ref, err = parseGitURL(gitURL)
require.Equal(t, "arduino-lib", libraryName)
require.EqualValues(t, "", ref)
require.NoError(t, err)

gitURL = "https://github.com/arduino/arduino-lib.git#0.1.2"
libraryName, ref, err = parseGitURL(gitURL)
require.Equal(t, "arduino-lib", libraryName)
require.EqualValues(t, "0.1.2", ref)
require.NoError(t, err)

gitURL = "[email protected]:arduino/arduino-lib.git"
libraryName, err = parseGitURL(gitURL)
libraryName, ref, err = parseGitURL(gitURL)
require.Equal(t, "arduino-lib", libraryName)
require.EqualValues(t, "", ref)
require.NoError(t, err)

gitURL = "file:///path/to/arduino-lib"
libraryName, err = parseGitURL(gitURL)
libraryName, ref, err = parseGitURL(gitURL)
require.Equal(t, "arduino-lib", libraryName)
require.EqualValues(t, "", ref)
require.NoError(t, err)

gitURL = "file:///path/to/arduino-lib.git"
libraryName, err = parseGitURL(gitURL)
libraryName, ref, err = parseGitURL(gitURL)
require.Equal(t, "arduino-lib", libraryName)
require.EqualValues(t, "", ref)
require.NoError(t, err)

gitURL = "/path/to/arduino-lib"
libraryName, err = parseGitURL(gitURL)
libraryName, ref, err = parseGitURL(gitURL)
require.Equal(t, "arduino-lib", libraryName)
require.EqualValues(t, "", ref)
require.NoError(t, err)

gitURL = "/path/to/arduino-lib.git"
libraryName, err = parseGitURL(gitURL)
libraryName, ref, err = parseGitURL(gitURL)
require.Equal(t, "arduino-lib", libraryName)
require.EqualValues(t, "", ref)
require.NoError(t, err)

gitURL = "file:///path/to/arduino-lib"
libraryName, err = parseGitURL(gitURL)
libraryName, ref, err = parseGitURL(gitURL)
require.Equal(t, "arduino-lib", libraryName)
require.EqualValues(t, "", ref)
require.NoError(t, err)
}

Expand Down
1 change: 1 addition & 0 deletions cli/lib/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func initInstallCommand() *cobra.Command {
" " + os.Args[0] + " lib install AudioZero # " + tr("for the latest version.") + "\n" +
" " + os.Args[0] + " lib install [email protected] # " + tr("for the specific version.") + "\n" +
" " + os.Args[0] + " lib install --git-url https://github.com/arduino-libraries/WiFi101.git https://github.com/arduino-libraries/ArduinoBLE.git\n" +
" " + os.Args[0] + " lib install --git-url https://github.com/arduino-libraries/WiFi101.git#0.16.0 # " + tr("for the specific version.") + "\n" +
" " + os.Args[0] + " lib install --zip-path /path/to/WiFi101.zip /path/to/ArduinoBLE.zip\n",
Args: cobra.MinimumNArgs(1),
Run: runInstallCommand,
Expand Down
33 changes: 33 additions & 0 deletions test/test_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,39 @@ def test_install_with_git_url(run_command, data_dir, downloads_dir):
assert lib_install_dir.exists()


def test_install_with_git_url_fragment_as_branch(run_command, data_dir, downloads_dir):
# Initialize configs to enable --git-url flag
env = {
"ARDUINO_DATA_DIR": data_dir,
"ARDUINO_DOWNLOADS_DIR": downloads_dir,
"ARDUINO_SKETCHBOOK_DIR": data_dir,
"ARDUINO_ENABLE_UNSAFE_LIBRARY_INSTALL": "true",
}
assert run_command(["config", "init", "--dest-dir", "."], custom_env=env)

lib_install_dir = Path(data_dir, "libraries", "WiFi101")
# Verifies library is not already installed
assert not lib_install_dir.exists()

git_url = "https://github.com/arduino-libraries/WiFi101.git"

# Test that a bad ref fails
res = run_command(["lib", "install", "--git-url", git_url + "#x-ref-does-not-exist"])
assert res.failed

# Verifies library is installed in expected path
res = run_command(["lib", "install", "--git-url", git_url + "#0.16.0"])
assert res.ok
assert lib_install_dir.exists()

# Reinstall library at an existing ref
assert run_command(["lib", "install", "--git-url", git_url + "#master"])
assert res.ok

# Verifies library remains installed
assert lib_install_dir.exists()


def test_install_with_zip_path(run_command, data_dir, downloads_dir):
# Initialize configs to enable --zip-path flag
env = {
Expand Down