gosick #1
@@ -12,7 +12,8 @@ FROM alpine:3.21
|
|||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
bash \
|
bash \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
git
|
git \
|
||||||
|
ruby
|
||||||
|
|
||||||
WORKDIR /workspace
|
WORKDIR /workspace
|
||||||
COPY . /workspace
|
COPY . /workspace
|
||||||
|
|||||||
@@ -257,21 +257,61 @@ func normalizeArgs(args []string) []string {
|
|||||||
return []string{"--help"}
|
return []string{"--help"}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch args[0] {
|
prefix, rest := splitLeadingGlobalFlags(args)
|
||||||
|
if len(rest) == 0 {
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
|
switch rest[0] {
|
||||||
case "-h", "--help":
|
case "-h", "--help":
|
||||||
return []string{"--help"}
|
return []string{"--help"}
|
||||||
case "help":
|
case "help":
|
||||||
if len(args) == 1 {
|
if len(rest) == 1 {
|
||||||
return []string{"--help"}
|
return []string{"--help"}
|
||||||
}
|
}
|
||||||
return append(args[1:], "--help")
|
normalized := append([]string{}, prefix...)
|
||||||
|
normalized = append(normalized, rest[1:]...)
|
||||||
|
return append(normalized, "--help")
|
||||||
case "-v", "--version":
|
case "-v", "--version":
|
||||||
return []string{"version"}
|
return []string{"version"}
|
||||||
|
case "symlink":
|
||||||
|
normalized := append([]string{}, prefix...)
|
||||||
|
normalized = append(normalized, "link")
|
||||||
|
return append(normalized, rest[1:]...)
|
||||||
|
case "commit":
|
||||||
|
if len(rest) == 3 && !hasCommitMessageFlag(rest[1:]) {
|
||||||
|
normalized := append([]string{}, prefix...)
|
||||||
|
return append(normalized, "commit", "-m", rest[2], rest[1])
|
||||||
|
}
|
||||||
|
return args
|
||||||
default:
|
default:
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func splitLeadingGlobalFlags(args []string) ([]string, []string) {
|
||||||
|
i := 0
|
||||||
|
for i < len(args) {
|
||||||
|
switch args[i] {
|
||||||
|
case "--pretend", "--dry-run", "--quiet":
|
||||||
|
i++
|
||||||
|
default:
|
||||||
|
return args[:i], args[i:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasCommitMessageFlag(args []string) bool {
|
||||||
|
for _, arg := range args {
|
||||||
|
if arg == "-m" || strings.HasPrefix(arg, "--MESSAGE") || strings.HasPrefix(arg, "--message") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func isHelpRequest(args []string) bool {
|
func isHelpRequest(args []string) bool {
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
if arg == "-h" || arg == "--help" {
|
if arg == "-h" || arg == "--help" {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -17,6 +18,7 @@ import (
|
|||||||
type App struct {
|
type App struct {
|
||||||
HomeDir string
|
HomeDir string
|
||||||
ReposDir string
|
ReposDir string
|
||||||
|
Stdin io.Reader
|
||||||
Stdout io.Writer
|
Stdout io.Writer
|
||||||
Stderr io.Writer
|
Stderr io.Writer
|
||||||
Verbose bool
|
Verbose bool
|
||||||
@@ -34,6 +36,7 @@ func New(stdout io.Writer, stderr io.Writer) (*App, error) {
|
|||||||
return &App{
|
return &App{
|
||||||
HomeDir: home,
|
HomeDir: home,
|
||||||
ReposDir: filepath.Join(home, ".homesick", "repos"),
|
ReposDir: filepath.Join(home, ".homesick", "repos"),
|
||||||
|
Stdin: os.Stdin,
|
||||||
Stdout: stdout,
|
Stdout: stdout,
|
||||||
Stderr: stderr,
|
Stderr: stderr,
|
||||||
}, nil
|
}, nil
|
||||||
@@ -173,6 +176,11 @@ func (a *App) PullAll() error {
|
|||||||
|
|
||||||
sort.Strings(castles)
|
sort.Strings(castles)
|
||||||
for _, castle := range castles {
|
for _, castle := range castles {
|
||||||
|
if !a.Quiet {
|
||||||
|
if _, err := fmt.Fprintf(a.Stdout, "%s:\n", castle); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := a.runGit(filepath.Join(a.ReposDir, castle), "pull"); err != nil {
|
if err := a.runGit(filepath.Join(a.ReposDir, castle), "pull"); err != nil {
|
||||||
return fmt.Errorf("pull --all failed for %q: %w", castle, err)
|
return fmt.Errorf("pull --all failed for %q: %w", castle, err)
|
||||||
}
|
}
|
||||||
@@ -220,6 +228,16 @@ func (a *App) Destroy(castle string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !a.Force {
|
||||||
|
confirmed, confirmErr := a.confirmDestroy(castle)
|
||||||
|
if confirmErr != nil {
|
||||||
|
return confirmErr
|
||||||
|
}
|
||||||
|
if !confirmed {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only attempt unlinking managed home files for regular castle directories.
|
// Only attempt unlinking managed home files for regular castle directories.
|
||||||
if castleInfo.Mode()&os.ModeSymlink == 0 {
|
if castleInfo.Mode()&os.ModeSymlink == 0 {
|
||||||
castleHome := filepath.Join(castleRoot, "home")
|
castleHome := filepath.Join(castleRoot, "home")
|
||||||
@@ -233,6 +251,25 @@ func (a *App) Destroy(castle string) error {
|
|||||||
return os.RemoveAll(castleRoot)
|
return os.RemoveAll(castleRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) confirmDestroy(castle string) (bool, error) {
|
||||||
|
reader := a.Stdin
|
||||||
|
if reader == nil {
|
||||||
|
reader = os.Stdin
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := fmt.Fprintf(a.Stdout, "Destroy castle %q? [y/N]: ", castle); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
line, err := bufio.NewReader(reader).ReadString('\n')
|
||||||
|
if err != nil && !errors.Is(err, io.EOF) {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := strings.ToLower(strings.TrimSpace(line))
|
||||||
|
return response == "y" || response == "yes", nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) Open(castle string) error {
|
func (a *App) Open(castle string) error {
|
||||||
if strings.TrimSpace(castle) == "" {
|
if strings.TrimSpace(castle) == "" {
|
||||||
castle = "dotfiles"
|
castle = "dotfiles"
|
||||||
|
|||||||
Reference in New Issue
Block a user