Skip to content

Commit

Permalink
all: Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
jmooring committed Sep 18, 2023
1 parent 8b27e95 commit ac608a5
Show file tree
Hide file tree
Showing 51 changed files with 164 additions and 159 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.hvm
.markdownlint.yaml
/dist
/hvm
cover.out
dist/
hvm
NOTES.md
6 changes: 3 additions & 3 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ builds:
goarch: arm64
ldflags:
- -s -w
- -X github.com/jmooring/hvm/cmd.version={{.Version}}
- -X github.com/jmooring/hvm/cmd.commitHash={{.ShortCommit}}
- -X github.com/jmooring/hvm/cmd.buildDate={{.Date}}
- -X github.com/jmooring/hvm/cmd/hvm.version={{.Version}}
- -X github.com/jmooring/hvm/cmd/hvm.commitHash={{.ShortCommit}}
- -X github.com/jmooring/hvm/cmd/hvm.buildDate={{.Date}}
archives:
- format: tar.gz
name_template: >-
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

Hugo Version Manager (hvm) allows you to download and manage multiple versions of the extended edition of the [Hugo] static site generator. You can use hvm to specify which version of Hugo to use in the current directory.

![Demonstration](demo/hvm.gif)
![Demonstration](assets/hvm.gif)

If you do not specify a version of Hugo to use in the current directory, the Hugo executable will be found by searching the `PATH` environment variable.

Expand Down
File renamed without changes
File renamed without changes.
6 changes: 3 additions & 3 deletions cmd/clean.go → cmd/hvm/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ func clean() error {
}

if strings.ToLower(string(r[0])) == "y" {
d, err := os.ReadDir(cacheDir)
d, err := os.ReadDir(App.CacheDirPath)
if err != nil {
return err
}

for _, f := range d {
if f.Name() != defaultDirName {
err := os.RemoveAll(filepath.Join(cacheDir, f.Name()))
if f.Name() != App.DefaultDirName {
err := os.RemoveAll(filepath.Join(App.CacheDirPath, f.Name()))
if err != nil {
return err
}
Expand Down
78 changes: 49 additions & 29 deletions cmd/root.go → cmd/hvm/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,44 +22,59 @@ import (
"os"
"path/filepath"
"runtime"
"strings"

"github.com/jmooring/hvm/helpers"
"github.com/jmooring/hvm/pkg/helpers"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

type config struct {
GithubToken string `toml:"githubToken,omitempty" comment:"GitHub personal access token"`
NumTagsToDisplay int `toml:"numTagsToDisplay" comment:"Number of tags to display with the \"use\" and \"install\" commands"`
// An application contains details about the application. Some are constants, while
// others depend on the user environment.
type application struct {
CacheDirPath string // path to the application cache directory
ConfigFilePath string // path to the application configuration
DefaultDirName string // name of the "default" directory within the application cache directory
DefaultDirPath string // path to the "default" directory within the application cache directory
DotFileName string // name of the dot file written to the current directory (e.g., .hvm)
Name string // name of the application
RepositoryName string // name of the GitHub repository without the .git extension
RepositoryOwner string // account owner of the GitHub repository
}

var Config config
// A configuration contains the current configuration parameters from environment
// variables, the configuration file, or default values, in that order.
type configuration struct {
GithubToken string // a GitHub personal access token
NumTagsToDisplay int // number of tags to display when using the "use" and "install" commands
}

var App application = application{
DefaultDirName: "default",
DotFileName: ".hvm",
Name: "hvm",
RepositoryName: "hugo",
RepositoryOwner: "gohugoio",
}
var Config configuration

var (
cacheDir string
buildDate string
buildDate string = runtime.GOOS
commitHash string
version string = "dev"
versionString string = fmt.Sprintf("%s %s %s/%s %s %s", appName, version, runtime.GOOS, runtime.GOARCH, commitHash, buildDate)
)

const (
appName string = "hvm"
dotFileName string = ".hvm"
defaultDirName string = "default"
versionString string = fmt.Sprintf("%s %s %s/%s %s %s", App.Name, version, runtime.GOOS, runtime.GOARCH, commitHash, buildDate)
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: appName,
Use: App.Name,
Short: "Hugo Version Manager",
Long: `Hugo Version Manager (` + appName + `) allows you to download and manage multiple versions
Long: `Hugo Version Manager (` + App.Name + `) allows you to download and manage multiple versions
of the extended edition of the Hugo static site generator. You can use hvm to
specify which version of Hugo to use in the current directory.
If you do not specify a version of Hugo to use in the current directory, the
Hugo executable will be found by searching the PATH environment variable.
`,
Hugo executable will be found by searching the PATH environment variable.`,
Version: versionString,
}

Expand All @@ -73,10 +88,10 @@ func Execute() {
}

func init() {
cobra.OnInitialize(initConfig, initCache)
cobra.OnInitialize(initConfig, initApp)

rootCmd.PersistentFlags().BoolP("help", "h", false, "Display help")
rootCmd.PersistentFlags().BoolP("version", "v", false, "Display the "+appName+" version")
rootCmd.PersistentFlags().BoolP("version", "v", false, "Display the "+App.Name+" version")
rootCmd.SetVersionTemplate(fmt.Sprintf("%s\n", versionString))
}

Expand All @@ -89,11 +104,11 @@ func initConfig() {
// Create config directory.
userConfigDir, err := os.UserConfigDir()
cobra.CheckErr(err)
err = os.MkdirAll(filepath.Join(userConfigDir, appName), 0777)
err = os.MkdirAll(filepath.Join(userConfigDir, App.Name), 0777)
cobra.CheckErr(err)

// Define config file.
viper.AddConfigPath(filepath.Join(userConfigDir, appName))
viper.AddConfigPath(filepath.Join(userConfigDir, App.Name))
viper.SetConfigName("config")
viper.SetConfigType("toml")

Expand All @@ -110,18 +125,18 @@ func initConfig() {
}

// Get config values from env vars.
viper.SetEnvPrefix("HVM")
viper.SetEnvPrefix(strings.ToUpper(App.Name))
viper.AutomaticEnv()

// Validate config values.
k := "numTagsToDisplay"
if viper.GetInt(k) == 0 {
err = fmt.Errorf("configuration: %s must be a non-zero integer: see %s", k, viper.ConfigFileUsed())
err = fmt.Errorf("configuration: %s must be a non-zero integer: see %s", k, App.ConfigFilePath)
cobra.CheckErr(err)
}
k = "githubToken"
if !helpers.IsString(viper.Get(k)) {
err = fmt.Errorf("configuration: %s must be a string: see %s", k, viper.ConfigFileUsed())
err = fmt.Errorf("configuration: %s must be a string: see %s", k, App.ConfigFilePath)
cobra.CheckErr(err)
}

Expand All @@ -130,11 +145,16 @@ func initConfig() {
cobra.CheckErr(err)
}

// initCache creates the cache directory.
func initCache() {
// initApp initializes the application and creates the application cache
// directory.
func initApp() {
userCacheDir, err := os.UserCacheDir()
cobra.CheckErr(err)
cacheDir = filepath.Join(userCacheDir, appName)
err = os.MkdirAll(cacheDir, 0777)

App.CacheDirPath = filepath.Join(userCacheDir, App.Name)
App.ConfigFilePath = viper.ConfigFileUsed()
App.DefaultDirPath = filepath.Join(userCacheDir, App.Name, App.DefaultDirName)

err = os.MkdirAll(App.CacheDirPath, 0777)
cobra.CheckErr(err)
}
File renamed without changes.
8 changes: 2 additions & 6 deletions cmd/config.go → cmd/hvm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (

"github.com/pelletier/go-toml/v2"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// configCmd represents the config command
Expand All @@ -43,12 +42,9 @@ func init() {
func displayConfig() error {
t, err := toml.Marshal(Config)
cobra.CheckErr(err)
fmt.Println(string(t))

f := viper.ConfigFileUsed()
if f != "" {
fmt.Println("Configuration file:", f)
}
fmt.Println(string(t))
fmt.Println("Configuration file:", App.ConfigFilePath)

return nil
}
6 changes: 3 additions & 3 deletions cmd/disable.go → cmd/hvm/disable.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"os"
"path/filepath"

"github.com/jmooring/hvm/helpers"
"github.com/jmooring/hvm/pkg/helpers"
"github.com/spf13/cobra"
)

Expand All @@ -46,13 +46,13 @@ func disable() error {
return err
}

exists, err := helpers.Exists(filepath.Join(wd, dotFileName))
exists, err := helpers.Exists(filepath.Join(wd, App.DotFileName))
if err != nil {
return err
}

if exists {
err := os.Remove(filepath.Join(wd, dotFileName))
err := os.Remove(filepath.Join(wd, App.DotFileName))
if err != nil {
return err
}
Expand Down
31 changes: 12 additions & 19 deletions cmd/install.go → cmd/hvm/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ import (
"log"
"os"
"path/filepath"
"runtime"
"slices"

"github.com/jmooring/hvm/archive"
"github.com/jmooring/hvm/helpers"
"github.com/jmooring/hvm/pkg/archive"
"github.com/jmooring/hvm/pkg/helpers"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -53,30 +52,25 @@ func init() {
// install sets the version of the Hugo executable to use when version
// management is disabled in the current directory.
func install() error {
repo := newRepository("gohugoio", "hugo")
asset := newAsset(runtime.GOOS, runtime.GOARCH)

err := asset.fetchTags(repo)
if err != nil {
return err
}
repo := newRepository()
asset := newAsset()

msg := "Select a version to use when version management is disabled"
err = asset.selectTag(repo, msg)
err := repo.selectTag(asset, msg)
if err != nil {
return err
}
if asset.tag == "" {
return nil // the user did not select a tag; do nothing
}

exists, err := helpers.Exists(filepath.Join(cacheDir, asset.tag))
exists, err := helpers.Exists(filepath.Join(App.CacheDirPath, asset.tag))
if err != nil {
return err
}

if !exists {
err = asset.fetchURL(repo)
err = repo.fetchURL(asset)
if err != nil {
return err
}
Expand All @@ -102,24 +96,23 @@ func install() error {
return err
}

err = helpers.CopyDirectoryContent(asset.archiveDirPath, filepath.Join(cacheDir, asset.tag))
err = helpers.CopyDirectoryContent(asset.archiveDirPath, filepath.Join(App.CacheDirPath, asset.tag))
if err != nil {
return err
}
}

err = helpers.CopyFile(asset.getExecPath(), filepath.Join(cacheDir, defaultDirName, asset.getExecName()))
err = helpers.CopyFile(asset.getExecPath(), filepath.Join(App.CacheDirPath, App.DefaultDirName, asset.execName))
if err != nil {
return err
}

fmt.Println("Installation of", asset.tag, "complete.")

defaultDirPath := filepath.Join(cacheDir, defaultDirName)
if !slices.Contains(filepath.SplitList(os.Getenv("PATH")), defaultDirPath) {
if !slices.Contains(filepath.SplitList(os.Getenv("PATH")), App.DefaultDirPath) {
fmt.Println()
fmt.Printf("Please add %s to the PATH environment\n", defaultDirPath)
fmt.Println("variable. Open a new terminal after making the change.")
fmt.Printf("Please add %s to the PATH environment variable.\n", App.DefaultDirPath)
fmt.Println("Open a new terminal after making the change.")

}

Expand Down
8 changes: 3 additions & 5 deletions cmd/remove.go → cmd/hvm/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ package cmd
import (
"fmt"
"os"
"path/filepath"

"github.com/jmooring/hvm/helpers"
"github.com/jmooring/hvm/pkg/helpers"
"github.com/spf13/cobra"
)

Expand All @@ -41,13 +40,12 @@ func init() {
}

func remove() error {
defaultDirPath := filepath.Join(cacheDir, defaultDirName)
exists, err := helpers.Exists(defaultDirPath)
exists, err := helpers.Exists(App.DefaultDirPath)
if err != nil {
return err
}
if exists {
err = os.RemoveAll(defaultDirPath)
err = os.RemoveAll(App.DefaultDirPath)
if err != nil {
return err
}
Expand Down
6 changes: 2 additions & 4 deletions cmd/reset.go → cmd/hvm/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ package cmd
import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// resetCmd represents the reset command
Expand Down Expand Up @@ -61,11 +59,11 @@ func reset() error {
if err != nil {
return err
}
err = os.RemoveAll(filepath.Dir(viper.ConfigFileUsed()))
err = os.RemoveAll(App.ConfigFilePath)
if err != nil {
return err
}
err = os.RemoveAll(cacheDir)
err = os.RemoveAll(App.CacheDirPath)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit ac608a5

Please sign in to comment.