github.com/twelho/conform@v0.0.0-20231016230407-c25e9238598a/cmd/conform/enforce.go (about) 1 // This Source Code Form is subject to the terms of the Mozilla Public 2 // License, v. 2.0. If a copy of the MPL was not distributed with this 3 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 package main 6 7 import ( 8 "errors" 9 "fmt" 10 11 git "github.com/go-git/go-git/v5" 12 "github.com/spf13/cobra" 13 14 "github.com/twelho/conform/internal/enforcer" 15 "github.com/twelho/conform/internal/policy" 16 ) 17 18 // enforceCmd represents the enforce command. 19 var enforceCmd = &cobra.Command{ 20 Use: "enforce", 21 Short: "", 22 Long: ``, 23 RunE: func(cmd *cobra.Command, args []string) error { 24 if len(args) != 0 { 25 return errors.New("the enforce command does not take arguments") 26 } 27 // Done validating the arguments, do not print usage for errors 28 // after this point 29 cmd.SilenceUsage = true 30 31 reporter := cmd.Flags().Lookup("reporter").Value.String() 32 e, err := enforcer.New(reporter) 33 if err != nil { 34 return fmt.Errorf("failed to create enforcer: %w", err) 35 } 36 37 opts := []policy.Option{} 38 39 if commitMsgFile := cmd.Flags().Lookup("commit-msg-file").Value.String(); commitMsgFile != "" { 40 opts = append(opts, policy.WithCommitMsgFile(&commitMsgFile)) 41 } 42 43 if commitRef := cmd.Flags().Lookup("commit-ref").Value.String(); commitRef != "" { 44 opts = append(opts, policy.WithCommitRef(commitRef)) 45 } else { 46 mainBranch, err := detectMainBranch() 47 if err != nil { 48 return fmt.Errorf("failed to detect main branch: %w", err) 49 } 50 if mainBranch != "" { 51 opts = append(opts, policy.WithCommitRef(fmt.Sprintf("refs/heads/%s", mainBranch))) 52 } 53 } 54 55 if baseBranch := cmd.Flags().Lookup("base-branch").Value.String(); baseBranch != "" { 56 opts = append(opts, policy.WithRevisionRange(fmt.Sprintf("%s..HEAD", baseBranch))) 57 } else if revisionRange := cmd.Flags().Lookup("revision-range").Value.String(); revisionRange != "" { 58 opts = append(opts, policy.WithRevisionRange(revisionRange)) 59 } 60 61 return e.Enforce(opts...) 62 }, 63 } 64 65 func init() { 66 enforceCmd.Flags().String("commit-msg-file", "", "the path to the temporary commit message file") 67 enforceCmd.Flags().String("commit-ref", "", "the ref to compare git policies against") 68 enforceCmd.Flags().String("reporter", "none", "the reporter method to use") 69 enforceCmd.Flags().String("revision-range", "", "<commit1>..<commit2>") 70 enforceCmd.Flags().String("base-branch", "", "base branch to compare with") 71 rootCmd.AddCommand(enforceCmd) 72 } 73 74 func detectMainBranch() (string, error) { 75 mainBranch := "main" 76 77 repo, err := git.PlainOpen(".") 78 if err != nil { 79 // not a git repo, ignore 80 return "", nil //nolint:nilerr 81 } 82 83 c, err := repo.Config() 84 if err != nil { 85 return "", fmt.Errorf("failed to get repository configuration: %w", err) 86 } 87 88 rawConfig := c.Raw 89 90 const branchSectionName = "branch" 91 92 branchSection := rawConfig.Section(branchSectionName) 93 for _, b := range branchSection.Subsections { 94 remote := b.Option("remote") 95 if remote == git.DefaultRemoteName { 96 mainBranch = b.Name 97 98 break 99 } 100 } 101 102 return mainBranch, nil 103 }