2020-09-29 05:55:34 +00:00
package lint
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
2022-09-19 20:23:45 +00:00
"gitlab.com/gitlab-org/cli/api"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
"gitlab.com/gitlab-org/cli/pkg/git"
2020-09-29 05:55:34 +00:00
"github.com/MakeNowJust/heredoc"
"github.com/spf13/cobra"
)
2024-01-02 20:31:50 +00:00
var (
ref string
dryRun bool
includeJobs bool
)
2020-09-29 05:55:34 +00:00
func NewCmdLint ( f * cmdutils . Factory ) * cobra . Command {
2022-11-17 18:36:09 +00:00
pipelineCILintCmd := & cobra . Command {
2020-09-29 05:55:34 +00:00
Use : "lint" ,
2022-10-21 14:38:48 +00:00
Short : "Checks if your `.gitlab-ci.yml` file is valid." ,
2020-12-21 15:59:47 +00:00
Args : cobra . MaximumNArgs ( 1 ) ,
2020-09-29 05:55:34 +00:00
Example : heredoc . Doc ( `
2022-12-08 15:14:46 +00:00
$ glab ci lint
2023-12-06 09:11:57 +00:00
# Uses . gitlab - ci . yml in the current directory
2020-12-21 15:59:47 +00:00
2020-12-21 12:21:59 +00:00
$ glab ci lint . gitlab - ci . yml
2020-12-21 15:59:47 +00:00
2020-12-21 12:21:59 +00:00
$ glab ci lint path / to / . gitlab - ci . yml
2020-09-29 05:55:34 +00:00
` ) ,
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
path := ".gitlab-ci.yml"
if len ( args ) == 1 {
path = args [ 0 ]
}
2020-12-21 15:59:47 +00:00
return lintRun ( f , path )
} ,
}
2020-10-20 20:04:23 +00:00
2024-01-02 20:31:50 +00:00
pipelineCILintCmd . Flags ( ) . BoolVarP ( & dryRun , "dry-run" , "" , false , "Run pipeline creation simulation." )
pipelineCILintCmd . Flags ( ) . BoolVarP ( & includeJobs , "include-jobs" , "" , false , "The response should include the list of jobs that would exist in a static check or pipeline simulation." )
pipelineCILintCmd . Flags ( ) . StringVar ( & ref , "ref" , "" , "When dry-run is true, sets the branch or tag context for validating the CI/CD YAML configuration." )
2020-12-21 15:59:47 +00:00
return pipelineCILintCmd
}
2020-09-29 05:55:34 +00:00
2020-12-21 15:59:47 +00:00
func lintRun ( f * cmdutils . Factory , path string ) error {
var err error
out := f . IO . StdOut
2021-01-29 00:56:45 +00:00
c := f . IO . Color ( )
2020-09-29 05:55:34 +00:00
2020-12-21 15:59:47 +00:00
apiClient , err := f . HttpClient ( )
if err != nil {
return err
}
2020-09-29 05:55:34 +00:00
2023-05-12 03:10:59 +00:00
repo , err := f . BaseRepo ( )
if err != nil {
return fmt . Errorf ( "You need to be in a GitLab project repository for this action.\nError: %s" , err )
}
project , err := repo . Project ( apiClient )
if err != nil {
return fmt . Errorf ( "You need to be in a GitLab project repository for this action.\nError: %s" , err )
}
projectID := project . ID
2020-09-29 05:55:34 +00:00
2020-12-21 15:59:47 +00:00
var content [ ] byte
var stdout bytes . Buffer
2020-09-29 05:55:34 +00:00
2020-12-21 15:59:47 +00:00
if git . IsValidURL ( path ) {
resp , err := http . Get ( path )
if err != nil {
return err
}
_ , err = io . Copy ( & stdout , resp . Body )
if err != nil {
return err
}
content = stdout . Bytes ( )
} else {
2022-11-30 12:45:08 +00:00
content , err = os . ReadFile ( path )
2020-12-21 15:59:47 +00:00
if err != nil {
if os . IsNotExist ( err ) {
return fmt . Errorf ( "%s: no such file or directory" , path )
2020-09-29 05:55:34 +00:00
}
2020-12-21 15:59:47 +00:00
return err
}
}
2020-09-29 05:55:34 +00:00
2023-05-12 03:10:59 +00:00
fmt . Fprintln ( f . IO . StdOut , "Validating..." )
2020-12-21 15:59:47 +00:00
2024-01-02 20:31:50 +00:00
lint , err := api . ProjectNamespaceLint ( apiClient , projectID , string ( content ) , ref , dryRun , includeJobs )
2020-12-21 15:59:47 +00:00
if err != nil {
return err
2020-09-29 05:55:34 +00:00
}
2023-05-12 03:10:59 +00:00
if ! lint . Valid {
2021-01-29 00:56:45 +00:00
fmt . Fprintln ( out , c . Red ( path + " is invalid" ) )
2020-12-21 15:59:47 +00:00
for i , err := range lint . Errors {
i ++
fmt . Fprintln ( out , i , err )
}
2022-10-17 19:49:28 +00:00
// Returning the error to cobra here causes the process to exit with code 0, so we exit manually.
os . Exit ( 1 )
2020-12-21 15:59:47 +00:00
}
2022-12-08 15:14:46 +00:00
fmt . Fprintln ( out , c . GreenCheck ( ) , "CI/CD YAML is valid!" )
2020-12-21 15:59:47 +00:00
return nil
2020-09-29 05:55:34 +00:00
}