diff --git a/internal/cli/modify.go b/internal/cli/modify.go index 31ab7805..dfeaa5a6 100644 --- a/internal/cli/modify.go +++ b/internal/cli/modify.go @@ -42,6 +42,7 @@ Modify the registration data of library name LIBRARY_NAME according to the FLAGs func init() { modifyCmd.Flags().String("repo-url", "", "New library repository URL") + modifyCmd.Flags().String("types", "", "New types list for the library's releases (comma separated)") rootCmd.AddCommand(modifyCmd) } diff --git a/internal/command/modify/modify.go b/internal/command/modify/modify.go index d80245af..a21315a7 100644 --- a/internal/command/modify/modify.go +++ b/internal/command/modify/modify.go @@ -27,6 +27,7 @@ package modify import ( "fmt" "os" + "strings" "github.com/arduino/go-paths-helper" "github.com/arduino/libraries-repository-engine/internal/backup" @@ -121,6 +122,10 @@ func modifications(flags *pflag.FlagSet) (bool, error) { if err != nil { return false, err } + newTypes, err := flags.GetString("types") + if err != nil { + return false, err + } if newRepositoryURL != "" { if err := modifyRepositoryURL(newRepositoryURL); err != nil { @@ -130,6 +135,14 @@ func modifications(flags *pflag.FlagSet) (bool, error) { didModify = true } + if newTypes != "" { + if err := modifyTypes(newTypes); err != nil { + return false, err + } + + didModify = true + } + if !didModify { return false, fmt.Errorf("No modification flags provided so nothing happened. See 'libraries-repository-engine modify --help'") } @@ -215,3 +228,48 @@ func modifyRepositoryURL(newRepositoryURL string) error { return nil } + +func modifyTypes(rawTypes string) error { + newTypes := strings.Split(rawTypes, ",") + for i := range newTypes { + newTypes[i] = strings.TrimSpace(newTypes[i]) + } + + sameTypes := func(oldTypes []string) bool { + if len(oldTypes) != len(newTypes) { + return false + } + + for _, oldType := range oldTypes { + found := false + for _, newType := range newTypes { + if oldType == newType { + found = true + break + } + } + if !found { + return false + } + } + + return true + } + + typesChanged := false + + for _, releaseData := range releasesData { + if !typesChanged { + // Compare old and new types for this release + typesChanged = !sameTypes(releaseData.Types) + } + + releaseData.Types = newTypes + } + + if !typesChanged { + return fmt.Errorf("Library %s already has types %s", libraryName, rawTypes) + } + + return nil +} diff --git a/test/test_modify.py b/test/test_modify.py index a434022b..f6ef6b64 100644 --- a/test/test_modify.py +++ b/test/test_modify.py @@ -333,3 +333,65 @@ def get_release_archive_url(name, version): ) assert canary_release_archive_path.exists() assert get_release_archive_url(name=canary_name, version=canary_release) == canary_release_archive_url + + +def test_types(configuration, run_command): + """Test the `--types` modification flag in action.""" + name = "SpacebrewYun" + raw_old_types = "Arduino" + raw_new_types = "Arduino, Retired" + canary_name = "Arduino Uno WiFi Dev Ed Library" + raw_canary_types = "Partner" + # Run the sync command to generate test data + engine_command = [ + "sync", + "--config-file", + configuration.path, + test_data_path.joinpath("test_modify", "test_types", "repos.txt"), + ] + result = run_command(cmd=engine_command) + assert result.ok + assert pathlib.Path(configuration.data["LibrariesDB"]).exists() + + def assert_types(name, raw_types): + with pathlib.Path(configuration.data["LibrariesDB"]).open(mode="r", encoding="utf-8") as library_db_file: + library_db = json.load(fp=library_db_file) + for release in library_db["Releases"]: + if release["LibraryName"] == name and release["Types"] != [ + raw_type.strip() for raw_type in raw_types.split(sep=",") + ]: + return False + return True + + # Verify the pre-command DB is as expected + assert assert_types(name=name, raw_types=raw_old_types) + assert assert_types(name=canary_name, raw_types=raw_canary_types) + + # Run the modification command with existing types + engine_command = [ + "modify", + "--config-file", + configuration.path, + "--types", + raw_old_types, + name, + ] + result = run_command(cmd=engine_command) + assert not result.ok + assert f"{name} already has types {raw_old_types}" in result.stderr + + # Run the modification command with existing types + engine_command = [ + "modify", + "--config-file", + configuration.path, + "--types", + raw_new_types, + name, + ] + result = run_command(cmd=engine_command) + assert result.ok + + # Verify the effect of the command was as expected + assert assert_types(name=name, raw_types=raw_new_types) + assert assert_types(name=canary_name, raw_types=raw_canary_types) diff --git a/test/testdata/test_modify/test_types/repos.txt b/test/testdata/test_modify/test_types/repos.txt new file mode 100644 index 00000000..c35693c1 --- /dev/null +++ b/test/testdata/test_modify/test_types/repos.txt @@ -0,0 +1,2 @@ +https://github.com/arduino-libraries/SpacebrewYun.git|Arduino|SpacebrewYun +https://github.com/arduino-libraries/UnoWiFi-Developer-Edition-Lib.git|Partner|Arduino Uno WiFi Dev Ed Library