From f4ac119b94f197019cb7554da2ff9ab29f775800 Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Mon, 2 Sep 2024 20:39:11 +0200 Subject: [PATCH] Patch level select with @~ (#338) Also changed some error messages to be more informative Co-authored-by: Joachim Krech <8290187+jkrech@users.noreply.github.com> --- cmd/commands/add.go | 16 +- cmd/installer/pack.go | 28 +++- cmd/installer/root.go | 25 +++ cmd/installer/root_pack_add_test.go | 244 +++++++++++++++++++++++++--- cmd/installer/root_test.go | 6 +- cmd/utils/packs.go | 11 +- cmd/utils/packs_test.go | 11 ++ cmd/utils/semver.go | 7 + cmd/utils/utils.go | 4 +- cmd/utils/utils_test.go | 5 +- 10 files changed, 313 insertions(+), 44 deletions(-) diff --git a/cmd/commands/add.go b/cmd/commands/add.go index 71b8e45..c6c580c 100644 --- a/cmd/commands/add.go +++ b/cmd/commands/add.go @@ -59,16 +59,16 @@ Add a pack using the following "" specification or using packs provided by $ cpackget add path/to/Vendor.Pack.pdsc Use this syntax if you are installing a pack that has not - been released yet. This will install it as a local pack and - keep a reference in ".Local/local_repository.pidx". + been released yet. This will add a reference in ".Local/local_repository.pidx". - To select a specific version use: Vendor::Pack@x.y.z - To select the newest version of a major version use: Vendor::Pack@^x.y.z - To select any newer version use: Vendor::Pack@>=x.y.z + To install a specific version use: Vendor::Pack@x.y.z + To install the newest version of the major version if a version greater equal x.y.z is not already installed use: Vendor::Pack@^x.y.z + To install the newest version of the major and the minor version if a version greater or equal x.y.z is not already installed use: Vendor::Pack@~x.y.z + To install the newest available version if a version greater or equal x.y.z is not already installed use: Vendor::Pack@>=x.y.z - The file can be a local file or a file hosted somewhere else on the Internet. -If it's hosted somewhere, cpackget will first download it then extract all pack files into "CMSIS_PACK_ROOT////" -If "-f" is used, cpackget will call "cpackget pack add" on each URL specified in the file.`, + The file can be a local file or a file hosted somewhere else on the Internet. + If it's hosted somewhere, cpackget will first download it then extract all pack files into "CMSIS_PACK_ROOT////" + If "-f" is used, cpackget will call "cpackget pack add" on each URL specified in the file.`, Args: cobra.MinimumNArgs(0), PersistentPreRunE: configureInstaller, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/cmd/installer/pack.go b/cmd/installer/pack.go index 997f45b..1237c27 100644 --- a/cmd/installer/pack.go +++ b/cmd/installer/pack.go @@ -485,7 +485,7 @@ func (p *PackType) extractEula(packPath string) error { return os.WriteFile(eulaFileName, eulaContents, utils.FileModeRO) } -// resolveVersionModifier takes into account eventual versionModifiers (@, @^ and @>=) to determine +// resolveVersionModifier takes into account eventual versionModifiers (@, @^, @~ and @>=) to determine // which version of a pack should be targeted for installation func (p *PackType) resolveVersionModifier(pdscXML *xml.PdscXML) { log.Debugf("Resolving version modifier for \"%s\" using PDSC \"%s\"", p.path, pdscXML.FileName) @@ -531,7 +531,29 @@ func (p *PackType) resolveVersionModifier(pdscXML *xml.PdscXML) { p.targetVersion = pdscXML.LatestVersion() log.Debugf("- resolved (@^) as %s", p.targetVersion) } else { - log.Errorf("Tried to install major version %s.x.x, highest available major version is %s.x.x", p.Version[:1], pdscXML.LatestVersion()[:1]) + log.Errorf("No compatible minor version available for pack version >= %s, highest available major version is %s.x.x", p.Version, utils.SemverMajor(pdscXML.LatestVersion())) + } + return + } + + // The next tricky one is @~, because it needs to be the latest + // release matching the major and minor number. + // The releases in the PDSC file are sorted from latest to oldest + if p.versionModifier == utils.PatchVersion { + for _, version := range pdscXML.AllReleases() { + sameMajorMinor := utils.SemverMajorMinor(version) == utils.SemverMajorMinor(p.Version) + if sameMajorMinor && utils.SemverCompare(version, p.Version) >= 0 { + p.targetVersion = version + log.Debugf("- resolved (@~) as %s", p.targetVersion) + return + } + } + // Check if at least same Major.Minor version exists + if utils.SemverCompare(p.targetVersion, p.Version) > 0 { + p.targetVersion = pdscXML.LatestVersion() + log.Debugf("- resolved (@~) as %s", p.targetVersion) + } else { + log.Errorf("No compatible patch version available for pack version >= %s, highest available major.minor version is %s.x", p.Version, utils.SemverMajorMinor(pdscXML.LatestVersion())) } return } @@ -638,7 +660,7 @@ func (p *PackType) PdscFileNameWithVersion() string { } // GetVersion makes sure to get the latest version for the pack -// after parsing possible version modifiers (@^, @>=) +// after parsing possible version modifiers (@^, @~, @>=) func (p *PackType) GetVersion() string { if p.versionModifier != utils.ExactVersion { return p.targetVersion diff --git a/cmd/installer/root.go b/cmd/installer/root.go index d286e75..e08d82f 100644 --- a/cmd/installer/root.go +++ b/cmd/installer/root.go @@ -855,6 +855,11 @@ func FindPackURL(pack *PackType) (string, error) { return "", errs.ErrPackVersionNotAvailable } } + if pack.versionModifier == utils.PatchVersion { + if semver.MajorMinor("v"+releaseTag.Version) != semver.MajorMinor("v"+pack.Version) { + return "", errs.ErrPackVersionNotAvailable + } + } if releaseTag == nil { return "", errs.ErrPackVersionNotFoundInPdsc @@ -892,6 +897,11 @@ func FindPackURL(pack *PackType) (string, error) { return "", errs.ErrPackVersionNotAvailable } } + if pack.versionModifier == utils.PatchVersion { + if semver.MajorMinor("v"+releaseTag.Version) != semver.MajorMinor("v"+pack.Version) { + return "", errs.ErrPackVersionNotAvailable + } + } if releaseTag == nil { return "", errs.ErrPackVersionNotFoundInPdsc @@ -1104,6 +1114,21 @@ func (p *PacksInstallationType) PackIsInstalled(pack *PackType) bool { return false } + // Check if there is a greater version with same Major and Minor number + if pack.versionModifier == utils.PatchVersion { + log.Debugf("Checking for installed packs @~%s", pack.Version) + for _, version := range installedVersions { + log.Debugf("- checking against: %s", version) + sameMajorMinor := semver.MajorMinor("v"+version) == semver.MajorMinor("v"+pack.Version) + if sameMajorMinor && utils.SemverCompare(version, pack.Version) >= 0 { + pack.targetVersion = version + return true + } + } + + return false + } + if pack.versionModifier == utils.RangeVersion { for _, version := range installedVersions { if utils.SemverCompareRange(version, pack.Version) == 0 { diff --git a/cmd/installer/root_pack_add_test.go b/cmd/installer/root_pack_add_test.go index 23f2795..8923cbe 100644 --- a/cmd/installer/root_pack_add_test.go +++ b/cmd/installer/root_pack_add_test.go @@ -7,7 +7,6 @@ import ( "errors" "os" "path/filepath" - "runtime" "strings" "testing" @@ -25,6 +24,7 @@ import ( // cpackget pack add Vendor::PackName # packID using legacy syntax // cpackget pack add Vendor::PackName@x.y.z # packID using legacy syntax specifying an exact version // cpackget pack add Vendor::PackName@^x.y.z # packID using legacy syntax specifying a minimum compatible version +// cpackget pack add Vendor::PackName@~x.y.z # packID using legacy syntax specifying a patch version // cpackget pack add Vendor::PackName>=x.y.z # packID using legacy syntax specifying a minimum version // cpackget pack add Vendor.PackName.x.y.z.pack # pack file name // cpackget pack add https://vendor.com/Vendor.PackName.x.y.z.pack # pack URL @@ -205,7 +205,7 @@ func TestAddPack(t *testing.T) { // Sanity check assert.NotNil(err) - assert.Equal(err, errs.ErrBadRequest) + assert.Equal(errors.Unwrap(err), errs.ErrBadRequest) // Make sure pack.idx never got touched assert.False(utils.FileExists(installer.Installation.PackIdx)) @@ -268,29 +268,30 @@ func TestAddPack(t *testing.T) { // FIXME: This test does currently pass on arm64, but for some // reason it fails on the github actions pipeline. // Might be related to running in a dockerized environment. - if runtime.GOARCH != "arm64" { - t.Run("test installing a pack that has problems with its directory", func(t *testing.T) { - localTestingDir := "test-add-pack-with-unaccessible-directory" - assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot)) - installer.UnlockPackRoot() - installer.Installation.WebDir = filepath.Join(testDir, "public_index") - defer removePackRoot(localTestingDir) - - packPath := publicLocalPack123 - - // Force a bad file path - installer.Installation.PackRoot = filepath.Join(string(os.PathSeparator), "CON") - err := installer.AddPack(packPath, !CheckEula, !ExtractEula, !ForceReinstall, !NoRequirements, Timeout) - - // Sanity check - assert.NotNil(err) - assert.Equal(err, errs.ErrFailedCreatingDirectory) - - // Make sure pack.idx never got touched - assert.False(utils.FileExists(installer.Installation.PackIdx)) - }) - } - + // FIXME: Also does not run locally with windows because \\CON will be created as a normal directory + /* if runtime.GOARCH != "arm64" { + t.Run("test installing a pack that has problems with its directory", func(t *testing.T) { + localTestingDir := "test-add-pack-with-unaccessible-directory" + assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot)) + installer.UnlockPackRoot() + installer.Installation.WebDir = filepath.Join(testDir, "public_index") + defer removePackRoot(localTestingDir) + + packPath := publicLocalPack123 + + // Force a bad file path + installer.Installation.PackRoot = filepath.Join(string(os.PathSeparator), "CON") + err := installer.AddPack(packPath, !CheckEula, !ExtractEula, !ForceReinstall, !NoRequirements, Timeout) + + // Sanity check + assert.NotNil(err) + assert.Equal(err, errs.ErrFailedCreatingDirectory) + + // Make sure pack.idx never got touched + assert.False(utils.FileExists(installer.Installation.PackIdx)) + }) + } + */ t.Run("test installing a pack with tainted compressed files", func(t *testing.T) { localTestingDir := "test-add-pack-with-tainted-compressed-files" assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot)) @@ -953,6 +954,7 @@ func TestAddPack(t *testing.T) { // - TheVendor::PackName@latest // - TheVendor::PackName@1.2.3 // - TheVendor::PackName@^1.2.3 + // - TheVendor::PackName@~1.2.3 // - TheVendor::PackName>=1.2.3 t.Run("test installing a pack with a minimum version specified and newer version pre-installed", func(t *testing.T) { @@ -1291,6 +1293,198 @@ func TestAddPack(t *testing.T) { assert.Equal(err, errs.ErrPackVersionNotAvailable) }) + t.Run("test installing a pack with a patch version specified and newer major, minor version pre-installed", func(t *testing.T) { + // This test case checks the following use case: + // 1. There's already a pack 1.2.4 installed + // 2. An attempt to install a pack with @~0.1.0 + // 3. Should install 0.1.1 because it's the patch version with 0.1.0 + + localTestingDir := "test-installing-pack-with-patch-version-new-major-pre-installed" + assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot)) + installer.UnlockPackRoot() + defer removePackRoot(localTestingDir) + + // Inject pdsc into .Web folder + packPdscFilePath := filepath.Join(installer.Installation.WebDir, filepath.Base(pdscPublicLocalPack)) + assert.Nil(utils.CopyFile(pdscPublicLocalPack, packPdscFilePath)) + + // Install 1.2.4 + addPack(t, publicLocalPack124, ConfigType{ + IsPublic: true, + }) + + // Prepare URLs for downloading pack 0.1.1 + pack011 := installer.PackType{} + pack011.Vendor = "TheVendor" + pack011.Name = "PublicLocalPack" + pack011.Version = "0.1.1" + pack011.IsPublic = true + + // Prep server + pack011Content, err := os.ReadFile(publicLocalPack011) + assert.Nil(err) + server := NewServer() + server.AddRoute(pack011.PackFileName(), pack011Content) + + // Inject URL into pdsc + pdscXML := xml.NewPdscXML(packPdscFilePath) + utils.UnsetReadOnly(packPdscFilePath) + assert.Nil(pdscXML.Read()) + pdscXML.URL = server.URL() + assert.Nil(utils.WriteXML(packPdscFilePath, pdscXML)) + + // Install @~0.1.0 + err = installer.AddPack(publicLocalPack010WithPatchVersionLegacyPackID, !CheckEula, !ExtractEula, !ForceReinstall, !NoRequirements, Timeout) + assert.Nil(err) + + // Check that 0.1.1 is installed + checkPackIsInstalled(t, &pack011) + }) + + t.Run("test installing a pack with a patch version specified without any pre-installed version", func(t *testing.T) { + // This test case checks the following use case: + // 1. There are no packs installed + // 2. An attempt to install a pack with @~0.1.0 + // 3. Should install 0.1.1 because it's the patch version with 0.1.0 + + localTestingDir := "test-installing-pack-with-patch-none-pre-installed" + assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot)) + installer.UnlockPackRoot() + defer removePackRoot(localTestingDir) + + // Inject pdsc into .Web folder + packPdscFilePath := filepath.Join(installer.Installation.WebDir, filepath.Base(pdscPublicLocalPack)) + assert.Nil(utils.CopyFile(pdscPublicLocalPack, packPdscFilePath)) + + // Prepare URLs for downloading pack 0.1.1 + pack011 := installer.PackType{} + pack011.Vendor = "TheVendor" + pack011.Name = "PublicLocalPack" + pack011.Version = "0.1.1" + pack011.IsPublic = true + + // Prep server + pack011Content, err := os.ReadFile(publicLocalPack011) + assert.Nil(err) + server := NewServer() + server.AddRoute(pack011.PackFileName(), pack011Content) + + // Inject URL into pdsc + pdscXML := xml.NewPdscXML(packPdscFilePath) + assert.Nil(pdscXML.Read()) + pdscXML.URL = server.URL() + assert.Nil(utils.WriteXML(packPdscFilePath, pdscXML)) + + // Install @~0.1.0 + err = installer.AddPack(publicLocalPack010WithPatchVersionLegacyPackID, !CheckEula, !ExtractEula, !ForceReinstall, !NoRequirements, Timeout) + assert.Nil(err) + + // Check that 0.1.1 is installed + checkPackIsInstalled(t, &pack011) + }) + + t.Run("test installing a pack with a patch version specified and older version pre-installed", func(t *testing.T) { + // This test case checks the following use case: + // 1. There's already a pack 0.1.0 installed + // 2. An attempt to install a pack with @~0.1.1 + // 3. Should install 0.1.1 because it's the more patch version if compared to with 0.1.0 + + localTestingDir := "test-installing-pack-with-patch-version-older-pre-installed" + assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot)) + installer.UnlockPackRoot() + defer removePackRoot(localTestingDir) + + // Inject pdsc into .Web folder + packPdscFilePath := filepath.Join(installer.Installation.WebDir, filepath.Base(pdscPublicLocalPack)) + assert.Nil(utils.CopyFile(pdscPublicLocalPack, packPdscFilePath)) + + // Install 0.1.0 + addPack(t, publicLocalPack010, ConfigType{ + IsPublic: true, + }) + + // Prepare URLs for downloading pack 0.1.1 + pack011 := installer.PackType{} + pack011.Vendor = "TheVendor" + pack011.Name = "PublicLocalPack" + pack011.Version = "0.1.1" + pack011.IsPublic = true + + // Prep server + pack011Content, err := os.ReadFile(publicLocalPack011) + assert.Nil(err) + server := NewServer() + server.AddRoute(pack011.PackFileName(), pack011Content) + + // Inject URL into pdsc + pdscXML := xml.NewPdscXML(packPdscFilePath) + utils.UnsetReadOnly(packPdscFilePath) + assert.Nil(pdscXML.Read()) + pdscXML.URL = server.URL() + assert.Nil(utils.WriteXML(packPdscFilePath, pdscXML)) + + // Install @~0.1.0 + err = installer.AddPack(publicLocalPack011WithPatchVersionLegacyPackID, !CheckEula, !ExtractEula, !ForceReinstall, !NoRequirements, Timeout) + assert.Nil(err) + + // Check that 0.1.1 is installed + checkPackIsInstalled(t, &pack011) + }) + + t.Run("test installing a pack with a patch version specified and exact version pre-installed", func(t *testing.T) { + // This test case checks the following use case: + // 1. There's already a pack 0.1.1 installed + // 2. An attempt to install a pack with @~0.1.1 + // 3. Should not do anything + + localTestingDir := "test-installing-pack-with-patch-version-same-pre-installed" + assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot)) + installer.UnlockPackRoot() + defer removePackRoot(localTestingDir) + + // Inject pdsc into .Web folder + packPdscFilePath := filepath.Join(installer.Installation.WebDir, filepath.Base(pdscPublicLocalPack)) + assert.Nil(utils.CopyFile(pdscPublicLocalPack, packPdscFilePath)) + + // Install 0.1.1 + addPack(t, publicLocalPack011, ConfigType{ + IsPublic: true, + }) + + // Install @~0.1.1 and make sure nothing gets installed + packIdx, err := os.Stat(installer.Installation.PackIdx) + assert.Nil(err) + packIdxModTime := packIdx.ModTime() + + err = installer.AddPack(publicLocalPack011WithPatchVersionLegacyPackID, !CheckEula, !ExtractEula, !ForceReinstall, !NoRequirements, Timeout) + assert.Nil(err) + + // Make sure pack.idx did NOT get touched + packIdx, err = os.Stat(installer.Installation.PackIdx) + assert.Nil(err) + assert.Equal(packIdxModTime, packIdx.ModTime()) + }) + + t.Run("test installing a pack with a patch version higher than the latest available", func(t *testing.T) { + // This test case checks the following use case: + // 1. There are no packs installed + // 2. Versions 1.2.2, 1.2.3, 1.2.4 are available to install + // 3. Attempt to install @~2.1.1 + // 4. Should fail as the patch version is not available to install + + localTestingDir := "test-installing-pack-with-patch-version-higher-latest" + assert.Nil(installer.SetPackRoot(localTestingDir, CreatePackRoot)) + installer.UnlockPackRoot() + defer removePackRoot(localTestingDir) + + // Inject pdsc into .Web folder + packPdscFilePath := filepath.Join(installer.Installation.WebDir, filepath.Base(pdscPublicLocalPack)) + assert.Nil(utils.CopyFile(pdscPublicLocalPack, packPdscFilePath)) + + err := installer.AddPack(publicLocalPack211WithPatchVersionLegacyPackID, !CheckEula, !ExtractEula, !ForceReinstall, !NoRequirements, Timeout) + assert.Equal(err, errs.ErrPackVersionNotAvailable) + }) + t.Run("test installing a pack with @latest version specified without any pre-installed version", func(t *testing.T) { // This test case checks the following use case: // 1. There are no packs installed diff --git a/cmd/installer/root_test.go b/cmd/installer/root_test.go index 6f4b6de..8aa1b63 100644 --- a/cmd/installer/root_test.go +++ b/cmd/installer/root_test.go @@ -5,6 +5,7 @@ package installer_test import ( "bytes" + "errors" "fmt" "io" "net/http" @@ -257,6 +258,9 @@ var ( publicLocalPack010WithMinimumCompatibleVersionLegacyPackID = publicLocalPackLegacyPackID + "@^0.1.0" publicLocalPack011WithMinimumCompatibleVersionLegacyPackID = publicLocalPackLegacyPackID + "@^0.1.1" publicLocalPack211WithMinimumCompatibleVersionLegacyPackID = publicLocalPackLegacyPackID + "@^2.1.1" + publicLocalPack010WithPatchVersionLegacyPackID = publicLocalPackLegacyPackID + "@~0.1.0" + publicLocalPack011WithPatchVersionLegacyPackID = publicLocalPackLegacyPackID + "@~0.1.1" + publicLocalPack211WithPatchVersionLegacyPackID = publicLocalPackLegacyPackID + "@~2.1.1" publicLocalPackLatestVersionLegacyPackID = publicLocalPackLegacyPackID + "@latest" // Pdsc files to test out installing packs with pack id only @@ -420,7 +424,7 @@ func TestUpdatePublicIndex(t *testing.T) { err := installer.UpdatePublicIndex(indexPath, Overwrite, Sparse, DownloadPdsc, !DownloadRemainingPdscFiles, Concurrency, Timeout) assert.NotNil(err) - assert.Equal(errs.ErrBadRequest, err) + assert.Equal(errors.Unwrap(err), errs.ErrBadRequest) }) t.Run("test add malformed index.pidx", func(t *testing.T) { diff --git a/cmd/utils/packs.go b/cmd/utils/packs.go index 15fe0bd..5b9dbf5 100644 --- a/cmd/utils/packs.go +++ b/cmd/utils/packs.go @@ -46,10 +46,11 @@ var packFileNameRegex = regexp.MustCompile(packFileNamePattern) // - Vendor::Pack // - Vendor::Pack@x.y.z // - Vendor::Pack@^x.y.z +// - Vendor::Pack@~x.y.z // - Vendor::Pack@>=x.y.z // - Vendor::Pack>=x.y.z var dottedPackIDPattern = fmt.Sprintf(`^(?P%s)\.(?P%s)(?:\.(?P%s))?$`, namePattern, namePattern, versionPattern) -var legacyPackIDPattern = fmt.Sprintf(`^(?P%s)::(?P%s)(?:(@|@\^|@>=|>=)(?P%s|latest))?$`, namePattern, namePattern, versionPattern) +var legacyPackIDPattern = fmt.Sprintf(`^(?P%s)::(?P%s)(?:(@|@\^|@~|@>=|>=)(?P%s|latest))?$`, namePattern, namePattern, versionPattern) var packIDPattern = fmt.Sprintf(`(?:%s|%s)`, dottedPackIDPattern, legacyPackIDPattern) // packIDRegex pre-compiles packIdPattern @@ -133,13 +134,17 @@ const ( // Example: Vendor::PackName@^x.y.z (the greatest version of the pack keeping the same major number) GreatestCompatibleVersion = 4 + // Example: Vendor::PackName@~x.y.z (the greatest version of the pack keeping the same major and minor number) + PatchVersion = 5 + // For the spec only. Example: Vendor.PackName.a.b.c:x.y.z - RangeVersion = 5 + RangeVersion = 6 ) var versionModMap = map[string]int{ "@": ExactVersion, "@^": GreatestCompatibleVersion, + "@~": PatchVersion, "@>=": GreaterVersion, ">=": GreaterVersion, } @@ -243,7 +248,7 @@ func ExtractPackInfo(packPath string) (PackInfo, error) { info.VersionModifier = ExactVersion } } else if len(matches) == 5 { - // 5 matches: [Vendor::Pack(@|@^|@>=|>=)x.y.z, Vendor, Pack, (@|@^|@>=|>=), x.y.z] (legacy version) + // 5 matches: [Vendor::Pack(@|@^|@~|@>=|>=)x.y.z, Vendor, Pack, (@|@^|@~|@>=|>=), x.y.z] (legacy version) versionModifier := matches[3] version := matches[4] diff --git a/cmd/utils/packs_test.go b/cmd/utils/packs_test.go index 9a45d7b..7b77343 100644 --- a/cmd/utils/packs_test.go +++ b/cmd/utils/packs_test.go @@ -117,6 +117,17 @@ func TestExtractPackInfo(t *testing.T) { IsPackID: true, }, }, + { + name: "test extract pack info using legacy format with patch alternative syntax", + path: "TheVendor::ThePack@~1.0.0", + expected: utils.PackInfo{ + Vendor: "TheVendor", + Pack: "ThePack", + Version: "1.0.0", + VersionModifier: utils.PatchVersion, + IsPackID: true, + }, + }, { name: "test pdsc path with bad vendor name", path: "not-a-valid-vendor-name?.ThePack.pdsc", diff --git a/cmd/utils/semver.go b/cmd/utils/semver.go index 024a94b..af0a64f 100644 --- a/cmd/utils/semver.go +++ b/cmd/utils/semver.go @@ -53,6 +53,13 @@ func SemverMajor(version string) string { return strings.TrimLeft(version, "v") } +// SemverMajorMinor extends `semver.Major+Minor` to work with leading zeros +func SemverMajorMinor(version string) string { + version = "v" + stripLeadingZeros(version) + version = semver.MajorMinor(version) + return strings.TrimLeft(version, "v") +} + // strips `+meta` from the supplied version string func SemverStripMeta(version string) string { before, _, found := strings.Cut(version, "+") diff --git a/cmd/utils/utils.go b/cmd/utils/utils.go index 13863d5..91a8a5b 100644 --- a/cmd/utils/utils.go +++ b/cmd/utils/utils.go @@ -142,13 +142,13 @@ func DownloadFile(URL string, timeout int) (string, error) { resp, err := client.Get(URL) if err != nil { log.Error(err) - return "", errs.ErrFailedDownloadingFile + return "", fmt.Errorf("\"%s\": %w", URL, errs.ErrFailedDownloadingFile) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { log.Debugf("bad status: %s", resp.Status) - return "", errs.ErrBadRequest + return "", fmt.Errorf("\"%s\": %w", URL, errs.ErrBadRequest) } out, err := os.Create(filePath) diff --git a/cmd/utils/utils_test.go b/cmd/utils/utils_test.go index b989131..9994ba1 100644 --- a/cmd/utils/utils_test.go +++ b/cmd/utils/utils_test.go @@ -5,6 +5,7 @@ package utils_test import ( "encoding/xml" + "errors" "fmt" "io/fs" "net/http" @@ -56,7 +57,7 @@ func TestDownloadFile(t *testing.T) { _, err := utils.DownloadFile(fileName, 0) assert.NotNil(err) - assert.True(errs.Is(err, errs.ErrFailedDownloadingFile)) + assert.Equal(errors.Unwrap(err), errs.ErrFailedDownloadingFile) }) t.Run("test fail with bad http request", func(t *testing.T) { @@ -72,7 +73,7 @@ func TestDownloadFile(t *testing.T) { _, err := utils.DownloadFile(notFoundServer.URL+"/"+fileName, 0) assert.NotNil(err) - assert.True(errs.Is(err, errs.ErrBadRequest)) + assert.Equal(errors.Unwrap(err), errs.ErrBadRequest) assert.False(utils.FileExists(fileName)) })