| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "bytes" |
| 5 | "encoding/json" |
| 6 | "flag" |
| 7 | "fmt" |
| 8 | "os" |
| 9 | "os/exec" |
| 10 | "path/filepath" |
| 11 | "sort" |
| 12 | "strings" |
| 13 | |
| 14 | "amadan.net/oficina/estilo.git/credits" |
| 15 | "amadan.net/oficina/estilo.git/credits/catalog" |
| 16 | ) |
| 17 | |
| 18 | func main() { |
| 19 | entry := flag.String("package", "", "production Go package") |
| 20 | excludes := flag.String("exclude", "", "comma-separated first-party module paths") |
| 21 | lucide := flag.Bool("lucide", false, "include vendored Lucide and Feather notices") |
| 22 | onest := flag.Bool("onest", false, "include the Onest font notice (apps that mount theme.FontHandler)") |
| 23 | flag.Parse() |
| 24 | if *entry == "" || flag.NArg() != 0 { |
| 25 | fmt.Fprintln(os.Stderr, "oficina-notices: -package is required") |
| 26 | os.Exit(2) |
| 27 | } |
| 28 | command := exec.Command("go", "list", "-deps", "-json", *entry) |
| 29 | command.Stderr = os.Stderr |
| 30 | raw, err := command.Output() |
| 31 | if err != nil { |
| 32 | fmt.Fprintln(os.Stderr, "oficina-notices: go list failed") |
| 33 | os.Exit(1) |
| 34 | } |
| 35 | excluded := map[string]bool{} |
| 36 | for _, name := range strings.Split(*excludes, ",") { |
| 37 | if name = strings.TrimSpace(name); name != "" { |
| 38 | excluded[name] = true |
| 39 | } |
| 40 | } |
| 41 | inventory, err := catalog.Collect(bytes.NewReader(raw), excluded) |
| 42 | if err != nil { |
| 43 | fmt.Fprintln(os.Stderr, err) |
| 44 | os.Exit(1) |
| 45 | } |
| 46 | env, err := exec.Command("go", "env", "-json", "GOROOT", "GOVERSION").Output() |
| 47 | if err != nil { |
| 48 | fmt.Fprintln(os.Stderr, "oficina-notices: Go provenance unavailable") |
| 49 | os.Exit(1) |
| 50 | } |
| 51 | var toolchain struct{ GOROOT, GOVERSION string } |
| 52 | if json.Unmarshal(env, &toolchain) != nil || toolchain.GOROOT == "" || toolchain.GOVERSION == "" { |
| 53 | fmt.Fprintln(os.Stderr, "oficina-notices: invalid Go provenance") |
| 54 | os.Exit(1) |
| 55 | } |
| 56 | license, err := os.ReadFile(filepath.Join(toolchain.GOROOT, "LICENSE")) |
| 57 | if err != nil { |
| 58 | fmt.Fprintln(os.Stderr, "oficina-notices: Go license unavailable") |
| 59 | os.Exit(1) |
| 60 | } |
| 61 | inventory.Components = append(inventory.Components, credits.Component{Name: "Go", Version: toolchain.GOVERSION, SourceURL: "https://go.dev/LICENSE", Notices: []credits.Notice{{Name: "LICENSE", Text: string(license)}}}) |
| 62 | if *lucide { |
| 63 | inventory.Components = append(inventory.Components, credits.Lucide()) |
| 64 | } |
| 65 | if *onest { |
| 66 | inventory.Components = append(inventory.Components, credits.Onest()) |
| 67 | } |
| 68 | sort.Slice(inventory.Components, func(i, j int) bool { return inventory.Components[i].Name < inventory.Components[j].Name }) |
| 69 | encoder := json.NewEncoder(os.Stdout) |
| 70 | encoder.SetIndent("", " ") |
| 71 | if err := encoder.Encode(inventory); err != nil { |
| 72 | os.Exit(1) |
| 73 | } |
| 74 | } |
| 75 | |