@@ -2,33 +2,26 @@ package buildinfo
22
33import (
44 "errors"
5- "io"
6- "os"
7- "os/exec"
8- "strconv"
9-
5+ "github.com/forPelevin/gomoji"
106 buildinfo "github.com/jfrog/build-info-go/entities"
117 gofrogcmd "github.com/jfrog/gofrog/io"
12- "github.com/jfrog/jfrog-cli-core/v2 /artifactory/utils"
8+ "github.com/jfrog/jfrog-cli-artifactory /artifactory/utils"
139 "github.com/jfrog/jfrog-cli-core/v2/common/build"
1410 "github.com/jfrog/jfrog-cli-core/v2/common/project"
1511 utilsconfig "github.com/jfrog/jfrog-cli-core/v2/utils/config"
16- "github.com/jfrog/jfrog-client-go/artifactory/services"
17- artclientutils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
1812 clientutils "github.com/jfrog/jfrog-client-go/utils"
19-
20- "github.com/forPelevin/gomoji"
2113 "github.com/jfrog/jfrog-client-go/utils/errorutils"
22- "github.com/jfrog/jfrog-client-go/utils/io/fileutils"
2314 "github.com/jfrog/jfrog-client-go/utils/log"
2415 "github.com/spf13/viper"
16+ "strconv"
2517)
2618
2719const (
2820 GitLogLimit = 100
2921 ConfigIssuesPrefix = "issues."
3022 ConfigParseValueError = "Failed parsing %s from configuration file: %s"
3123 MissingConfigurationError = "Configuration file must contain: %s"
24+ gitParsingPrettyFormat = "format:%s"
3225)
3326
3427type BuildAddGitCommand struct {
@@ -84,15 +77,9 @@ func (config *BuildAddGitCommand) Run() error {
8477 }
8578
8679 // Find .git if it wasn't provided in the command.
87- if config.dotGitPath == "" {
88- var exists bool
89- config.dotGitPath, exists, err = fileutils.FindUpstream(".git", fileutils.Any)
90- if err != nil {
91- return err
92- }
93- if !exists {
94- return errorutils.CheckErrorf("Could not find .git")
95- }
80+ config.dotGitPath, err = utils.GetDotGit(config.dotGitPath)
81+ if err != nil {
82+ return err
9683 }
9784
9885 // Collect URL, branch and revision into GitManager.
@@ -105,7 +92,7 @@ func (config *BuildAddGitCommand) Run() error {
10592 // Collect issues if required.
10693 var issues []buildinfo.AffectedIssue
10794 if config.configFilePath != "" {
108- issues, err = config.collectBuildIssues(gitManager.GetUrl() )
95+ issues, err = config.collectBuildIssues()
10996 if err != nil {
11097 return err
11198 }
@@ -163,77 +150,31 @@ func (config *BuildAddGitCommand) CommandName() string {
163150 return "rt_build_add_git"
164151}
165152
166- func (config *BuildAddGitCommand) collectBuildIssues(vcsUrl string ) ([]buildinfo.AffectedIssue, error) {
153+ func (config *BuildAddGitCommand) collectBuildIssues() ([]buildinfo.AffectedIssue, error) {
167154 log.Info("Collecting build issues from VCS...")
168155
169- // Check that git exists in path.
170- _, err := exec.LookPath("git")
171- if err != nil {
172- return nil, errorutils.CheckError(err)
173- }
174-
175156 // Initialize issues-configuration.
176157 config.issuesConfig = new(IssuesConfiguration)
177158
178159 // Create config's IssuesConfigurations from the provided spec file.
179- err = config.createIssuesConfigs()
160+ err : = config.createIssuesConfigs()
180161 if err != nil {
181162 return nil, err
182163 }
183164
184- // Get latest build's VCS revision from Artifactory.
185- lastVcsRevision , err := config.getLatestVcsRevision(vcsUrl )
165+ var foundIssues []buildinfo.AffectedIssue
166+ logRegExp , err := createLogRegExpHandler( config.issuesConfig, &foundIssues )
186167 if err != nil {
187168 return nil, err
188169 }
189170
190171 // Run issues collection.
191- return config.DoCollect(config.issuesConfig, lastVcsRevision)
192- }
193-
194- func (config *BuildAddGitCommand) DoCollect(issuesConfig *IssuesConfiguration, lastVcsRevision string) (foundIssues []buildinfo.AffectedIssue, err error) {
195- logRegExp, err := createLogRegExpHandler(issuesConfig, &foundIssues)
172+ gitDetails := utils.GitLogDetails{DotGitPath: config.dotGitPath, LogLimit: config.issuesConfig.LogLimit, PrettyFormat: gitParsingPrettyFormat}
173+ err = utils.ParseGitLogFromLastBuild(config.issuesConfig.ServerDetails, config.buildConfiguration, gitDetails, logRegExp)
196174 if err != nil {
197- return
198- }
199-
200- errRegExp, err := createErrRegExpHandler(lastVcsRevision)
201- if err != nil {
202- return
203- }
204-
205- // Get log with limit, starting from the latest commit.
206- logCmd := &LogCmd{logLimit: issuesConfig.LogLimit, lastVcsRevision: lastVcsRevision}
207-
208- // Change working dir to where .git is.
209- wd, err := os.Getwd()
210- if errorutils.CheckError(err) != nil {
211- return
212- }
213- defer func() {
214- err = errors.Join(err, errorutils.CheckError(os.Chdir(wd)))
215- }()
216- err = os.Chdir(config.dotGitPath)
217- if errorutils.CheckError(err) != nil {
218- return
219- }
220-
221- // Run git command.
222- _, _, exitOk, err := gofrogcmd.RunCmdWithOutputParser(logCmd, false, logRegExp, errRegExp)
223- if errorutils.CheckError(err) != nil {
224- var revisionRangeError RevisionRangeError
225- if errors.As(err, &revisionRangeError) {
226- // Revision not found in range. Ignore and don't collect new issues.
227- log.Info(err.Error())
228- return []buildinfo.AffectedIssue{}, nil
229- }
230- return
231- }
232- if !exitOk {
233- // May happen when trying to run git log for non-existing revision.
234- err = errorutils.CheckErrorf("failed executing git log command")
175+ return nil, err
235176 }
236- return
177+ return foundIssues, nil
237178}
238179
239180// Creates a regexp handler to parse and fetch issues from the output of the git log command.
@@ -267,35 +208,6 @@ func createLogRegExpHandler(issuesConfig *IssuesConfiguration, foundIssues *[]bu
267208 return &logRegExp, nil
268209}
269210
270- // Error to be thrown when revision could not be found in the git revision range.
271- type RevisionRangeError struct {
272- ErrorMsg string
273- }
274-
275- func (err RevisionRangeError) Error() string {
276- return err.ErrorMsg
277- }
278-
279- // Creates a regexp handler to handle the event of revision missing in the git revision range.
280- func createErrRegExpHandler(lastVcsRevision string) (*gofrogcmd.CmdOutputPattern, error) {
281- // Create regex pattern.
282- invalidRangeExp, err := clientutils.GetRegExp(`fatal: Invalid revision range [a-fA-F0-9]+\.\.`)
283- if err != nil {
284- return nil, err
285- }
286-
287- // Create handler with exec function.
288- errRegExp := gofrogcmd.CmdOutputPattern{
289- RegExp: invalidRangeExp,
290- ExecFunc: func(pattern *gofrogcmd.CmdOutputPattern) (string, error) {
291- // Revision could not be found in the revision range, probably due to a squash / revert. Ignore and don't collect new issues.
292- errMsg := "Revision: '" + lastVcsRevision + "' that was fetched from latest build info does not exist in the git revision range. No new issues are added."
293- return "", RevisionRangeError{ErrorMsg: errMsg}
294- },
295- }
296- return &errRegExp, nil
297- }
298-
299211func (config *BuildAddGitCommand) createIssuesConfigs() (err error) {
300212 // Read file's data.
301213 err = config.issuesConfig.populateIssuesConfigsFromSpec(config.configFilePath)
@@ -323,50 +235,6 @@ func (config *BuildAddGitCommand) createIssuesConfigs() (err error) {
323235 return
324236}
325237
326- func (config *BuildAddGitCommand) getLatestVcsRevision(vcsUrl string) (string, error) {
327- // Get latest build's build-info from Artifactory
328- buildInfo, err := config.getLatestBuildInfo(config.issuesConfig)
329- if err != nil {
330- return "", err
331- }
332-
333- // Get previous VCS Revision from BuildInfo.
334- lastVcsRevision := ""
335- for _, vcs := range buildInfo.VcsList {
336- if vcs.Url == vcsUrl {
337- lastVcsRevision = vcs.Revision
338- break
339- }
340- }
341-
342- return lastVcsRevision, nil
343- }
344-
345- // Returns build info, or empty build info struct if not found.
346- func (config *BuildAddGitCommand) getLatestBuildInfo(issuesConfig *IssuesConfiguration) (*buildinfo.BuildInfo, error) {
347- // Create services manager to get build-info from Artifactory.
348- sm, err := utils.CreateServiceManager(issuesConfig.ServerDetails, -1, 0, false)
349- if err != nil {
350- return nil, err
351- }
352-
353- // Get latest build-info from Artifactory.
354- buildName, err := config.buildConfiguration.GetBuildName()
355- if err != nil {
356- return nil, err
357- }
358- buildInfoParams := services.BuildInfoParams{BuildName: buildName, BuildNumber: artclientutils.LatestBuildNumberKey}
359- publishedBuildInfo, found, err := sm.GetBuildInfo(buildInfoParams)
360- if err != nil {
361- return nil, err
362- }
363- if !found {
364- return &buildinfo.BuildInfo{}, nil
365- }
366-
367- return &publishedBuildInfo.BuildInfo, nil
368- }
369-
370238func (ic *IssuesConfiguration) populateIssuesConfigsFromSpec(configFilePath string) (err error) {
371239 var vConfig *viper.Viper
372240 vConfig, err = project.ReadConfigFile(configFilePath, project.YAML)
@@ -461,30 +329,3 @@ type IssuesConfiguration struct {
461329 AggregationStatus string
462330 ServerID string
463331}
464-
465- type LogCmd struct {
466- logLimit int
467- lastVcsRevision string
468- }
469-
470- func (logCmd *LogCmd) GetCmd() *exec.Cmd {
471- var cmd []string
472- cmd = append(cmd, "git")
473- cmd = append(cmd, "log", "--pretty=format:%s", "-"+strconv.Itoa(logCmd.logLimit))
474- if logCmd.lastVcsRevision != "" {
475- cmd = append(cmd, logCmd.lastVcsRevision+"..")
476- }
477- return exec.Command(cmd[0], cmd[1:]...)
478- }
479-
480- func (logCmd *LogCmd) GetEnv() map[string]string {
481- return map[string]string{}
482- }
483-
484- func (logCmd *LogCmd) GetStdWriter() io.WriteCloser {
485- return nil
486- }
487-
488- func (logCmd *LogCmd) GetErrWriter() io.WriteCloser {
489- return nil
490- }
0 commit comments