Skip to content

Commit 930f6c0

Browse files
authored
Merge pull request #52 from drognisep/go-sync-webui
Adding a method to sync the webui dependency without scripts
2 parents 6fe1c0b + 07a933c commit 930f6c0

File tree

3 files changed

+214
-0
lines changed

3 files changed

+214
-0
lines changed

v2/sync-webui/gotools.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"os"
7+
"os/exec"
8+
"strings"
9+
)
10+
11+
type Gotools struct {
12+
exe string
13+
}
14+
15+
func GetGo() *Gotools {
16+
exe, err := exec.LookPath("go")
17+
if err != nil {
18+
panic(fmt.Errorf("failed to find go executable on PATH: %w", err))
19+
}
20+
return &Gotools{
21+
exe: exe,
22+
}
23+
}
24+
25+
func (gt *Gotools) Cmd(args ...string) *exec.Cmd {
26+
cmd := exec.Command(gt.exe, args...)
27+
cmd.Stdin = os.Stdin
28+
cmd.Stdout = os.Stdout
29+
cmd.Stderr = os.Stderr
30+
return cmd
31+
}
32+
33+
func (gt *Gotools) CmdSilent(args ...string) *exec.Cmd {
34+
cmd := gt.Cmd(args...)
35+
cmd.Stdout = io.Discard
36+
cmd.Stderr = io.Discard
37+
return cmd
38+
}
39+
40+
func (gt *Gotools) Gopath() (string, error) {
41+
gopath, ok := os.LookupEnv("GOPATH")
42+
if ok {
43+
return gopath, nil
44+
}
45+
output, err := gt.Cmd("env", "GOPATH").Output()
46+
if err != nil {
47+
return "", fmt.Errorf("failed to check GOPATH from go tools: %w", err)
48+
}
49+
gopath = strings.TrimSpace(string(output))
50+
return gopath, nil
51+
}

v2/sync-webui/main.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
"runtime"
9+
)
10+
11+
const (
12+
goWebuiRepo = "github.com/webui-dev/go-webui/v2"
13+
webuiRepo = "github.com/webui-dev/webui"
14+
)
15+
16+
func goWebuiVersion(version string) string {
17+
return fmt.Sprintf("%s@%s", goWebuiRepo, version)
18+
}
19+
20+
func webuiVersion(version string) string {
21+
return fmt.Sprintf("%s@%s", webuiRepo, version)
22+
}
23+
24+
func main() {
25+
// Ensure the current directory is part of a go module.
26+
if !fileExists("go.mod") {
27+
errExit(`error: failed to find go.mod file in current directory.
28+
To set up the go-webui module, use this script in a module directory.`)
29+
}
30+
goTools := GetGo()
31+
// Run go commands
32+
iferrExit(goTools.Cmd("mod", "tidy").Run())
33+
iferrExit(goTools.Cmd("get", goWebuiVersion("main")).Run())
34+
iferrExit(goTools.CmdSilent("get", webuiVersion("main")).Run())
35+
36+
// Retrieve GOPATH (use environment variable if defined, otherwise go env)
37+
goPath, err := goTools.Gopath()
38+
iferrExit(err)
39+
40+
// Parse the first matching version lines from go.sum
41+
// For go-webui/v2:
42+
goWebuiFullVersion := field(headN1(grep(goWebuiRepo, "go.sum")), 2)
43+
// For webui:
44+
webuiFullVersion := field(headN1(grep(webuiRepo, "go.sum")), 2)
45+
46+
// Construct paths based on the parsed versions
47+
goWebuiPath := filepath.Join(goPath, "pkg", "mod", goWebuiVersion(goWebuiFullVersion))
48+
webuiPath := filepath.Join(goPath, "pkg", "mod", webuiVersion(webuiFullVersion))
49+
50+
// Validate that these paths actually exist
51+
iferrExit(validatePaths(goWebuiPath, webuiPath))
52+
linkName := filepath.Join(goWebuiPath, "webui")
53+
// Exit if link already exists in the directory of the used go-webui version.
54+
if dirExists(linkName) {
55+
return
56+
}
57+
58+
// Store original permissions.
59+
// Not strictly necessary, yet we ensure end without changes to the original permissions.
60+
ogPerms, err := getPerms(goWebuiPath)
61+
iferrExit(err)
62+
iferrExit(os.Chmod(goWebuiPath, 0200+ogPerms))
63+
// Linking allows using WebUI C even in cases of multiple go-webui versions without creating bloat.
64+
if err := os.Symlink(webuiPath, linkName); err != nil {
65+
if runtime.GOOS == "windows" {
66+
// (Requires Administrator privileges or Developer Mode)
67+
errExit("mklink failed. Run as Administrator if needed.")
68+
}
69+
errExit(err.Error())
70+
}
71+
// Restore original permissions.
72+
iferrExit(os.Chmod(goWebuiPath, ogPerms))
73+
iferrExit(goTools.Cmd("mod", "tidy").Run())
74+
}
75+
76+
func validatePaths(goWebuiPath, webuiPath string) error {
77+
var errs []error
78+
if !dirExists(goWebuiPath) {
79+
errs = append(errs, fmt.Errorf("failed to find go-webui in '%s'", goWebuiPath))
80+
}
81+
if !dirExists(webuiPath) {
82+
errs = append(errs, fmt.Errorf("failed to find webui in '%s'", webuiPath))
83+
}
84+
return errors.Join(errs...)
85+
}
86+
87+
func iferrExit(err error) {
88+
if err != nil {
89+
fmt.Println(err.Error())
90+
os.Exit(1)
91+
}
92+
}
93+
94+
func errExit(msg string) {
95+
fmt.Println(msg)
96+
os.Exit(1)
97+
}

v2/sync-webui/shellfuncs.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"os"
6+
"strings"
7+
)
8+
9+
func fileExists(path string) bool {
10+
fi, err := os.Stat(path)
11+
if err != nil {
12+
return false
13+
}
14+
return !fi.IsDir()
15+
}
16+
17+
func dirExists(path string) bool {
18+
fi, err := os.Stat(path)
19+
if err != nil {
20+
return false
21+
}
22+
return fi.IsDir()
23+
}
24+
25+
func grep(text, path string) []string {
26+
var lines []string
27+
f, err := os.Open(path)
28+
if err != nil {
29+
return nil
30+
}
31+
defer func() {
32+
_ = f.Close()
33+
}()
34+
scanner := bufio.NewScanner(f)
35+
for scanner.Scan() {
36+
line := scanner.Text()
37+
if strings.Contains(line, text) {
38+
lines = append(lines, line)
39+
}
40+
}
41+
return lines
42+
}
43+
44+
func headN1(lines []string) string {
45+
if len(lines) == 0 {
46+
return ""
47+
}
48+
return lines[0]
49+
}
50+
51+
func field(line string, field int) string {
52+
line = strings.TrimSpace(line)
53+
fields := strings.Split(line, " ")
54+
if len(fields) < field {
55+
return ""
56+
}
57+
return fields[field-1]
58+
}
59+
60+
func getPerms(path string) (os.FileMode, error) {
61+
fi, err := os.Stat(path)
62+
if err != nil {
63+
return 0, err
64+
}
65+
return fi.Mode(), nil
66+
}

0 commit comments

Comments
 (0)