@@ -1464,7 +1464,15 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
14641464 if len (cfg .params .SourcePaths ) != 1 {
14651465 return errors .New ("checksum can't be specified for multiple sources" )
14661466 }
1467- if ! isHTTPSource (cfg .params .SourcePaths [0 ]) && ! isGitSource (cfg .params .SourcePaths [0 ]) {
1467+ isHTTPSourceV , err := isHTTPSource (cfg .params .SourcePaths [0 ])
1468+ if err != nil {
1469+ return err
1470+ }
1471+ isGitSourceV , err := isGitSource (cfg .params .SourcePaths [0 ])
1472+ if err != nil {
1473+ return err
1474+ }
1475+ if ! isHTTPSourceV && ! isGitSourceV {
14681476 return errors .New ("checksum requires HTTP(S) or Git sources" )
14691477 }
14701478 }
@@ -1529,85 +1537,91 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
15291537 } else {
15301538 a = a .Copy (st , "/" , dest , opts ... )
15311539 }
1532- } else if isHTTPSource (src ) {
1533- if ! cfg .isAddCommand {
1534- return errors .New ("source can't be a URL for COPY" )
1540+ } else {
1541+ isHTTPSourceV , err := isHTTPSource (src )
1542+ if err != nil {
1543+ return err
15351544 }
1545+ if isHTTPSourceV {
1546+ if ! cfg .isAddCommand {
1547+ return errors .New ("source can't be a URL for COPY" )
1548+ }
15361549
1537- // Resources from remote URLs are not decompressed.
1538- // https://docs.docker.com/engine/reference/builder/#add
1539- //
1540- // Note: mixing up remote archives and local archives in a single ADD instruction
1541- // would result in undefined behavior: https://github.com/moby/buildkit/pull/387#discussion_r189494717
1542- u , err := url .Parse (src )
1543- f := "__unnamed__"
1544- if err == nil {
1545- if base := path .Base (u .Path ); base != "." && base != "/" {
1546- f = base
1550+ // Resources from remote URLs are not decompressed.
1551+ // https://docs.docker.com/engine/reference/builder/#add
1552+ //
1553+ // Note: mixing up remote archives and local archives in a single ADD instruction
1554+ // would result in undefined behavior: https://github.com/moby/buildkit/pull/387#discussion_r189494717
1555+ u , err := url .Parse (src )
1556+ f := "__unnamed__"
1557+ if err == nil {
1558+ if base := path .Base (u .Path ); base != "." && base != "/" {
1559+ f = base
1560+ }
15471561 }
1548- }
15491562
1550- var checksum digest.Digest
1551- if cfg .checksum != "" {
1552- checksum , err = digest .Parse (cfg .checksum )
1553- if err != nil {
1554- return err
1563+ var checksum digest.Digest
1564+ if cfg .checksum != "" {
1565+ checksum , err = digest .Parse (cfg .checksum )
1566+ if err != nil {
1567+ return err
1568+ }
15551569 }
1556- }
15571570
1558- st := llb .HTTP (src , llb .Filename (f ), llb .WithCustomName (pgName ), llb .Checksum (checksum ), dfCmd (cfg .params ))
1571+ st := llb .HTTP (src , llb .Filename (f ), llb .WithCustomName (pgName ), llb .Checksum (checksum ), dfCmd (cfg .params ))
15591572
1560- opts := append ([]llb.CopyOption {& llb.CopyInfo {
1561- Mode : chopt ,
1562- CreateDestPath : true ,
1563- }}, copyOpt ... )
1573+ opts := append ([]llb.CopyOption {& llb.CopyInfo {
1574+ Mode : chopt ,
1575+ CreateDestPath : true ,
1576+ }}, copyOpt ... )
15641577
1565- if a == nil {
1566- a = llb .Copy (st , f , dest , opts ... )
1567- } else {
1568- a = a .Copy (st , f , dest , opts ... )
1569- }
1570- } else {
1571- validateCopySourcePath (src , & cfg )
1572- var patterns []string
1573- if cfg .parents {
1574- // detect optional pivot point
1575- parent , pattern , ok := strings .Cut (src , "/./" )
1576- if ! ok {
1577- pattern = src
1578- src = "/"
1578+ if a == nil {
1579+ a = llb .Copy (st , f , dest , opts ... )
15791580 } else {
1580- src = parent
1581+ a = a .Copy (st , f , dest , opts ... )
1582+ }
1583+ } else {
1584+ validateCopySourcePath (src , & cfg )
1585+ var patterns []string
1586+ if cfg .parents {
1587+ // detect optional pivot point
1588+ parent , pattern , ok := strings .Cut (src , "/./" )
1589+ if ! ok {
1590+ pattern = src
1591+ src = "/"
1592+ } else {
1593+ src = parent
1594+ }
1595+
1596+ pattern , err = system .NormalizePath ("/" , pattern , d .platform .OS , false )
1597+ if err != nil {
1598+ return errors .Wrap (err , "removing drive letter" )
1599+ }
1600+
1601+ patterns = []string {strings .TrimPrefix (pattern , "/" )}
15811602 }
15821603
1583- pattern , err = system .NormalizePath ("/" , pattern , d .platform .OS , false )
1604+ src , err = system .NormalizePath ("/" , src , d .platform .OS , false )
15841605 if err != nil {
15851606 return errors .Wrap (err , "removing drive letter" )
15861607 }
15871608
1588- patterns = []string {strings .TrimPrefix (pattern , "/" )}
1589- }
1590-
1591- src , err = system .NormalizePath ("/" , src , d .platform .OS , false )
1592- if err != nil {
1593- return errors .Wrap (err , "removing drive letter" )
1594- }
1595-
1596- opts := append ([]llb.CopyOption {& llb.CopyInfo {
1597- Mode : chopt ,
1598- FollowSymlinks : true ,
1599- CopyDirContentsOnly : true ,
1600- IncludePatterns : patterns ,
1601- AttemptUnpack : cfg .isAddCommand ,
1602- CreateDestPath : true ,
1603- AllowWildcard : true ,
1604- AllowEmptyWildcard : true ,
1605- }}, copyOpt ... )
1606-
1607- if a == nil {
1608- a = llb .Copy (cfg .source , src , dest , opts ... )
1609- } else {
1610- a = a .Copy (cfg .source , src , dest , opts ... )
1609+ opts := append ([]llb.CopyOption {& llb.CopyInfo {
1610+ Mode : chopt ,
1611+ FollowSymlinks : true ,
1612+ CopyDirContentsOnly : true ,
1613+ IncludePatterns : patterns ,
1614+ AttemptUnpack : cfg .isAddCommand ,
1615+ CreateDestPath : true ,
1616+ AllowWildcard : true ,
1617+ AllowEmptyWildcard : true ,
1618+ }}, copyOpt ... )
1619+
1620+ if a == nil {
1621+ a = llb .Copy (cfg .source , src , dest , opts ... )
1622+ } else {
1623+ a = a .Copy (cfg .source , src , dest , opts ... )
1624+ }
16111625 }
16121626 }
16131627 }
@@ -2269,19 +2283,26 @@ func commonImageNames() []string {
22692283 return out
22702284}
22712285
2272- func isHTTPSource (src string ) bool {
2286+ func isHTTPSource (src string ) ( bool , error ) {
22732287 if ! strings .HasPrefix (src , "http://" ) && ! strings .HasPrefix (src , "https://" ) {
2274- return false
2288+ return false , nil
22752289 }
2276- return ! isGitSource (src )
2290+ b , err := isGitSource (src )
2291+ return ! b , err
22772292}
22782293
2279- func isGitSource (src string ) bool {
2294+ func isGitSource (src string ) ( bool , error ) {
22802295 // https://github.com/ORG/REPO.git is a git source, not an http source
2281- if gitRef , gitErr := gitutil .ParseGitRef (src ); gitRef != nil && gitErr == nil {
2282- return true
2296+ gitRef , gitErr := gitutil .ParseGitRef (src )
2297+ var guoe * gitutil.GitURLOptsError
2298+ if errors .As (gitErr , & guoe ) {
2299+ // this is a git source, and it has invalid URL opts
2300+ return true , gitErr
2301+ }
2302+ if gitRef != nil && gitErr == nil {
2303+ return true , nil
22832304 }
2284- return false
2305+ return false , nil
22852306}
22862307
22872308func isEnabledForStage (stage string , value string ) bool {
0 commit comments