support upgrading existing packages with empty mod get command
Signed-off-by: Tihomir Jovicic <tihomir.jovicic.develop@gmail.com>
This commit is contained in:
parent
2102e78c1f
commit
6a0b74416a
@ -10,6 +10,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
const filePath = "./cue.mod/dagger.mod.cue"
|
const filePath = "./cue.mod/dagger.mod.cue"
|
||||||
@ -20,6 +22,8 @@ const tmpBasePath = "./cue.mod/tmp"
|
|||||||
type file struct {
|
type file struct {
|
||||||
module string
|
module string
|
||||||
require []*require
|
require []*require
|
||||||
|
|
||||||
|
workspacePath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func readPath(workspacePath string) (*file, error) {
|
func readPath(workspacePath string) (*file, error) {
|
||||||
@ -33,6 +37,8 @@ func readPath(workspacePath string) (*file, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
modFile.workspacePath = workspacePath
|
||||||
|
|
||||||
return modFile, nil
|
return modFile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,8 +99,75 @@ func nonEmptyLines(b []byte) []string {
|
|||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *file) write(workspacePath string) error {
|
func (f *file) processRequire(req *require, upgrade bool) (bool, error) {
|
||||||
return ioutil.WriteFile(path.Join(workspacePath, filePath), f.contents().Bytes(), 0600)
|
var isNew bool
|
||||||
|
|
||||||
|
tmpPath := path.Join(f.workspacePath, tmpBasePath, req.repo)
|
||||||
|
if err := os.MkdirAll(tmpPath, 0755); err != nil {
|
||||||
|
return false, fmt.Errorf("error creating tmp dir for cloning package")
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmpPath)
|
||||||
|
|
||||||
|
// clone the repo
|
||||||
|
privateKeyFile := viper.GetString("private-key-file")
|
||||||
|
privateKeyPassword := viper.GetString("private-key-password")
|
||||||
|
r, err := clone(req, tmpPath, privateKeyFile, privateKeyPassword)
|
||||||
|
if err != nil {
|
||||||
|
return isNew, fmt.Errorf("error downloading package %s: %w", req, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
existing := f.search(req)
|
||||||
|
destPath := path.Join(f.workspacePath, destBasePath)
|
||||||
|
|
||||||
|
// requirement is new, so we should move the files and add it to the mod file
|
||||||
|
if existing == nil {
|
||||||
|
if err := move(req, tmpPath, destPath); err != nil {
|
||||||
|
return isNew, err
|
||||||
|
}
|
||||||
|
f.require = append(f.require, req)
|
||||||
|
isNew = true
|
||||||
|
return isNew, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if upgrade {
|
||||||
|
latestTag, err := r.latestTag()
|
||||||
|
if err != nil {
|
||||||
|
return isNew, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if latestTag == "" {
|
||||||
|
return isNew, fmt.Errorf("repo does not have a tag")
|
||||||
|
}
|
||||||
|
|
||||||
|
req.version = latestTag
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := compareVersions(existing.version, req.version)
|
||||||
|
if err != nil {
|
||||||
|
return isNew, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// the existing requirement is newer so we skip installation
|
||||||
|
if c > 0 {
|
||||||
|
return isNew, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// the new requirement is newer so we checkout the cloned repo to that tag, change the version in the existing
|
||||||
|
// requirement and replace the code in the /pkg folder
|
||||||
|
existing.version = req.version
|
||||||
|
if err = r.checkout(req.version); err != nil {
|
||||||
|
return isNew, err
|
||||||
|
}
|
||||||
|
if err = replace(req, tmpPath, destPath); err != nil {
|
||||||
|
return isNew, err
|
||||||
|
}
|
||||||
|
isNew = true
|
||||||
|
|
||||||
|
return isNew, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *file) write() error {
|
||||||
|
return ioutil.WriteFile(path.Join(f.workspacePath, filePath), f.contents().Bytes(), 0600)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *file) contents() *bytes.Buffer {
|
func (f *file) contents() *bytes.Buffer {
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
package mod
|
package mod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/hashicorp/go-version"
|
"github.com/hashicorp/go-version"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
@ -29,10 +25,6 @@ var getCmd = &cobra.Command{
|
|||||||
lg := logger.New()
|
lg := logger.New()
|
||||||
ctx := lg.WithContext(cmd.Context())
|
ctx := lg.WithContext(cmd.Context())
|
||||||
|
|
||||||
if len(args) == 0 {
|
|
||||||
lg.Fatal().Msg("need to specify package name in command argument")
|
|
||||||
}
|
|
||||||
|
|
||||||
workspace := common.CurrentWorkspace(ctx)
|
workspace := common.CurrentWorkspace(ctx)
|
||||||
st := common.CurrentEnvironmentState(ctx, workspace)
|
st := common.CurrentEnvironmentState(ctx, workspace)
|
||||||
doneCh := common.TrackWorkspaceCommand(ctx, cmd, workspace, st, &telemetry.Property{
|
doneCh := common.TrackWorkspaceCommand(ctx, cmd, workspace, st, &telemetry.Property{
|
||||||
@ -48,21 +40,28 @@ var getCmd = &cobra.Command{
|
|||||||
|
|
||||||
// parse packages to install
|
// parse packages to install
|
||||||
var packages []*require
|
var packages []*require
|
||||||
|
var upgrade bool
|
||||||
|
|
||||||
|
if len(args) == 0 {
|
||||||
|
lg.Info().Msg("upgrading installed packages...")
|
||||||
|
packages = modFile.require
|
||||||
|
upgrade = true
|
||||||
|
} else {
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
p, err := parseArgument(arg)
|
p, err := parseArgument(arg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lg.Error().Err(err).Msgf("error parsing package %s", arg)
|
lg.Error().Err(err).Msgf("error parsing package %s", arg)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
packages = append(packages, p)
|
packages = append(packages, p)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// download packages
|
// download packages
|
||||||
for _, p := range packages {
|
for _, p := range packages {
|
||||||
isNew, err := processRequire(workspace.Path, p, modFile)
|
isNew, err := modFile.processRequire(p, upgrade)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lg.Error().Err(err).Msg("error processing package")
|
lg.Error().Err(err).Msgf("error processing package %s", p.repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isNew {
|
if isNew {
|
||||||
@ -71,70 +70,14 @@ var getCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write to mod file in the current dir
|
// write to mod file in the current dir
|
||||||
if err = modFile.write(workspace.Path); err != nil {
|
if err = modFile.write(); err != nil {
|
||||||
lg.Error().Err(err).Msg("error writing to mod file")
|
lg.Error().Err(err).Msg("error writing to mod file")
|
||||||
}
|
}
|
||||||
|
|
||||||
lg.Info().Msg("checking for new versions...")
|
|
||||||
|
|
||||||
<-doneCh
|
<-doneCh
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func processRequire(workspacePath string, req *require, modFile *file) (bool, error) {
|
|
||||||
var isNew bool
|
|
||||||
|
|
||||||
tmpPath := path.Join(workspacePath, tmpBasePath, req.repo)
|
|
||||||
if err := os.MkdirAll(tmpPath, 0755); err != nil {
|
|
||||||
return false, fmt.Errorf("error creating tmp dir for cloning package")
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmpPath)
|
|
||||||
|
|
||||||
// clone the repo
|
|
||||||
privateKeyFile := viper.GetString("private-key-file")
|
|
||||||
privateKeyPassword := viper.GetString("private-key-password")
|
|
||||||
r, err := clone(req, tmpPath, privateKeyFile, privateKeyPassword)
|
|
||||||
if err != nil {
|
|
||||||
return isNew, fmt.Errorf("error downloading package %s: %w", req, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
existing := modFile.search(req)
|
|
||||||
destPath := path.Join(workspacePath, destBasePath)
|
|
||||||
|
|
||||||
// requirement is new, so we should move the files and add it to the mod file
|
|
||||||
if existing == nil {
|
|
||||||
if err := move(req, tmpPath, destPath); err != nil {
|
|
||||||
return isNew, err
|
|
||||||
}
|
|
||||||
modFile.require = append(modFile.require, req)
|
|
||||||
isNew = true
|
|
||||||
return isNew, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := compareVersions(existing.version, req.version)
|
|
||||||
if err != nil {
|
|
||||||
return isNew, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// the existing requirement is newer so we skip installation
|
|
||||||
if c > 0 {
|
|
||||||
return isNew, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// the new requirement is newer so we checkout the cloned repo to that tag, change the version in the existing
|
|
||||||
// requirement and replace the code in the /pkg folder
|
|
||||||
existing.version = req.version
|
|
||||||
if err = r.checkout(req.version); err != nil {
|
|
||||||
return isNew, err
|
|
||||||
}
|
|
||||||
if err = replace(req, tmpPath, destPath); err != nil {
|
|
||||||
return isNew, err
|
|
||||||
}
|
|
||||||
isNew = true
|
|
||||||
|
|
||||||
return isNew, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func compareVersions(reqV1, reqV2 string) (int, error) {
|
func compareVersions(reqV1, reqV2 string) (int, error) {
|
||||||
v1, err := version.NewVersion(reqV1)
|
v1, err := version.NewVersion(reqV1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -145,10 +88,15 @@ func compareVersions(reqV1, reqV2 string) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if v1.LessThan(v2) {
|
if v1.LessThan(v2) {
|
||||||
return -1, nil
|
return -1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v1.Equal(v2) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user