maidn-cli/cmd/fresh.go

103 lines
3.6 KiB
Go

package cmd
import (
"fmt"
"github.com/Pingu-Studio/MaidnCLI/internal/bootstrap"
"github.com/Pingu-Studio/MaidnCLI/internal/config"
"github.com/Pingu-Studio/MaidnCLI/internal/forgejo"
"github.com/spf13/cobra"
)
var freshConfigPath, freshOrganization, onboardConfigPath, onboardFrom string
var freshCreateOrganization, freshEnableDelivery, freshYes bool
var freshMode string
var loadFreshConfig = config.LoadRaw
var runFreshOrganization = bootstrap.RunFreshOrganization
var resolveAppOnboarding = config.ResolveAppOnboarding
var ensureOnboardCheckoutClean = forgejo.EnsureCleanCheckout
var onboardCheckoutOrigin = forgejo.CheckoutOrigin
var onboardCheckoutBranch = forgejo.CurrentBranch
var generateAppDelivery = bootstrap.GenerateAppDelivery
var bootstrapInitCmd = &cobra.Command{
Use: "init",
Short: "Create and lock a fresh Forgejo organization bootstrap workspace.",
RunE: runBootstrapInit,
}
var appCmd = &cobra.Command{
Use: "app",
Short: "Manage application delivery scaffolding.",
}
var appOnboardCmd = &cobra.Command{
Use: "onboard",
Short: "Validate an application checkout and add its source-owned delivery contract.",
RunE: runAppOnboard,
}
func init() {
bootstrapCmd.AddCommand(bootstrapInitCmd)
bootstrapInitCmd.Flags().StringVar(&freshConfigPath, "config", "", "Path to private bootstrap config YAML")
bootstrapInitCmd.Flags().StringVar(&freshOrganization, "organization", "", "New Forgejo organization name")
bootstrapInitCmd.Flags().BoolVar(&freshCreateOrganization, "create-organization", false, "Create the Forgejo organization when absent")
bootstrapInitCmd.Flags().BoolVar(&freshEnableDelivery, "enable-delivery", false, "Initialize delivery repository prerequisites")
bootstrapInitCmd.Flags().StringVar(&freshMode, "mode", string(bootstrap.Reconcile), "Lifecycle mode: reconcile or rebuild")
bootstrapInitCmd.Flags().BoolVar(&freshYes, "yes", false, "Confirm destructive rebuild")
_ = bootstrapInitCmd.MarkFlagRequired("config")
_ = bootstrapInitCmd.MarkFlagRequired("organization")
rootCmd.AddCommand(appCmd)
appCmd.AddCommand(appOnboardCmd)
appOnboardCmd.Flags().StringVar(&onboardConfigPath, "config", "", "Path to private bootstrap config YAML")
appOnboardCmd.Flags().StringVar(&onboardFrom, "from", "", "Clean application checkout to scaffold")
_ = appOnboardCmd.MarkFlagRequired("config")
_ = appOnboardCmd.MarkFlagRequired("from")
}
func runBootstrapInit(cmd *cobra.Command, _ []string) error {
cfg, err := loadFreshConfig(freshConfigPath)
if err != nil {
return err
}
plan, err := runFreshOrganization(cfg, bootstrap.FreshOrganizationOptions{Organization: freshOrganization, CreateOrganization: freshCreateOrganization, EnableDelivery: freshEnableDelivery, Mode: bootstrap.Mode(freshMode), ConfirmRebuild: freshYes})
if err != nil {
return err
}
for _, phase := range plan.Phases {
fmt.Fprintf(cmd.OutOrStdout(), "[PLAN] %s\n", phase)
}
return nil
}
func runAppOnboard(_ *cobra.Command, _ []string) error {
cfg, err := loadFreshConfig(onboardConfigPath)
if err != nil {
return err
}
cfg, err = resolveAppOnboarding(cfg)
if err != nil {
return err
}
if err := ensureOnboardCheckoutClean(onboardFrom); err != nil {
return err
}
origin, err := onboardCheckoutOrigin(onboardFrom)
if err != nil {
return err
}
if config.RedactURL(origin) != cfg.Delivery.AppRepoURL {
return fmt.Errorf("--from origin does not match delivery appRepoUrl")
}
branch, err := onboardCheckoutBranch(onboardFrom)
if err != nil {
return err
}
if branch != cfg.Delivery.AppRepoRef {
return fmt.Errorf("--from branch must match delivery appRepoRef")
}
return generateAppDelivery(onboardFrom, cfg)
}