diff --git a/AUTHORS b/AUTHORS index 30ae7a2c..57e773ef 100644 --- a/AUTHORS +++ b/AUTHORS @@ -40,3 +40,4 @@ List of contributors, in chronological order: * Raphael Medaer (https://github.com/rmedaer) * Raul Benencia (https://github.com/rul) * Don Kuntz (https://github.com/dkuntz2) +* Joshua Colson (https://github.com/freakinhippie) diff --git a/cmd/repo_list.go b/cmd/repo_list.go index b2eea06b..91b820cc 100644 --- a/cmd/repo_list.go +++ b/cmd/repo_list.go @@ -1,6 +1,7 @@ package cmd import ( + "encoding/json" "fmt" "sort" @@ -16,8 +17,10 @@ func aptlyRepoList(cmd *commander.Command, args []string) error { } raw := cmd.Flag.Lookup("raw").Value.Get().(bool) + jsonFlag := cmd.Flag.Lookup("json").Value.Get().(bool) repos := make([]string, context.CollectionFactory().LocalRepoCollection().Len()) + jsonRepos := make([]*deb.LocalRepo, context.CollectionFactory().LocalRepoCollection().Len()) i := 0 context.CollectionFactory().LocalRepoCollection().ForEach(func(repo *deb.LocalRepo) error { if raw { @@ -28,7 +31,11 @@ func aptlyRepoList(cmd *commander.Command, args []string) error { return e } - repos[i] = fmt.Sprintf(" * %s (packages: %d)", repo.String(), repo.NumPackages()) + if jsonFlag { + jsonRepos[i] = repo + } else { + repos[i] = fmt.Sprintf(" * %s (packages: %d)", repo.String(), repo.NumPackages()) + } } i++ return nil @@ -36,13 +43,22 @@ func aptlyRepoList(cmd *commander.Command, args []string) error { context.CloseDatabase() - sort.Strings(repos) - if raw { + sort.Strings(repos) for _, repo := range repos { fmt.Printf("%s\n", repo) } + } else if jsonFlag { + sort.Slice(jsonRepos, func(i, j int) bool { + return jsonRepos[i].Name < jsonRepos[j].Name + }) + if output, e := json.MarshalIndent(jsonRepos, "", " "); e == nil { + fmt.Println(string(output)) + } else { + err = e + } } else { + sort.Strings(repos) if len(repos) > 0 { fmt.Printf("List of local repos:\n") for _, repo := range repos { @@ -72,6 +88,7 @@ Example: `, } + cmd.Flag.Bool("json", false, "display list in JSON format") cmd.Flag.Bool("raw", false, "display list in machine-readable format") return cmd diff --git a/cmd/repo_show.go b/cmd/repo_show.go index 7ca5b009..c97af570 100644 --- a/cmd/repo_show.go +++ b/cmd/repo_show.go @@ -1,8 +1,11 @@ package cmd import ( + "encoding/json" "fmt" + "sort" + "github.com/aptly-dev/aptly/deb" "github.com/smira/commander" "github.com/smira/flag" ) @@ -16,6 +19,9 @@ func aptlyRepoShow(cmd *commander.Command, args []string) error { name := args[0] + jsonFlag := cmd.Flag.Lookup("json").Value.Get().(bool) + withPackages := context.Flags().Lookup("with-packages").Value.Get().(bool) + repo, err := context.CollectionFactory().LocalRepoCollection().ByName(name) if err != nil { return fmt.Errorf("unable to show: %s", err) @@ -26,18 +32,42 @@ func aptlyRepoShow(cmd *commander.Command, args []string) error { return fmt.Errorf("unable to show: %s", err) } - fmt.Printf("Name: %s\n", repo.Name) - fmt.Printf("Comment: %s\n", repo.Comment) - fmt.Printf("Default Distribution: %s\n", repo.DefaultDistribution) - fmt.Printf("Default Component: %s\n", repo.DefaultComponent) - if repo.Uploaders != nil { - fmt.Printf("Uploaders: %s\n", repo.Uploaders) - } - fmt.Printf("Number of packages: %d\n", repo.NumPackages()) + if jsonFlag { + // include packages if requested + packageList := []string{} + if withPackages { + if repo.RefList() != nil { + var list *deb.PackageList + list, err = deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) + if err == nil { + packageList = list.Strings() // similar output to /api/{repo}/packages + } + } - withPackages := context.Flags().Lookup("with-packages").Value.Get().(bool) - if withPackages { - ListPackagesRefList(repo.RefList()) + sort.Strings(packageList) + } + + // merge the repo object with the package list + var output []byte + if output, err = json.MarshalIndent(struct { + *deb.LocalRepo + Packages []string + }{repo, packageList}, "", " "); err == nil { + fmt.Println(string(output)) + } + } else { + fmt.Printf("Name: %s\n", repo.Name) + fmt.Printf("Comment: %s\n", repo.Comment) + fmt.Printf("Default Distribution: %s\n", repo.DefaultDistribution) + fmt.Printf("Default Component: %s\n", repo.DefaultComponent) + if repo.Uploaders != nil { + fmt.Printf("Uploaders: %s\n", repo.Uploaders) + } + fmt.Printf("Number of packages: %d\n", repo.NumPackages()) + + if withPackages { + ListPackagesRefList(repo.RefList()) + } } return err @@ -57,6 +87,7 @@ ex: Flag: *flag.NewFlagSet("aptly-repo-show", flag.ExitOnError), } + cmd.Flag.Bool("json", false, "display record in JSON format") cmd.Flag.Bool("with-packages", false, "show list of packages") return cmd diff --git a/completion.d/_aptly b/completion.d/_aptly index b2c3a432..d4cffc53 100644 --- a/completion.d/_aptly +++ b/completion.d/_aptly @@ -285,6 +285,7 @@ local keyring="*-keyring=[gpg keyring to use when verifying Release file (could ;; list) _arguments '1:: :' \ + "-json=[display list in JSON format]:$bool" \ "-raw=[display list in machine−readable format]:$bool" ;; move) @@ -300,6 +301,7 @@ local keyring="*-keyring=[gpg keyring to use when verifying Release file (could ;; show) _arguments \ + "-json=[display record in JSON format]:$bool" \ "-with-packages=[show list of packages]:$bool" \ "(-)2:repo name:$repos" ;; diff --git a/completion.d/aptly b/completion.d/aptly index 088aac9f..bd1b64c3 100644 --- a/completion.d/aptly +++ b/completion.d/aptly @@ -314,7 +314,11 @@ _aptly() ;; "list") if [[ $numargs -eq 0 ]]; then - COMPREPLY=($(compgen -W "-raw" -- ${cur})) + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-raw -json" -- ${cur})) + else + COMPREPLY=($(compgen -W "$(__aptly_repo_list)" -- ${cur})) + fi return 0 fi ;; @@ -361,7 +365,7 @@ _aptly() "show") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then - COMPREPLY=($(compgen -W "-with-packages" -- ${cur})) + COMPREPLY=($(compgen -W "-json -with-packages" -- ${cur})) else COMPREPLY=($(compgen -W "$(__aptly_repo_list)" -- ${cur})) fi diff --git a/files/README.md b/files/README.md index 749bfa92..4a5b6421 100644 --- a/files/README.md +++ b/files/README.md @@ -12,7 +12,7 @@ This checksum is used to create a file tree where each package will reside, with ex: - sha256sum **476e0**cdac6bc757dd2b78bacc1325323b09c45ecb41d4562deec2a1c7c148405 my-package_1.2.3_all.deb + sha256sum **476e**0cdac6bc757dd2b78bacc1325323b09c45ecb41d4562deec2a1c7c148405 my-package_1.2.3_all.deb ```bash ${rootDir}/pool # rootDir defined in aptly.conf @@ -24,12 +24,12 @@ ${rootDir}/pool # rootDir defined in aptly.conf The following items are concatenated to form the filename under which package is stored. - 5th to the 31st characters of SHA-256 checksum - - "\_" (undescore) + - "\_" (undescore) - filename of uploaded _Debian_ as defined in [Debian package file names](https://www.debian.org/doc/manuals/debian-reference/ch02.en.html#_debian_package_file_names) ex: - sha256sum 476e0**cdac6bc757dd2b78bacc13253**23b09c45ecb41d4562deec2a1c7c148405 **my-package_1.2.3_all.deb** + sha256sum 476e**0cdac6bc757dd2b78bacc13253**23b09c45ecb41d4562deec2a1c7c148405 **my-package_1.2.3_all.deb** ``` 0cdac6bc757dd2b78bacc13253_my-package_1.2.3_all.deb diff --git a/system/t09_repo/ListRepo5Test_gold b/system/t09_repo/ListRepo5Test_gold new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/system/t09_repo/ListRepo5Test_gold @@ -0,0 +1 @@ +[] diff --git a/system/t09_repo/ListRepo6Test_gold b/system/t09_repo/ListRepo6Test_gold new file mode 100644 index 00000000..e0643ce9 --- /dev/null +++ b/system/t09_repo/ListRepo6Test_gold @@ -0,0 +1,20 @@ +[ + { + "Name": "repo1", + "Comment": "", + "DefaultDistribution": "", + "DefaultComponent": "main" + }, + { + "Name": "repo2", + "Comment": "Cool2", + "DefaultDistribution": "", + "DefaultComponent": "main" + }, + { + "Name": "repo3", + "Comment": "Cool3", + "DefaultDistribution": "", + "DefaultComponent": "main" + } +] diff --git a/system/t09_repo/ShowRepo4Test_gold b/system/t09_repo/ShowRepo4Test_gold new file mode 100644 index 00000000..3901d78a --- /dev/null +++ b/system/t09_repo/ShowRepo4Test_gold @@ -0,0 +1,7 @@ +{ + "Name": "repo1", + "Comment": "Cool", + "DefaultDistribution": "squeeze", + "DefaultComponent": "main", + "Packages": [] +} diff --git a/system/t09_repo/ShowRepo5Test_gold b/system/t09_repo/ShowRepo5Test_gold new file mode 100644 index 00000000..2bd1f17e --- /dev/null +++ b/system/t09_repo/ShowRepo5Test_gold @@ -0,0 +1,12 @@ +{ + "Name": "repo2", + "Comment": "Cool", + "DefaultDistribution": "wheezy", + "DefaultComponent": "contrib", + "Packages": [ + "Pi386 libboost-program-options-dev 1.49.0.1 918d2f433384e378", + "Pi386 libboost-program-options-dev 1.62.0.1 7760e62f99c551cb", + "Psource pyspi 0.6.1-1.3 3a8b37cbd9a3559e", + "Psource pyspi 0.6.1-1.4 f8f1daa806004e89" + ] +} diff --git a/system/t09_repo/list.py b/system/t09_repo/list.py index 9be862a2..6a8ed189 100644 --- a/system/t09_repo/list.py +++ b/system/t09_repo/list.py @@ -37,3 +37,20 @@ class ListRepo4Test(BaseTest): "aptly repo create repo1", ] runCmd = "aptly repo list -raw" + +class ListRepo5Test(BaseTest): + """ + list local repo: json no repos + """ + runCmd = "aptly repo list -json" + +class ListRepo6Test(BaseTest): + """ + list local repo: json normal + """ + fixtureCmds = [ + "aptly repo create -comment=Cool3 repo3", + "aptly repo create -comment=Cool2 repo2", + "aptly repo create repo1", + ] + runCmd = "aptly repo list -json" diff --git a/system/t09_repo/show.py b/system/t09_repo/show.py index c275c7fc..fc3d2132 100644 --- a/system/t09_repo/show.py +++ b/system/t09_repo/show.py @@ -26,3 +26,22 @@ class ShowRepo3Test(BaseTest): """ expectedCode = 1 runCmd = "aptly repo show repo3" + + +class ShowRepo4Test(BaseTest): + """ + show local repo: json regular + """ + fixtureCmds = ["aptly repo create -comment=Cool -distribution=squeeze repo1"] + runCmd = "aptly repo show -json repo1" + + +class ShowRepo5Test(BaseTest): + """ + show local repo: json -with-packages + """ + fixtureCmds = [ + "aptly repo create -comment=Cool -distribution=wheezy -component=contrib repo2", + "aptly repo add repo2 ${files}" + ] + runCmd = "aptly repo show -json -with-packages repo2"