Skip to content

Commit

Permalink
feat: Added a subcommand show for pkg
Browse files Browse the repository at this point in the history
Signed-off-by: sahil <mohdssahil1@gmail.com>
  • Loading branch information
MdSahil-oss committed Jul 10, 2023
1 parent 3f3ded3 commit baf8395
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 8 deletions.
2 changes: 2 additions & 0 deletions cmd/kraft/pkg/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"kraftkit.sh/cmd/kraft/pkg/list"
"kraftkit.sh/cmd/kraft/pkg/pull"
"kraftkit.sh/cmd/kraft/pkg/push"
"kraftkit.sh/cmd/kraft/pkg/show"
"kraftkit.sh/cmd/kraft/pkg/source"
"kraftkit.sh/cmd/kraft/pkg/unsource"
"kraftkit.sh/cmd/kraft/pkg/update"
Expand Down Expand Up @@ -80,6 +81,7 @@ func New() *cobra.Command {
cmd.AddCommand(source.New())
cmd.AddCommand(unsource.New())
cmd.AddCommand(update.New())
cmd.AddCommand(show.New())

return cmd
}
Expand Down
95 changes: 95 additions & 0 deletions cmd/kraft/pkg/show/show.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package show

import (
"encoding/json"
"fmt"
"reflect"
"strings"

"github.com/MakeNowJust/heredoc"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
"kraftkit.sh/cmdfactory"
"kraftkit.sh/iostreams"
"kraftkit.sh/manifest"
"kraftkit.sh/packmanager"
)

type Show struct {
Output string `long:"output" short:"o" usage:"Set output format" default:"yaml"`
Cache bool `long:"local" short:"l" usage:"Search package details locally" default:"false"`
}

func New() *cobra.Command {
cmd, err := cmdfactory.New(&Show{}, cobra.Command{
Short: "Shows a Unikraft package",
Use: "show [FLAGS] [PACKAGE|DIR]",
Aliases: []string{"sw"},
Long: heredoc.Doc(`
Shows a Unikraft package like library, core etc details
`),
Example: heredoc.Doc(`
# Shows details for the library nginx
$ kraft pkg show nginx`),
Annotations: map[string]string{
cmdfactory.AnnotationHelpGroup: "pkg",
},
})
if err != nil {
panic(err)
}

return cmd
}

func (opts *Show) Pre(cmd *cobra.Command, _ []string) error {
ctx := cmd.Context()
pm, err := packmanager.NewUmbrellaManager(ctx)
if err != nil {
return err
}

cmd.SetContext(packmanager.WithPackageManager(ctx, pm))

return nil
}

func (opts *Show) Run(cmd *cobra.Command, args []string) error {
opts.Output = strings.ToLower(opts.Output)
if len(args) == 0 {
return fmt.Errorf("Package name is not specified to show information")
} else if opts.Output != "json" && opts.Output != "yaml" {
return fmt.Errorf("Specified output format is not supported")
}

ctx := cmd.Context()

metadata, err := packmanager.G(ctx).Show(ctx, opts.Output, packmanager.WithCache(opts.Cache), packmanager.WithName(args[0]))

if metadata != nil {
var byteCode []byte
var manifestStruct *manifest.Manifest
if opts.Cache {
manifestStruct, err = manifest.NewManifestFromFile(ctx, reflect.ValueOf(metadata).Elem().FieldByName("Origin").String())
} else {
manifestStruct, err = manifest.NewManifestFromURL(ctx, reflect.ValueOf(metadata).Elem().FieldByName("Origin").String())
}
if err != nil {
return err
}
if opts.Output == "json" {
byteCode, err = json.Marshal(manifestStruct)
} else {
byteCode, err = yaml.Marshal(manifestStruct)
}
if err != nil {
return err
}
fmt.Fprint(iostreams.G(ctx).Out, string(byteCode)+"\n")
}
if err != nil {
return err
}

return nil
}
4 changes: 4 additions & 0 deletions manifest/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,3 +397,7 @@ func (m *manifestManager) LocalManifestIndex(ctx context.Context) string {
func (m *manifestManager) Format() pack.PackageFormat {
return ManifestFormat
}

func (m *manifestManager) Show(ctx context.Context, outputFormat string, qopts ...packmanager.QueryOption) (any, error) {
return nil, fmt.Errorf("Show is not implemented for manifestManager")
}
16 changes: 8 additions & 8 deletions manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,32 @@ import (

type Manifest struct {
// Name of the entity which this manifest represents
Name string `yaml:"name"`
Name string `yaml:"name" json:"name"`

// Type of entity which this manifest represetns
Type unikraft.ComponentType `yaml:"type"`
Type unikraft.ComponentType `yaml:"type" json:"type"`

// Manifest is used to point to remote manifest, allowing the manifest itself
// to be retrieved by indirection. Manifest is XOR with Versions and should
// be back-propagated.
Manifest string `yaml:"manifest,omitempty"`
Manifest string `yaml:"manifest,omitempty" json:"manifest,omitempty"`

// Description of what this manifest represents
Description string `yaml:"description,omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`

// Origin represents where (and therefore how) this manifest was populated
Origin string `yaml:"origin,omitempty"`
Origin string `yaml:"origin,omitempty" json:"origin,omitempty"`

// Provider is the string name of the underlying implementation providing the
// contents of this manifest
Provider Provider `yaml:"provider,omitempty"`
Provider Provider `yaml:"provider,omitempty" json:"provider,omitempty"`

// Channels provides multiple ways to retrieve versions. Classically this is
// a separation between "staging" and "stable"
Channels []ManifestChannel `yaml:"channels,omitempty"`
Channels []ManifestChannel `yaml:"channels,omitempty" json:"channels,omitempty"`

// Versions
Versions []ManifestVersion `yaml:"versions,omitempty"`
Versions []ManifestVersion `yaml:"versions,omitempty" json:"versions,omitempty"`

// mopts contains additional configuration used within the implementation that
// are non-exportable attributes and variables.
Expand Down
4 changes: 4 additions & 0 deletions oci/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,3 +440,7 @@ func (manager *ociManager) From(pack.PackageFormat) (packmanager.PackageManager,
func (manager *ociManager) Format() pack.PackageFormat {
return OCIFormat
}

func (manager *ociManager) Show(ctx context.Context, outputFormat string, qopts ...packmanager.QueryOption) (any, error) {
return nil, fmt.Errorf("Show is not implemented for ociManager")
}
3 changes: 3 additions & 0 deletions packmanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,7 @@ type PackageManager interface {

// Format returns the name of the implementation.
Format() pack.PackageFormat

// Show package information.
Show(context.Context, string, ...QueryOption) (any, error)
}
44 changes: 44 additions & 0 deletions packmanager/umbrella.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ package packmanager
import (
"context"
"fmt"
"sort"

"github.com/sirupsen/logrus"

"kraftkit.sh/log"

"kraftkit.sh/pack"
"kraftkit.sh/unikraft/component"
)
Expand Down Expand Up @@ -220,3 +222,45 @@ func (u umbrella) IsCompatible(ctx context.Context, source string, qopts ...Quer
func (u umbrella) Format() pack.PackageFormat {
return UmbrellaFormat
}

func (u umbrella) Show(ctx context.Context, outputFormat string, qopts ...QueryOption) (any, error) {
var query Query
var metadata any

for _, qopt := range qopts {
qopt(&query)
}

packages, err := u.Catalog(ctx, WithCache(query.useCache))
if err != nil {
return nil, err
}

// Sort packages by type, name, version, format
sort.Slice(packages, func(i, j int) bool {
if packages[i].Type() != packages[j].Type() {
return packages[i].Type() < packages[j].Type()
}

if packages[i].Name() != packages[j].Name() {
return packages[i].Name() < packages[j].Name()
}

if packages[i].Version() != packages[j].Version() {
return packages[i].Version() < packages[j].Version()
}

return packages[i].Format() < packages[j].Format()
})

for _, pack := range packages {
if query.name == pack.Name() {
metadata = pack.Metadata()
}
}

if metadata == nil {
return nil, fmt.Errorf("Package %s information not found", query.name)
}
return metadata, nil
}

0 comments on commit baf8395

Please sign in to comment.