返回 DeepSeek-Reasonix
shell.go
1 package installlayout
2
3 import (
4 "fmt"
5 "io/fs"
6 "os"
7 "path/filepath"
8 "runtime"
9 )
10
11 // AppShellDirName is the tree member inside versions/<version>/ that holds the
12 // Electron shell bundle beside the Go desktop binary.
13 const AppShellDirName = "app"
14
15 // ShellExecutableName is the shell executable base name under app/.
16 func ShellExecutableName() string { return ShellExecutableNameFor(runtime.GOOS) }
17
18 // ShellExecutableNameFor returns the shell executable base name for goos.
19 func ShellExecutableNameFor(goos string) string {
20 switch goos {
21 case "windows":
22 return "Reasonix.exe"
23 case "darwin":
24 return "Reasonix"
25 default:
26 return "Reasonix"
27 }
28 }
29
30 // ShellMembers enumerates a complete shell tree without following symlinks.
31 // Legacy flat releases may omit it; a present tree must contain its entry and
32 // renderer resources before any version pointer can be committed.
33 func ShellMembers(root, goos string) ([]Member, error) {
34 tree := filepath.Join(root, AppShellDirName)
35 if _, err := os.Lstat(tree); os.IsNotExist(err) {
36 return nil, nil
37 } else if err != nil {
38 return nil, err
39 }
40 var members []Member
41 seen := map[string]bool{}
42 err := filepath.WalkDir(tree, func(p string, d fs.DirEntry, err error) error {
43 if err != nil {
44 return err
45 }
46 if d.Type()&os.ModeSymlink != 0 {
47 return fmt.Errorf("shell tree contains symlink: %s", p)
48 }
49 if d.IsDir() {
50 return nil
51 }
52 info, err := d.Info()
53 if err != nil {
54 return err
55 }
56 if !info.Mode().IsRegular() {
57 return fmt.Errorf("shell tree member is not regular: %s", p)
58 }
59 rel, err := filepath.Rel(root, p)
60 if err != nil {
61 return err
62 }
63 name := filepath.ToSlash(rel)
64 if err := ValidateMemberName(name); err != nil {
65 return err
66 }
67 members = append(members, Member{Name: name, Path: p, Mode: info.Mode().Perm()})
68 seen[name] = true
69 return nil
70 })
71 if err != nil {
72 return nil, err
73 }
74 for _, name := range ShellRequiredNames(goos) {
75 if !seen[name] {
76 return nil, fmt.Errorf("shell tree missing %s", name)
77 }
78 }
79 return members, nil
80 }
81
82 func ShellRequiredNames(goos string) []string {
83 return []string{"app/" + ShellExecutableNameFor(goos), "app/resources/app.asar", "app/resources/app/index.html", "app/resources/build.json"}
84 }
85
85 lines GO