Skip to content

Commit

Permalink
feat: per OS/arch archive exe path
Browse files Browse the repository at this point in the history
Closes #19
  • Loading branch information
scop committed Nov 16, 2023
1 parent 4eda8fb commit 9acdc94
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 13 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ with the same one command for multiple OS/architectures.
```shellsession
$ wrun -help
Usage of wrun:
-archive-exe-path string
Path to executable within archive (separator always /, implies archive processing)
-archive-exe-path value
[<OS>/<architecture>=]path to executable within archive (separator always /, implies archive processing)
-http-timeout duration
HTTP client timeout (default 5m0s)
-url value
Expand Down
59 changes: 50 additions & 9 deletions wrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,16 @@ type urlMatch struct {
url *url.URL
}

type archiveExePathMatch struct {
pattern string
exePath string
}

type config struct {
urlMatches []urlMatch
archiveExePath string
usePreCommitCache bool
httpTimeout time.Duration
urlMatches []urlMatch
archiveExePathMatches []archiveExePathMatch
usePreCommitCache bool
httpTimeout time.Duration
}

// parseFlags parses command line flags using the given flag set.
Expand Down Expand Up @@ -149,7 +154,22 @@ func parseFlags(set *flag.FlagSet, args []string) (config, error) {
return nil
}
})
set.StringVar(&cfg.archiveExePath, "archive-exe-path", "", "Path to executable within archive (separator always /, implies archive processing)")
set.Func("archive-exe-path", "[<OS>/<architecture>=]path to executable within archive (separator always /, implies archive processing)", func(s string) error {
pattern, pth, found := strings.Cut(s, "=")
if found {
if pattern == "" {
pattern = "*/*"
}
if pth == "" {
return fmt.Errorf("missing path in %q", s)
}
} else {
pth = pattern
pattern = "*/*"
}
cfg.archiveExePathMatches = append(cfg.archiveExePathMatches, archiveExePathMatch{pattern, pth})
return nil
})
set.BoolVar(&cfg.usePreCommitCache, "use-pre-commit-cache", false, "Use pre-commit's cache dir")
set.DurationVar(&cfg.httpTimeout, "http-timeout", defaultHttpTimeout, "HTTP client timeout")
if err := set.Parse(args); err != nil {
Expand All @@ -172,6 +192,20 @@ func selectURL(s string, matches []urlMatch) (*url.URL, error) {
return nil, nil
}

// selectArchiveExePath selects an archive exe path for a system from the given matches.
func selectArchiveExePath(s string, matches []archiveExePathMatch) (string, error) {
for _, m := range matches {
match, err := filepath.Match(m.pattern, s)
if err != nil {
return "", err
}
if match {
return m.exePath, nil
}
}
return "", nil
}

func resolveCacheDir(usePreCommitCache bool) (string, error) {
var (
cacheDir string
Expand Down Expand Up @@ -276,7 +310,7 @@ Environment variables:
return
}

// Figure out download URL
// Figure out download URL and exe path in archive

osArch := runtime.GOOS + "/" + runtime.GOARCH
ur, err := selectURL(osArch, cfg.urlMatches)
Expand All @@ -292,6 +326,13 @@ Environment variables:
}
infoOut("URL: %s", ur)

archiveExePath, err := selectArchiveExePath(osArch, cfg.archiveExePathMatches)
if err != nil {
errorOut("select archive exe path: %v", err)
rc = 2 // usage, bad pattern
return
}

// Set up hashing

hshType, expectedDigest, err := prepareHash(ur.Fragment)
Expand All @@ -311,11 +352,11 @@ Environment variables:
return
}
// Here's hoping we don't hit path too long errors with this implementation anywhere
ps := make([]string, 0, strings.Count(cfg.archiveExePath, "/")+3)
ps := make([]string, 0, strings.Count(archiveExePath, "/")+3)
_, dlBase := path.Split(ur.Path)
ps = append(ps, cacheDir, urlDir(ur, hshType, expectedDigest), dlBase)
dlPath := filepath.Join(ps...)
ps = append(ps, strings.Split(cfg.archiveExePath, "/")...)
ps = append(ps, strings.Split(archiveExePath, "/")...)
exePath := filepath.Join(ps...)
err = os.MkdirAll(filepath.Dir(exePath), 0o777)
if err != nil {
Expand Down Expand Up @@ -430,7 +471,7 @@ Environment variables:

// Move to final location, make executable

if cfg.archiveExePath == "" {
if archiveExePath == "" {
if err = os.Rename(tmpf.Name(), exePath); err != nil {
errorOut("rename tempfile: %v", err)
rc = 1
Expand Down
4 changes: 2 additions & 2 deletions wrun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ func Test_parseFlags(t *testing.T) {
url: mustParseURL(t, urld),
},
},
archiveExePath: "",
httpTimeout: defaultHttpTimeout,
archiveExePathMatches: nil,
httpTimeout: defaultHttpTimeout,
}
got, err := parseFlags(set, args)
require.NoError(t, err)
Expand Down

0 comments on commit 9acdc94

Please sign in to comment.