Files
BrowserOS/packages/browseros/tools/bdev/cmd/init.go
2026-03-05 10:06:41 -08:00

116 lines
3.2 KiB
Go

package cmd
import (
"fmt"
"os"
"path/filepath"
"bdev/internal/config"
"bdev/internal/git"
"bdev/internal/ui"
"github.com/spf13/cobra"
)
var initCmd = &cobra.Command{
Use: "init",
Short: "Initialize a Chromium checkout for bdev",
Long: "Sets up a .bros/ directory in the current Chromium checkout,\nlinking it to a BrowserOS patches repository.",
RunE: runInit,
}
var (
initPatchesRepo string
initName string
)
func init() {
initCmd.Flags().StringVar(&initPatchesRepo, "patches-repo", "", "path to BrowserOS packages directory (required)")
initCmd.Flags().StringVar(&initName, "name", "", "human name for this checkout (default: directory name)")
_ = initCmd.MarkFlagRequired("patches-repo")
rootCmd.AddCommand(initCmd)
}
func runInit(cmd *cobra.Command, args []string) error {
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("getting cwd: %w", err)
}
if !config.LooksLikeChromium(cwd) {
return fmt.Errorf("current directory does not look like a Chromium checkout (missing chrome/, base/, or .git/)")
}
brosDir := filepath.Join(cwd, config.BrosDirName)
if _, err := os.Stat(filepath.Join(brosDir, "config.yaml")); err == nil {
return fmt.Errorf(".bros/config.yaml already exists — checkout already initialized")
}
patchesRepo, err := filepath.Abs(initPatchesRepo)
if err != nil {
return fmt.Errorf("resolving patches repo path: %w", err)
}
patchesDir := filepath.Join(patchesRepo, "chromium_patches")
if _, err := os.Stat(patchesDir); err != nil {
return fmt.Errorf("chromium_patches/ not found in %s", patchesRepo)
}
baseCommit, err := config.ReadBaseCommit(patchesRepo)
if err != nil {
return err
}
if !git.CommitExists(cwd, baseCommit) {
return fmt.Errorf("BASE_COMMIT %s not found in this checkout's git history", baseCommit)
}
name := initName
if name == "" {
name = filepath.Base(cwd)
}
cfg := &config.Config{
Name: name,
PatchesRepo: patchesRepo,
}
if err := config.WriteConfig(brosDir, cfg); err != nil {
return err
}
// Create logs directory
if err := os.MkdirAll(filepath.Join(brosDir, "logs"), 0o755); err != nil {
return fmt.Errorf("creating logs directory: %w", err)
}
chromiumVersion, _ := config.ReadChromiumVersion(patchesRepo)
// Count existing patches
patchCount := 0
_ = filepath.Walk(patchesDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if !info.IsDir() {
patchCount++
}
return nil
})
fmt.Println(ui.TitleStyle.Render("bdev init"))
fmt.Println()
fmt.Printf(" %s %s\n", ui.LabelStyle.Render("Checkout:"), ui.ValueStyle.Render(name))
fmt.Printf(" %s %s\n", ui.LabelStyle.Render("Directory:"), cwd)
fmt.Printf(" %s %s\n", ui.LabelStyle.Render("Patches repo:"), patchesRepo)
fmt.Printf(" %s %s\n", ui.LabelStyle.Render("Base commit:"), baseCommit[:min(12, len(baseCommit))])
if chromiumVersion != "" {
fmt.Printf(" %s %s\n", ui.LabelStyle.Render("Chromium:"), chromiumVersion)
}
fmt.Printf(" %s %d files\n", ui.LabelStyle.Render("Patches:"), patchCount)
fmt.Println()
fmt.Println(ui.SuccessStyle.Render("Initialized .bros/config.yaml"))
fmt.Println(ui.MutedStyle.Render("Run 'bdev pull' to apply patches, or 'bdev push' to extract."))
return nil
}