99 "strconv"
1010 "strings"
1111
12+ "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/container/strategies"
13+
1214 "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/python"
1315 "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/setup"
1416 "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
@@ -872,6 +874,9 @@ func dockerCmd(c *cli.Context) error {
872874 err = loginCmd (c )
873875 case "scan" :
874876 return dockerScanCmd (c , image )
877+ // Handle both build and buildx with same handler
878+ case "build" , "buildx" :
879+ err = buildCmd (c )
875880 default :
876881 err = dockerNativeCmd (c )
877882 }
@@ -929,6 +934,39 @@ func pushCmd(c *cli.Context, image string) (err error) {
929934 return
930935}
931936
937+ func buildCmd (c * cli.Context ) error {
938+ if show , err := cliutils .ShowGenericCmdHelpIfNeeded (c , c .Args (), "dockerbuildhelp" ); show || err != nil {
939+ return err
940+ }
941+
942+ // Extract build configuration and arguments
943+ _ , rtDetails , _ , _ , _ , cleanArgs , buildConfiguration , err := extractDockerOptionsFromArgs (c .Args ())
944+ if err != nil {
945+ return err
946+ }
947+ pushOption , dockerFilePath , imageTag , err := extractDockerBuildOptionsFromArgs (cleanArgs )
948+ if err != nil {
949+ return err
950+ }
951+
952+ // Login to the docker registry
953+ err = loginCmd (c )
954+ if err != nil {
955+ return err
956+ }
957+
958+ dockerOptions := strategies.DockerBuildOptions {
959+ DockerFilePath : dockerFilePath ,
960+ PushExpected : pushOption ,
961+ ImageTag : imageTag ,
962+ }
963+
964+ buildCommand := container .NewBuildCommand (cleanArgs ).SetDockerBuildOptions (dockerOptions ).SetBuildConfiguration (buildConfiguration )
965+ buildCommand .SetServerDetails (rtDetails )
966+
967+ return commands .Exec (buildCommand )
968+ }
969+
932970func loginCmd (c * cli.Context ) error {
933971 if show , err := cliutils .ShowGenericCmdHelpIfNeeded (c , c .Args (), "dockerloginhelp" ); show || err != nil {
934972 return err
@@ -967,8 +1005,12 @@ func loginCmd(c *cli.Context) error {
9671005 return errors .New ("you need to specify a registry for login using username and password" )
9681006 }
9691007 cmd := exec .Command ("docker" , "login" , registry , "-u" , user , "-p" , password )
970- _ , err := cmd .CombinedOutput ()
971- return err
1008+ output , err := cmd .CombinedOutput ()
1009+ if err != nil {
1010+ return errorutils .CheckErrorf ("%s, %s" , output , err )
1011+ }
1012+ log .Info (string (output ))
1013+ return nil
9721014 }
9731015
9741016 // if registry is not provided use the default from the server details
@@ -977,12 +1019,13 @@ func loginCmd(c *cli.Context) error {
9771019 }
9781020
9791021 loginCommand := container .NewContainerManagerCommand (containerutils .DockerClient )
1022+ loginCommand .SetPrintConsoleError (true )
9801023 loginCommand .SetServerDetails (rtDetails ).SetLoginRegistry (registry )
9811024 // Perform login
9821025 if err := loginCommand .PerformLogin (rtDetails , containerutils .DockerClient ); err != nil {
9831026 return err
9841027 }
985- log . Info ( "Login Succeeded." )
1028+ // here docker itself returns the login success message, so no need to print it again
9861029 return nil
9871030}
9881031
@@ -1067,6 +1110,44 @@ func extractDockerLoginOptionsFromArgs(args []string) (user, password string, er
10671110 return
10681111}
10691112
1113+ func extractDockerBuildOptionsFromArgs (args []string ) (pushOption bool , dockerfilePath string , imageTag string , err error ) {
1114+ // check for --push flag or output=type=registry or output=push=true flag, first is the shorthand operator of the later
1115+ _ , pushOption , err = coreutils .FindBooleanFlag ("--push" , args )
1116+ if err != nil {
1117+ return
1118+ }
1119+ _ , _ , outputOption , err := coreutils .FindFlag ("--output" , args )
1120+ if err != nil {
1121+ return
1122+ }
1123+ if ! pushOption && outputOption != "" &&
1124+ (strings .Contains (outputOption , "type=registry" ) ||
1125+ (strings .Contains (outputOption , "push=true" ) && strings .Contains (outputOption , "type=image" ))) {
1126+ pushOption = true
1127+ }
1128+
1129+ // Check for -f or --file flag
1130+ _ , _ , dockerfilePath , err = coreutils .FindFlag ("-f" , args )
1131+ if err != nil || dockerfilePath == "" {
1132+ _ , _ , dockerfilePath , _ = coreutils .FindFlag ("--file" , args )
1133+ }
1134+ if dockerfilePath == "" {
1135+ // Default to Dockerfile in current directory
1136+ dockerfilePath = "Dockerfile"
1137+ }
1138+
1139+ // Extract image tag from command
1140+ _ , _ , imageTag , err = coreutils .FindFlag ("-t" , args )
1141+ if err != nil || imageTag == "" {
1142+ // Try --tag flag as alternative
1143+ _ , _ , imageTag , _ = coreutils .FindFlag ("--tag" , args )
1144+ }
1145+ if imageTag == "" {
1146+ err = errors .New ("could not find image tag in the command arguments. Please provide an image tag using the '-t' or '--tag' flag" )
1147+ }
1148+ return
1149+ }
1150+
10701151// Assuming command name is the first argument that isn't a flag.
10711152// Returns the command name, and the filtered arguments slice without it.
10721153func getCommandName (orgArgs []string ) (string , []string ) {
0 commit comments