diff --git a/cmd/kraft/pkg/pkg.go b/cmd/kraft/pkg/pkg.go index 1e3e32b50..d598c0851 100644 --- a/cmd/kraft/pkg/pkg.go +++ b/cmd/kraft/pkg/pkg.go @@ -28,6 +28,7 @@ import ( "kraftkit.sh/cmd/kraft/pkg/prune" "kraftkit.sh/cmd/kraft/pkg/pull" "kraftkit.sh/cmd/kraft/pkg/push" + "kraftkit.sh/cmd/kraft/pkg/remove" "kraftkit.sh/cmd/kraft/pkg/source" "kraftkit.sh/cmd/kraft/pkg/unsource" "kraftkit.sh/cmd/kraft/pkg/update" @@ -83,6 +84,7 @@ func New() *cobra.Command { cmd.AddCommand(unsource.New()) cmd.AddCommand(update.New()) cmd.AddCommand(prune.New()) + cmd.AddCommand(remove.New()) return cmd } diff --git a/cmd/kraft/pkg/remove/remove.go b/cmd/kraft/pkg/remove/remove.go new file mode 100644 index 000000000..3312f9e10 --- /dev/null +++ b/cmd/kraft/pkg/remove/remove.go @@ -0,0 +1,80 @@ +package remove + +import ( + "os" + + "github.com/spf13/cobra" + "kraftkit.sh/cmdfactory" + "kraftkit.sh/packmanager" + "kraftkit.sh/unikraft/app" +) + +type Remove struct { + Workdir string `long:"workdir" short:"w" usage:"workdir location to remove pkg from that location"` + Kraftfile string `long:"kraftfile" short:"k" usage:"Set an alternative path of the Kraftfile"` +} + +func New() *cobra.Command { + cmd, err := cmdfactory.New(&Remove{}, cobra.Command{ + Short: "Remove a library dependency from the project directory", + Use: "remove [FLAGS] [PACKAGE]", + Aliases: []string{"rm"}, + Args: cmdfactory.MinimumArgs(1, "package name is not specified to remove from the project"), + Annotations: map[string]string{ + cmdfactory.AnnotationHelpGroup: "pkg", + }, + }) + if err != nil { + panic(err) + } + + return cmd +} + +func (opts *Remove) Pre(cmd *cobra.Command, _ []string) error { + ctx, err := packmanager.WithDefaultUmbrellaManagerInContext(cmd.Context()) + if err != nil { + return err + } + cmd.SetContext(ctx) + return nil +} + +func (opts *Remove) Run(cmd *cobra.Command, args []string) error { + var workdir string + var err error + + if len(opts.Workdir) > 0 { + workdir = opts.Workdir + } + + if workdir == "." || workdir == "./" || workdir == "" { + workdir, err = os.Getwd() + } + if err != nil { + return err + } + ctx := cmd.Context() + + popts := []app.ProjectOption{} + + if len(opts.Kraftfile) > 0 { + popts = append(popts, app.WithProjectKraftfile(opts.Kraftfile)) + } else { + popts = append(popts, app.WithProjectDefaultKraftfiles()) + } + + project, err := app.NewProjectFromOptions( + ctx, + append(popts, app.WithProjectWorkdir(workdir))..., + ) + if err != nil { + return err + } + + if err = project.RemoveLibrary(ctx, args[0]); err != nil { + return err + } + + return project.Save() +} diff --git a/unikraft/app/application.go b/unikraft/app/application.go index 39761172f..2c835767d 100644 --- a/unikraft/app/application.go +++ b/unikraft/app/application.go @@ -123,6 +123,9 @@ type Application interface { // Serialize and save the application to the kraftfile Save() error + + // Removes library from the project directory + RemoveLibrary(ctx context.Context, libraryName string) error } type application struct { @@ -809,3 +812,48 @@ func (app application) Save() error { return nil } + +func (app application) RemoveLibrary(ctx context.Context, libraryName string) error { + isLibraryExistInProject := false + for libKey, lib := range app.libraries { + if lib.Name() == libraryName { + isLibraryExistInProject = true + delete(app.libraries, libKey) + + yamlFile, err := os.ReadFile(app.kraftfile.path) + if err != nil { + return err + } + + var yamlMap = app + err = yaml.Unmarshal(yamlFile, &yamlMap) + if err != nil { + return err + } + + delete(yamlMap.libraries, libKey) + byteData, err := yaml.Marshal(yamlMap) + if err != nil { + return err + } + + err = os.WriteFile(app.kraftfile.path, byteData, 0o644) + if err != nil { + return err + } + + // Remove library directory from the project directory + libPath := filepath.Join(app.WorkingDir(), unikraft.LibsDir, libraryName) + if _, err = os.Stat(libPath); err == nil { + err = os.RemoveAll(libPath) + if err != nil { + return err + } + } + } + } + if !isLibraryExistInProject { + return fmt.Errorf("library %s does not exist in the project", libraryName) + } + return nil +} diff --git a/unikraft/unikraft.go b/unikraft/unikraft.go index 3955b4b48..d5bd91751 100644 --- a/unikraft/unikraft.go +++ b/unikraft/unikraft.go @@ -34,4 +34,5 @@ const ( // Built-in paths VendorDir = ".unikraft" BuildDir = ".unikraft/build" + LibsDir = ".unikraft/libs" )