@@ -1465,7 +1465,15 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
14651465 if len (cfg .params .SourcePaths ) != 1 {
14661466 return errors .New ("checksum can't be specified for multiple sources" )
14671467 }
1468- if ! isHTTPSource (cfg .params .SourcePaths [0 ]) && ! isGitSource (cfg .params .SourcePaths [0 ]) {
1468+ isHTTPSourceV , err := isHTTPSource (cfg .params .SourcePaths [0 ])
1469+ if err != nil {
1470+ return err
1471+ }
1472+ isGitSourceV , err := isGitSource (cfg .params .SourcePaths [0 ])
1473+ if err != nil {
1474+ return err
1475+ }
1476+ if ! isHTTPSourceV && ! isGitSourceV {
14691477 return errors .New ("checksum requires HTTP(S) or Git sources" )
14701478 }
14711479 }
@@ -1530,96 +1538,102 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
15301538 } else {
15311539 a = a .Copy (st , "/" , dest , opts ... )
15321540 }
1533- } else if isHTTPSource (src ) {
1534- if ! cfg .isAddCommand {
1535- return errors .New ("source can't be a URL for COPY" )
1541+ } else {
1542+ isHTTPSourceV , err := isHTTPSource (src )
1543+ if err != nil {
1544+ return err
15361545 }
1546+ if isHTTPSourceV {
1547+ if ! cfg .isAddCommand {
1548+ return errors .New ("source can't be a URL for COPY" )
1549+ }
15371550
1538- // Resources from remote URLs are not decompressed.
1539- // https://docs.docker.com/engine/reference/builder/#add
1540- //
1541- // Note: mixing up remote archives and local archives in a single ADD instruction
1542- // would result in undefined behavior: https://github.com/moby/buildkit/pull/387#discussion_r189494717
1543- u , err := url .Parse (src )
1544- f := "__unnamed__"
1545- if err == nil {
1546- if base := path .Base (u .Path ); base != "." && base != "/" {
1547- f = base
1551+ // Resources from remote URLs are not decompressed.
1552+ // https://docs.docker.com/engine/reference/builder/#add
1553+ //
1554+ // Note: mixing up remote archives and local archives in a single ADD instruction
1555+ // would result in undefined behavior: https://github.com/moby/buildkit/pull/387#discussion_r189494717
1556+ u , err := url .Parse (src )
1557+ f := "__unnamed__"
1558+ if err == nil {
1559+ if base := path .Base (u .Path ); base != "." && base != "/" {
1560+ f = base
1561+ }
15481562 }
1549- }
15501563
1551- var checksum digest.Digest
1552- if cfg .checksum != "" {
1553- checksum , err = digest .Parse (cfg .checksum )
1554- if err != nil {
1555- return err
1564+ var checksum digest.Digest
1565+ if cfg .checksum != "" {
1566+ checksum , err = digest .Parse (cfg .checksum )
1567+ if err != nil {
1568+ return err
1569+ }
15561570 }
1557- }
15581571
1559- st := llb .HTTP (src , llb .Filename (f ), llb .WithCustomName (pgName ), llb .Checksum (checksum ), dfCmd (cfg .params ))
1572+ st := llb .HTTP (src , llb .Filename (f ), llb .WithCustomName (pgName ), llb .Checksum (checksum ), dfCmd (cfg .params ))
15601573
1561- var unpack bool
1562- if cfg .unpack != nil {
1563- unpack = * cfg .unpack
1564- }
1574+ var unpack bool
1575+ if cfg .unpack != nil {
1576+ unpack = * cfg .unpack
1577+ }
15651578
1566- opts := append ([]llb.CopyOption {& llb.CopyInfo {
1567- Mode : chopt ,
1568- CreateDestPath : true ,
1569- AttemptUnpack : unpack ,
1570- }}, copyOpt ... )
1579+ opts := append ([]llb.CopyOption {& llb.CopyInfo {
1580+ Mode : chopt ,
1581+ CreateDestPath : true ,
1582+ AttemptUnpack : unpack ,
1583+ }}, copyOpt ... )
15711584
1572- if a == nil {
1573- a = llb .Copy (st , f , dest , opts ... )
1574- } else {
1575- a = a .Copy (st , f , dest , opts ... )
1576- }
1577- } else {
1578- validateCopySourcePath (src , & cfg )
1579- var patterns []string
1580- if cfg .parents {
1581- // detect optional pivot point
1582- parent , pattern , ok := strings .Cut (src , "/./" )
1583- if ! ok {
1584- pattern = src
1585- src = "/"
1585+ if a == nil {
1586+ a = llb .Copy (st , f , dest , opts ... )
15861587 } else {
1587- src = parent
1588+ a = a . Copy ( st , f , dest , opts ... )
15881589 }
1590+ } else {
1591+ validateCopySourcePath (src , & cfg )
1592+ var patterns []string
1593+ if cfg .parents {
1594+ // detect optional pivot point
1595+ parent , pattern , ok := strings .Cut (src , "/./" )
1596+ if ! ok {
1597+ pattern = src
1598+ src = "/"
1599+ } else {
1600+ src = parent
1601+ }
15891602
1590- pattern , err = system .NormalizePath ("/" , pattern , d .platform .OS , false )
1603+ pattern , err = system .NormalizePath ("/" , pattern , d .platform .OS , false )
1604+ if err != nil {
1605+ return errors .Wrap (err , "removing drive letter" )
1606+ }
1607+
1608+ patterns = []string {strings .TrimPrefix (pattern , "/" )}
1609+ }
1610+
1611+ src , err = system .NormalizePath ("/" , src , d .platform .OS , false )
15911612 if err != nil {
15921613 return errors .Wrap (err , "removing drive letter" )
15931614 }
15941615
1595- patterns = []string {strings .TrimPrefix (pattern , "/" )}
1596- }
1597-
1598- src , err = system .NormalizePath ("/" , src , d .platform .OS , false )
1599- if err != nil {
1600- return errors .Wrap (err , "removing drive letter" )
1601- }
1602-
1603- unpack := cfg .isAddCommand
1604- if cfg .unpack != nil {
1605- unpack = * cfg .unpack
1606- }
1607-
1608- opts := append ([]llb.CopyOption {& llb.CopyInfo {
1609- Mode : chopt ,
1610- FollowSymlinks : true ,
1611- CopyDirContentsOnly : true ,
1612- IncludePatterns : patterns ,
1613- AttemptUnpack : unpack ,
1614- CreateDestPath : true ,
1615- AllowWildcard : true ,
1616- AllowEmptyWildcard : true ,
1617- }}, copyOpt ... )
1616+ unpack := cfg .isAddCommand
1617+ if cfg .unpack != nil {
1618+ unpack = * cfg .unpack
1619+ }
16181620
1619- if a == nil {
1620- a = llb .Copy (cfg .source , src , dest , opts ... )
1621- } else {
1622- a = a .Copy (cfg .source , src , dest , opts ... )
1621+ opts := append ([]llb.CopyOption {& llb.CopyInfo {
1622+ Mode : chopt ,
1623+ FollowSymlinks : true ,
1624+ CopyDirContentsOnly : true ,
1625+ IncludePatterns : patterns ,
1626+ AttemptUnpack : unpack ,
1627+ CreateDestPath : true ,
1628+ AllowWildcard : true ,
1629+ AllowEmptyWildcard : true ,
1630+ }}, copyOpt ... )
1631+
1632+ if a == nil {
1633+ a = llb .Copy (cfg .source , src , dest , opts ... )
1634+ } else {
1635+ a = a .Copy (cfg .source , src , dest , opts ... )
1636+ }
16231637 }
16241638 }
16251639 }
@@ -2282,19 +2296,26 @@ func commonImageNames() []string {
22822296 return out
22832297}
22842298
2285- func isHTTPSource (src string ) bool {
2299+ func isHTTPSource (src string ) ( bool , error ) {
22862300 if ! strings .HasPrefix (src , "http://" ) && ! strings .HasPrefix (src , "https://" ) {
2287- return false
2301+ return false , nil
22882302 }
2289- return ! isGitSource (src )
2303+ b , err := isGitSource (src )
2304+ return ! b , err
22902305}
22912306
2292- func isGitSource (src string ) bool {
2307+ func isGitSource (src string ) ( bool , error ) {
22932308 // https://github.com/ORG/REPO.git is a git source, not an http source
2294- if gitRef , gitErr := gitutil .ParseGitRef (src ); gitRef != nil && gitErr == nil {
2295- return true
2309+ gitRef , gitErr := gitutil .ParseGitRef (src )
2310+ var guoe * gitutil.GitURLOptsError
2311+ if errors .As (gitErr , & guoe ) {
2312+ // this is a git source, and it has invalid URL opts
2313+ return true , gitErr
2314+ }
2315+ if gitRef != nil && gitErr == nil {
2316+ return true , nil
22962317 }
2297- return false
2318+ return false , nil
22982319}
22992320
23002321func isEnabledForStage (stage string , value string ) bool {
0 commit comments