feat: add download command
parent
4436671155
commit
7c07820fe1
|
@ -21,6 +21,10 @@
|
||||||
{
|
{
|
||||||
"internal": "data/kitty",
|
"internal": "data/kitty",
|
||||||
"external": "~/.config/kitty"
|
"external": "~/.config/kitty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internal": "data/kitty/mocha.conf",
|
||||||
|
"url": "https://raw.githubusercontent.com/catppuccin/kitty/main/mocha.conf"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# vim:ft=kitty
|
# vim:ft=kitty
|
||||||
|
|
||||||
## name: Catppuccin Kitty Diff Mocha
|
## name: Catppuccin Kitty Mocha
|
||||||
## author: Catppuccin Org
|
## author: Catppuccin Org
|
||||||
## license: MIT
|
## license: MIT
|
||||||
## upstream: https://github.com/catppuccin/kitty/blob/main/mocha.conf
|
## upstream: https://github.com/catppuccin/kitty/blob/main/mocha.conf
|
||||||
|
|
|
@ -21,73 +21,77 @@ func (a *action) runHelp(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) runInstall(c *cli.Context) error {
|
func (a *action) runInstall(c *cli.Context) error {
|
||||||
a.getFlags(c)
|
cfg, err := a.loadConfig(c, installCommand)
|
||||||
a.log("start %s\n", installCommand)
|
|
||||||
|
|
||||||
cfg, err := a.loadConfig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cfg.Install(); err != nil {
|
if err := cfg.Install(); err != nil {
|
||||||
return fmt.Errorf("failed to install config: %w", err)
|
return fmt.Errorf("config: failed to install: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) runUpdate(c *cli.Context) error {
|
func (a *action) runUpdate(c *cli.Context) error {
|
||||||
a.getFlags(c)
|
cfg, err := a.loadConfig(c, updateCommand)
|
||||||
a.log("start %s\n", updateCommand)
|
|
||||||
|
|
||||||
cfg, err := a.loadConfig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cfg.Update(); err != nil {
|
if err := cfg.Update(); err != nil {
|
||||||
return fmt.Errorf("failed to update config: %w", err)
|
return fmt.Errorf("config: failed to update: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *action) runDownload(c *cli.Context) error {
|
||||||
|
cfg, err := a.loadConfig(c, downloadCommand)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cfg.Download(); err != nil {
|
||||||
|
return fmt.Errorf("config: failed to download: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) runClean(c *cli.Context) error {
|
func (a *action) runClean(c *cli.Context) error {
|
||||||
a.getFlags(c)
|
cfg, err := a.loadConfig(c, cleanCommand)
|
||||||
a.log("start %s\n", cleanCommand)
|
|
||||||
|
|
||||||
cfg, err := a.loadConfig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cfg.Clean(); err != nil {
|
if err := cfg.Clean(); err != nil {
|
||||||
return fmt.Errorf("failed to clean config: %w", err)
|
return fmt.Errorf("config: failed to clean: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) runDiff(c *cli.Context) error {
|
func (a *action) runDiff(c *cli.Context) error {
|
||||||
a.getFlags(c)
|
cfg, err := a.loadConfig(c, diffCommand)
|
||||||
a.log("start %s\n", diffCommand)
|
|
||||||
|
|
||||||
cfg, err := a.loadConfig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cfg.Diff(); err != nil {
|
if err := cfg.Diff(); err != nil {
|
||||||
return fmt.Errorf("failed to compare config: %w", err)
|
return fmt.Errorf("config: failed to compare: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) loadConfig() (config.Config, error) {
|
func (a *action) loadConfig(c *cli.Context, command string) (config.Config, error) {
|
||||||
|
a.getFlags(c)
|
||||||
|
a.log("start %s with flags %+v\n", command, a.flags)
|
||||||
|
|
||||||
cfgReal, cfgDemo, err := config.LoadConfig(currentDir)
|
cfgReal, cfgDemo, err := config.LoadConfig(currentDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to load config: %w", err)
|
return nil, fmt.Errorf("config: failed to load: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.flags.dryRun {
|
if a.flags.dryRun {
|
||||||
|
|
|
@ -13,34 +13,36 @@ const (
|
||||||
appName = "dotfiles"
|
appName = "dotfiles"
|
||||||
appUsage = "managing dotfiles"
|
appUsage = "managing dotfiles"
|
||||||
|
|
||||||
// flags
|
|
||||||
verboseFlag = "verbose"
|
|
||||||
dryRunFlag = "dry-run"
|
|
||||||
|
|
||||||
// commands
|
|
||||||
installCommand = "install"
|
installCommand = "install"
|
||||||
updateCommand = "update"
|
installUsage = "install user configs from dotfiles"
|
||||||
cleanCommand = "clean"
|
|
||||||
diffCommand = "diff"
|
|
||||||
|
|
||||||
// flag usages
|
updateCommand = "update"
|
||||||
verboseUsage = "show what is going on"
|
updateUsage = "update dotfiles from user configs"
|
||||||
dryRunUsage = "demo mode without actually changing anything"
|
|
||||||
|
|
||||||
// command usages
|
downloadCommand = "download"
|
||||||
installUsage = "install user configs from dotfiles"
|
downloadUsage = "download configs from internet (theme for example)"
|
||||||
updateUsage = "update dotfiles from user configs"
|
|
||||||
|
cleanCommand = "clean"
|
||||||
cleanUsage = "clean unused dotfiles"
|
cleanUsage = "clean unused dotfiles"
|
||||||
diffUsage = "diff dotfiles with user configs"
|
|
||||||
|
diffCommand = "diff"
|
||||||
|
diffUsage = "diff dotfiles with user configs"
|
||||||
|
|
||||||
|
verboseFlag = "verbose"
|
||||||
|
verboseUsage = "show what is going on"
|
||||||
|
|
||||||
|
dryRunFlag = "dry-run"
|
||||||
|
dryRunUsage = "demo mode without actually changing anything"
|
||||||
|
|
||||||
currentDir = "."
|
currentDir = "."
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// command aliases
|
installAliases = []string{"i"}
|
||||||
installAliases = []string{"i"}
|
updateAliases = []string{"u"}
|
||||||
updateAliases = []string{"u"}
|
downloadAliases = []string{"d"}
|
||||||
cleanAliases = []string{"c"}
|
cleanAliases = []string{"c"}
|
||||||
|
diffAliases = []string{"df"}
|
||||||
)
|
)
|
||||||
|
|
||||||
// denyOSes contains OS which is not supported
|
// denyOSes contains OS which is not supported
|
||||||
|
@ -92,6 +94,22 @@ func NewApp() *App {
|
||||||
},
|
},
|
||||||
Action: a.runUpdate,
|
Action: a.runUpdate,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: downloadCommand,
|
||||||
|
Aliases: downloadAliases,
|
||||||
|
Usage: downloadUsage,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: verboseFlag,
|
||||||
|
Usage: verboseUsage,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: dryRunFlag,
|
||||||
|
Usage: dryRunUsage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: a.runDownload,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: cleanCommand,
|
Name: cleanCommand,
|
||||||
Aliases: cleanAliases,
|
Aliases: cleanAliases,
|
||||||
|
@ -109,8 +127,9 @@ func NewApp() *App {
|
||||||
Action: a.runClean,
|
Action: a.runClean,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: diffCommand,
|
Name: diffCommand,
|
||||||
Usage: diffUsage,
|
Aliases: diffAliases,
|
||||||
|
Usage: diffUsage,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: verboseFlag,
|
Name: verboseFlag,
|
||||||
|
|
|
@ -3,8 +3,10 @@ package config
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -17,6 +19,7 @@ type Config interface {
|
||||||
Update() error
|
Update() error
|
||||||
Clean() error
|
Clean() error
|
||||||
Diff() error
|
Diff() error
|
||||||
|
Download() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type configApps struct {
|
type configApps struct {
|
||||||
|
@ -30,7 +33,8 @@ type App struct {
|
||||||
|
|
||||||
type Path struct {
|
type Path struct {
|
||||||
Internal string `json:"internal"`
|
Internal string `json:"internal"`
|
||||||
External string `json:"external"`
|
External string `json:"external,omitempty"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadConfig return config, configDemo
|
// LoadConfig return config, configDemo
|
||||||
|
@ -47,6 +51,9 @@ func LoadConfig(path string) (*configReal, *configDemo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cfgReal := configReal{
|
cfgReal := configReal{
|
||||||
|
httpClient: &http.Client{
|
||||||
|
Timeout: time.Second * 5,
|
||||||
|
},
|
||||||
configApps: cfgApps,
|
configApps: cfgApps,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,10 @@ var _ Config = (*configDemo)(nil)
|
||||||
func (c *configDemo) Install() error {
|
func (c *configDemo) Install() error {
|
||||||
for _, app := range c.Apps {
|
for _, app := range c.Apps {
|
||||||
for _, p := range app.Paths {
|
for _, p := range app.Paths {
|
||||||
|
if p.External == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("Replace %s -> %s\n", p.Internal, p.External)
|
fmt.Printf("Replace %s -> %s\n", p.Internal, p.External)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +25,10 @@ func (c *configDemo) Install() error {
|
||||||
func (c *configDemo) Update() error {
|
func (c *configDemo) Update() error {
|
||||||
for _, app := range c.Apps {
|
for _, app := range c.Apps {
|
||||||
for _, p := range app.Paths {
|
for _, p := range app.Paths {
|
||||||
|
if p.External == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("Replace %s -> %s\n", p.External, p.Internal)
|
fmt.Printf("Replace %s -> %s\n", p.External, p.Internal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +36,20 @@ func (c *configDemo) Update() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *configDemo) Download() error {
|
||||||
|
for _, app := range c.Apps {
|
||||||
|
for _, p := range app.Paths {
|
||||||
|
if p.URL == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Download %s -> %s\n", p.URL, p.Internal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *configDemo) Clean() error {
|
func (c *configDemo) Clean() error {
|
||||||
unusedDirs, err := getUnusedDirs(c.Apps)
|
unusedDirs, err := getUnusedDirs(c.Apps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
@ -10,6 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type configReal struct {
|
type configReal struct {
|
||||||
|
httpClient *http.Client
|
||||||
configApps
|
configApps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +22,10 @@ var _ Config = (*configReal)(nil)
|
||||||
func (c *configReal) Install() error {
|
func (c *configReal) Install() error {
|
||||||
for _, app := range c.Apps {
|
for _, app := range c.Apps {
|
||||||
for _, p := range app.Paths {
|
for _, p := range app.Paths {
|
||||||
|
if p.External == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if err := copy.Replace(p.Internal, p.External); err != nil {
|
if err := copy.Replace(p.Internal, p.External); err != nil {
|
||||||
return fmt.Errorf("failed to replace %s -> %s: %w", p.Internal, p.External, err)
|
return fmt.Errorf("failed to replace %s -> %s: %w", p.Internal, p.External, err)
|
||||||
}
|
}
|
||||||
|
@ -32,6 +39,10 @@ func (c *configReal) Install() error {
|
||||||
func (c *configReal) Update() error {
|
func (c *configReal) Update() error {
|
||||||
for _, app := range c.Apps {
|
for _, app := range c.Apps {
|
||||||
for _, p := range app.Paths {
|
for _, p := range app.Paths {
|
||||||
|
if p.External == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if err := copy.Replace(p.External, p.Internal); err != nil {
|
if err := copy.Replace(p.External, p.Internal); err != nil {
|
||||||
return fmt.Errorf("failed to replace %s -> %s: %w", p.External, p.Internal, err)
|
return fmt.Errorf("failed to replace %s -> %s: %w", p.External, p.Internal, err)
|
||||||
}
|
}
|
||||||
|
@ -41,6 +52,34 @@ func (c *configReal) Update() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *configReal) Download() error {
|
||||||
|
for _, app := range c.Apps {
|
||||||
|
for _, p := range app.Paths {
|
||||||
|
if p.URL == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
httpRsp, err := c.httpClient.Get(p.URL)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("http client: failed to get: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := io.ReadAll(httpRsp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("io: failed to read all: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile(p.Internal, data, 0o600); err != nil {
|
||||||
|
return fmt.Errorf("os: failed to write file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
httpRsp.Body.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Clean remove unused config inside config dir
|
// Clean remove unused config inside config dir
|
||||||
func (c *configReal) Clean() error {
|
func (c *configReal) Clean() error {
|
||||||
unusedDirs, err := getUnusedDirs(c.Apps)
|
unusedDirs, err := getUnusedDirs(c.Apps)
|
||||||
|
|
Loading…
Reference in New Issue