diff --git a/CHANGELOG.md b/CHANGELOG.md index 09b840b..5dee69b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.21.2] - Unreleased + +### Fixed + +- Some ambiguous error messages. +- Not prompting for confirmation to overwrite existing files when installing a tooth. + ## [0.21.1] - 2024-02-17 ### Fixed @@ -406,6 +413,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Basic functions: cache, install, list, show, tooth init, and uninstall. +[0.21.2]: https://github.com/lippkg/lip/compare/v0.21.1...HEAD [0.21.1]: https://github.com/lippkg/lip/compare/v0.21.0...v0.21.1 [0.21.0]: https://github.com/lippkg/lip/compare/v0.20.1...v0.21.0 [0.20.1]: https://github.com/lippkg/lip/compare/v0.20.0...v0.20.1 diff --git a/cmd/lip/main.go b/cmd/lip/main.go index d2bc382..a9b97ed 100644 --- a/cmd/lip/main.go +++ b/cmd/lip/main.go @@ -17,7 +17,7 @@ var defaultConfig context.Config = context.Config{ ProxyURL: "", } -var lipVersion semver.Version = semver.MustParse("0.21.1") +var lipVersion semver.Version = semver.MustParse("0.21.2") func main() { if os.Getenv("NO_COLOR") != "" { diff --git a/internal/cmd/cmdlipinstall/archive.go b/internal/cmd/cmdlipinstall/archive.go index fc9de67..092fd05 100644 --- a/internal/cmd/cmdlipinstall/archive.go +++ b/internal/cmd/cmdlipinstall/archive.go @@ -48,7 +48,7 @@ func filterInstalledToothArchives(ctx *context.Context, archives []tooth.Archive } // installToothArchive installs the tooth archive. -func installToothArchive(ctx *context.Context, archive tooth.Archive, forceReinstall bool, upgrade bool) error { +func installToothArchive(ctx *context.Context, archive tooth.Archive, forceReinstall bool, upgrade bool, yes bool) error { debugLogger := log.WithFields(log.Fields{ "package": "cmdlipinstall", "method": "installToothArchive", @@ -143,7 +143,7 @@ func installToothArchive(ctx *context.Context, archive tooth.Archive, forceReins return fmt.Errorf("failed to attach asset archive %v\n\t%w", assetArchiveFilePath.LocalString(), err) } - if err := install.Install(ctx, archiveWithAssets); err != nil { + if err := install.Install(ctx, archiveWithAssets, yes); err != nil { return fmt.Errorf("failed to install tooth archive %v\n\t%w", archiveWithAssets.FilePath().LocalString(), err) } debugLogger.Debugf("Installed tooth archive %v", archiveWithAssets.FilePath().LocalString()) diff --git a/internal/cmd/cmdlipinstall/cmdlipinstall.go b/internal/cmd/cmdlipinstall/cmdlipinstall.go index fdd759b..f1ffdc8 100644 --- a/internal/cmd/cmdlipinstall/cmdlipinstall.go +++ b/internal/cmd/cmdlipinstall/cmdlipinstall.go @@ -171,7 +171,7 @@ func Run(ctx *context.Context, args []string) error { log.Info("Installing teeth...") for _, archive := range filteredArchives { - if err := installToothArchive(ctx, archive, flagDict.forceReinstallFlag, flagDict.upgradeFlag); err != nil { + if err := installToothArchive(ctx, archive, flagDict.forceReinstallFlag, flagDict.upgradeFlag, flagDict.yesFlag); err != nil { return fmt.Errorf("failed to install tooth archive %v\n\t%w", archive.FilePath().LocalString(), err) } } diff --git a/internal/install/install.go b/internal/install/install.go index 7670d69..d51a03f 100644 --- a/internal/install/install.go +++ b/internal/install/install.go @@ -17,7 +17,7 @@ import ( // Install installs a tooth archive with an asset archive. If assetArchiveFilePath is empty, // will use the tooth archive as the asset archive. -func Install(ctx *context.Context, archive tooth.Archive) error { +func Install(ctx *context.Context, archive tooth.Archive, yes bool) error { debugLogger := log.WithFields(log.Fields{ "package": "install", "method": "Install", @@ -60,7 +60,7 @@ func Install(ctx *context.Context, archive tooth.Archive) error { return fmt.Errorf("failed to get asset file path of archive %v\n\t%w", archive.FilePath().LocalString(), err) } - if err := placeFiles(ctx, archive.Metadata(), assetFilePath); err != nil { + if err := placeFiles(ctx, archive.Metadata(), assetFilePath, yes); err != nil { return fmt.Errorf("failed to place files\n\t%w", err) } debugLogger.Debug("Placed files") @@ -97,7 +97,7 @@ func Install(ctx *context.Context, archive tooth.Archive) error { } // placeFiles places the files of the tooth. -func placeFiles(ctx *context.Context, metadata tooth.Metadata, assetArchiveFilePath path.Path) error { +func placeFiles(ctx *context.Context, metadata tooth.Metadata, assetArchiveFilePath path.Path, forcePlace bool) error { debugLogger := log.WithFields(log.Fields{ "package": "install", "method": "placeFiles", @@ -130,7 +130,23 @@ func placeFiles(ctx *context.Context, metadata tooth.Metadata, assetArchiveFileP // Check if the destination exists. if _, err := os.Stat(relDest.LocalString()); err == nil { - return fmt.Errorf("destination %v already exists", relDest.LocalString()) + if !forcePlace { + // Ask for confirmation. + log.Infof("Destination %v already exists", relDest.LocalString()) + log.Info("Do you want to remove? [y/N]") + var ans string + fmt.Scanln(&ans) + if ans != "y" && ans != "Y" { + return fmt.Errorf("aborted") + } + } + + log.Infof("Removing destination %v", relDest.LocalString()) + + // Remove the destination if it exists. + if err := os.RemoveAll(relDest.LocalString()); err != nil { + return fmt.Errorf("failed to remove destination %v\n\t%w", relDest.LocalString(), err) + } } dest := workspaceDir.Join(relDest)