Skip to content

Commit c65d986

Browse files
committed
update
1 parent 2332065 commit c65d986

File tree

4 files changed

+322
-177
lines changed

4 files changed

+322
-177
lines changed

cmd/manageDeploymentRepo.go

Lines changed: 31 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
11
package cmd
22

33
import (
4-
"errors"
54
"fmt"
6-
"log"
7-
"os"
8-
"path/filepath"
9-
"time"
105

116
"github.com/go-git/go-git/v5"
12-
"github.com/go-git/go-git/v5/config"
13-
"github.com/go-git/go-git/v5/plumbing"
14-
"github.com/go-git/go-git/v5/plumbing/object"
7+
deploymentrepo "github.com/openmcp-project/bootstrapper/internal/deployment-repo"
8+
"github.com/openmcp-project/bootstrapper/internal/log"
9+
"github.com/openmcp-project/bootstrapper/internal/util"
1510
"github.com/spf13/cobra"
1611

1712
gitconfig "github.com/openmcp-project/bootstrapper/internal/git-config"
18-
"github.com/openmcp-project/bootstrapper/internal/template"
1913
)
2014

2115
const (
@@ -25,34 +19,34 @@ const (
2519
type LogWriter struct{}
2620

2721
func (w LogWriter) Write(p []byte) (n int, err error) {
28-
log.Print(string(p))
22+
logger := log.GetLogger()
23+
logger.Debugf("Git progress: %s", string(p))
2924
return len(p), nil
3025
}
3126

3227
// manageDeploymentRepoCmd represents the manageDeploymentRepo command
3328
var manageDeploymentRepoCmd = &cobra.Command{
3429
Use: "manageDeploymentRepo",
35-
Short: "A brief description of your command",
36-
Long: `A longer description that spans multiple lines and likely contains examples
37-
and usage of using your command. For example:
38-
39-
Cobra is a CLI library for Go that empowers applications.
40-
This application is a tool to generate the needed files
41-
to quickly create a Cobra application.`,
30+
Short: "Updates the openMCP deployment specification in the specified Git repository",
31+
Long: `Updates the openMCP deployment specification in the specified Git repository.
32+
The update is based on the specified component version.
33+
openmcp-bootstrapper manageDeploymentRepo <componentLocation> <templateDirectory> <deploymentRepository> <deploymentRepositoryBranch>`,
4234
Args: cobra.ExactArgs(4),
4335
ArgAliases: []string{
4436
"componentLocation",
4537
"templateDirectory",
4638
"deploymentRepository",
4739
"deploymentRepositoryBranch",
4840
},
41+
Example: ` openmcp-bootstrapper manageDeploymentRepo "ghcr.io/openmcp-project/components//github.com/openmcp-project/openmcp:${OPENMCP_VERSION}" ./templates "https://github.com/${GITHUB_USER}/deployment-repo.git" incoming-branch`,
4942
RunE: func(cmd *cobra.Command, args []string) error {
5043
//componentLocation := args[0]
5144
templateDirectory := args[1]
5245
deploymentRepository := args[2]
5346
deploymentRepositoryBranch := args[3]
5447

55-
log.Println("parsing git config file from flag:", cmd.Flag(FlagGitConfig).Value.String())
48+
logger := log.GetLogger()
49+
logger.Debug("parsing git config file from flag:", cmd.Flag(FlagGitConfig).Value.String())
5650

5751
gitConfig, err := gitconfig.ParseConfig(cmd.Flag(FlagGitConfig).Value.String())
5852
if err != nil {
@@ -70,164 +64,40 @@ to quickly create a Cobra application.`,
7064
return err
7165
}
7266

73-
tmpDir, err := os.MkdirTemp("", "deployment-repo-")
74-
if err != nil {
75-
return fmt.Errorf("failed to create temp dir: %w", err)
76-
}
77-
78-
repo, err := CloneRepo(deploymentRepository, tmpDir, gitConfig)
79-
log.Println("Cloned repository to temporary directory: ", tmpDir)
67+
tempDir, err := util.CreateTempDir("deployment-repo-")
68+
logger.Tracef("Created temp dir: %s", tempDir)
8069
if err != nil {
81-
return fmt.Errorf("failed to clone repository: %w", err)
70+
return fmt.Errorf("failed to create temporary directory for deployment repository: %w", err)
8271
}
83-
defer func(path string) {
84-
err := os.RemoveAll(path)
85-
if err != nil {
86-
_, _ = fmt.Fprintf(os.Stderr, "failed to remove temporary directory %s: %v\n", path, err)
72+
defer func() {
73+
if err := util.DeleteTempDir(tempDir); err != nil {
74+
logger.Errorf("failed to delete temporary directory %s: %v", tempDir, err)
8775
}
88-
}(tmpDir)
76+
}()
8977

90-
// Check if branch exists (local or remote)
91-
branchExists := false
92-
references, err := repo.References()
78+
repo, err := deploymentrepo.CloneRepo(deploymentRepository, tempDir, gitConfig)
9379
if err != nil {
94-
return fmt.Errorf("failed to list references: %w", err)
95-
}
96-
localRef := plumbing.NewBranchReferenceName(deploymentRepositoryBranch)
97-
remoteRef := plumbing.NewRemoteReferenceName("origin", deploymentRepositoryBranch)
98-
err = references.ForEach(func(ref *plumbing.Reference) error {
99-
log.Printf("Found reference: %s", ref.Name())
100-
if ref.Name() == localRef || ref.Name() == remoteRef {
101-
branchExists = true
102-
log.Printf("Branch %s exists as %s", deploymentRepositoryBranch, ref.Name())
103-
}
104-
return nil
105-
})
106-
if err != nil {
107-
return err
80+
return fmt.Errorf("failed to clone deployment repository: %w", err)
10881
}
10982

110-
workTree, err := repo.Worktree()
83+
err = deploymentrepo.CheckoutAndCreateBranchIfNotExists(repo, deploymentRepositoryBranch, gitConfig)
11184
if err != nil {
112-
return fmt.Errorf("failed to get worktree: %w", err)
113-
}
114-
115-
if !branchExists {
116-
// Create and checkout new branch
117-
log.Printf("Branch %s does not exist. Creating...\n", deploymentRepositoryBranch)
118-
err = workTree.Checkout(&git.CheckoutOptions{
119-
Branch: localRef,
120-
Create: true,
121-
})
122-
if err != nil {
123-
return fmt.Errorf("failed to create branch: %w", err)
124-
}
125-
126-
pushOptions := &git.PushOptions{
127-
RefSpecs: []config.RefSpec{
128-
config.RefSpec(localRef + ":" + localRef),
129-
},
130-
Progress: LogWriter{},
131-
}
132-
133-
if err := gitConfig.ConfigurePushOptions(pushOptions); err != nil {
134-
return fmt.Errorf("failed to configure push options: %w", err)
135-
}
136-
137-
// Push new branch to remote
138-
err = repo.Push(pushOptions)
139-
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
140-
return fmt.Errorf("failed to push new branch: %w", err)
141-
}
142-
} else {
143-
// Checkout existing branch
144-
err = workTree.Checkout(&git.CheckoutOptions{
145-
Branch: remoteRef,
146-
})
147-
if err != nil {
148-
return fmt.Errorf("failed to checkout branch: %w", err)
149-
}
85+
return fmt.Errorf("failed to checkout or create branch %s: %w", deploymentRepositoryBranch, err)
15086
}
15187

152-
// open the template directory
153-
templateDir, err := os.Open(templateDirectory)
88+
err = deploymentrepo.TemplateDir(templateDirectory, repo)
15489
if err != nil {
155-
return fmt.Errorf("failed to open template directory: %w", err)
90+
return fmt.Errorf("failed to apply templates from directory %s: %w", templateDirectory, err)
15691
}
157-
defer func() {
158-
if err := templateDir.Close(); err != nil {
159-
fmt.Fprintf(os.Stderr, "failed to close template directory: %v\n", err)
160-
}
161-
}()
162-
163-
te := template.NewTemplateExecution()
164-
templateInput := make(map[string]interface{})
165-
166-
// Recursively walk through all files in the template directory
167-
err = filepath.WalkDir(templateDirectory, func(path string, d os.DirEntry, err error) error {
168-
if err != nil {
169-
return err
170-
}
171-
if !d.IsDir() {
172-
// Process the file (path)
173-
log.Printf("Found file: %s\n", path)
174-
template, err := os.ReadFile(path)
175-
if err != nil {
176-
return fmt.Errorf("failed to read template file %s: %w", path, err)
177-
}
178-
179-
templateResult, err := te.Execute(path, string(template), templateInput)
180-
if err != nil {
181-
return fmt.Errorf("failed to execute template %s: %w", path, err)
182-
}
18392

184-
pathInRepo, err := filepath.Rel(templateDirectory, path)
185-
fileInWt, err := workTree.Filesystem.OpenFile(pathInRepo, os.O_WRONLY|os.O_CREATE, 0644)
186-
if err != nil {
187-
return fmt.Errorf("failed to open file in worktree %s: %w", path, err)
188-
}
189-
defer fileInWt.Close()
190-
_, err = fileInWt.Write(templateResult)
191-
if err != nil {
192-
return fmt.Errorf("failed to write to file in worktree %s: %w", path, err)
193-
}
194-
// Add the file to the git index
195-
if _, err := workTree.Add(pathInRepo); err != nil {
196-
return fmt.Errorf("failed to add file to git index: %w", err)
197-
}
198-
}
199-
return nil
200-
})
93+
err = deploymentrepo.CommitChanges(repo, "apply templates", "openmcp", "[email protected]")
20194
if err != nil {
202-
return fmt.Errorf("failed to walk template directory: %w", err)
95+
return fmt.Errorf("failed to commit changes: %w", err)
20396
}
20497

205-
// Commit the changes
206-
commitMsg := "Update deployment repo with template files"
207-
_, err = workTree.Commit(commitMsg, &git.CommitOptions{
208-
Author: &object.Signature{
209-
Name: "openmcp-bootstrapper",
210-
211-
When: time.Now(),
212-
},
213-
})
98+
err = deploymentrepo.PushRepo(repo, gitConfig)
21499
if err != nil {
215-
if !errors.Is(err, git.ErrEmptyCommit) {
216-
return fmt.Errorf("failed to commit changes: %w", err)
217-
}
218-
}
219-
220-
// Push the changes
221-
pushOptions := &git.PushOptions{}
222-
if err := gitConfig.ConfigurePushOptions(pushOptions); err != nil {
223-
return fmt.Errorf("failed to configure push options: %w", err)
224-
}
225-
pushOptions.Progress = LogWriter{}
226-
err = repo.Push(pushOptions)
227-
if err != nil {
228-
if !errors.Is(err, git.NoErrAlreadyUpToDate) {
229-
return fmt.Errorf("failed to push changes: %w", err)
230-
}
100+
return fmt.Errorf("failed to push changes to deployment repository: %w", err)
231101
}
232102

233103
return nil
@@ -237,6 +107,8 @@ to quickly create a Cobra application.`,
237107
func init() {
238108
RootCmd.AddCommand(manageDeploymentRepoCmd)
239109

110+
manageDeploymentRepoCmd.Flags().SortFlags = false
111+
240112
manageDeploymentRepoCmd.Flags().StringArray("cluster-providers", nil, "List of cluster providers to manage")
241113
manageDeploymentRepoCmd.Flags().StringArray("serviceProviders", nil, "List of service providers to manage")
242114
manageDeploymentRepoCmd.Flags().StringArray("platformServices", nil, "List of platform services to manage")
@@ -248,21 +120,3 @@ func init() {
248120
panic(err)
249121
}
250122
}
251-
252-
func CloneRepo(repoURL, path string, config *gitconfig.Config) (*git.Repository, error) {
253-
cloneOptions := &git.CloneOptions{
254-
URL: repoURL,
255-
SingleBranch: false,
256-
}
257-
258-
if err := config.ConfigureCloneOptions(cloneOptions); err != nil {
259-
return nil, err
260-
}
261-
262-
repo, err := git.PlainClone(path, false, cloneOptions)
263-
if err != nil {
264-
return nil, fmt.Errorf("failed to clone repository: %w", err)
265-
}
266-
267-
return repo, nil
268-
}

0 commit comments

Comments
 (0)