Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 6268e99

Browse files
author
Matthieu Nottale
committed
split/merge: Fix loading from image/URL with an empty target.
Signed-off-by: Matthieu Nottale <matthieu.nottale@docker.com>
1 parent d6fcc93 commit 6268e99

4 files changed

Lines changed: 50 additions & 5 deletions

File tree

cmd/docker-app/merge.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/docker/app/internal"
1111
"github.com/docker/app/internal/packager"
12+
"github.com/docker/app/types"
1213
"github.com/docker/cli/cli"
1314
"github.com/docker/cli/cli/command"
1415
"github.com/pkg/errors"
@@ -50,7 +51,15 @@ func mergeCmd(dockerCli command.Cli) *cobra.Command {
5051
return err
5152
}
5253
defer extractedApp.Cleanup()
53-
inPlace := mergeOutputFile == ""
54+
inPlace := false
55+
if mergeOutputFile == "" {
56+
if extractedApp.Source == types.AppSourceURL || extractedApp.Source == types.AppSourceImage {
57+
mergeOutputFile = internal.DirNameFromAppName(extractedApp.Name)
58+
} else {
59+
inPlace = true
60+
mergeOutputFile = extractedApp.Path + ".tmp"
61+
}
62+
}
5463
if inPlace {
5564
extra, err := extraFiles(extractedApp.Path)
5665
if err != nil {
@@ -59,7 +68,6 @@ func mergeCmd(dockerCli command.Cli) *cobra.Command {
5968
if len(extra) != 0 {
6069
return fmt.Errorf("refusing to overwrite %s: extra files would be deleted: %s", extractedApp.Path, strings.Join(extra, ","))
6170
}
62-
mergeOutputFile = extractedApp.Path + ".tmp"
6371
}
6472
var target io.Writer
6573
if mergeOutputFile == "-" {

cmd/docker-app/split.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package main
33
import (
44
"os"
55

6+
"github.com/docker/app/internal"
67
"github.com/docker/app/internal/packager"
8+
"github.com/docker/app/types"
79
"github.com/docker/cli/cli"
810
"github.com/pkg/errors"
911
"github.com/spf13/cobra"
@@ -22,9 +24,14 @@ func splitCmd() *cobra.Command {
2224
return err
2325
}
2426
defer extractedApp.Cleanup()
25-
inPlace := splitOutputDir == ""
26-
if inPlace {
27-
splitOutputDir = extractedApp.Path + ".tmp"
27+
inPlace := false
28+
if splitOutputDir == "" {
29+
if extractedApp.Source == types.AppSourceURL || extractedApp.Source == types.AppSourceImage {
30+
splitOutputDir = internal.DirNameFromAppName(extractedApp.Name)
31+
} else {
32+
inPlace = true
33+
splitOutputDir = extractedApp.Path + ".tmp"
34+
}
2835
}
2936
if err := packager.Split(extractedApp, splitOutputDir); err != nil {
3037
return err

internal/packager/extract.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,18 @@ func Extract(name string, ops ...func(*types.App) error) (*types.App, error) {
113113
// URL or docker image
114114
u, err := url.Parse(name)
115115
if err == nil && (u.Scheme == "http" || u.Scheme == "https") {
116+
ops = append(ops, types.WithSource(types.AppSourceURL))
116117
return loader.LoadFromURL(name, ops...)
117118
}
118119
// look for a docker image
120+
ops = append(ops, types.WithSource(types.AppSourceImage))
119121
return extractImage(name, ops...)
120122
}
121123
if s.IsDir() {
122124
// directory: already decompressed
123125
appOpts := append(ops,
124126
types.WithPath(appname),
127+
types.WithSource(types.AppSourceSplit),
125128
)
126129
return loader.LoadFromDirectory(appname, appOpts...)
127130
}
@@ -133,7 +136,9 @@ func Extract(name string, ops ...func(*types.App) error) (*types.App, error) {
133136
return nil, err
134137
}
135138
defer f.Close()
139+
ops = append(ops, types.WithSource(types.AppSourceMerged))
136140
return loader.LoadFromSingleFile(appname, f, ops...)
137141
}
142+
app.Source = types.AppSourceArchive
138143
return app, nil
139144
}

types/types.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,28 @@ import (
1515
// SingleFileSeparator is the separator used in single-file app
1616
const SingleFileSeparator = "\n---\n"
1717

18+
// AppSourceKind represents what format the app was in when read
19+
type AppSourceKind int
20+
21+
const (
22+
// AppSourceSplit represents an Application in multiple file format
23+
AppSourceSplit AppSourceKind = iota
24+
// AppSourceMerged represents an Application in single file format
25+
AppSourceMerged
26+
// AppSourceImage represents an Application pulled from an image
27+
AppSourceImage
28+
// AppSourceURL represents an Application fetched from an URL
29+
AppSourceURL
30+
// AppSourceArchive represents an Application in an archive format
31+
AppSourceArchive
32+
)
33+
1834
// App represents an app
1935
type App struct {
2036
Name string
2137
Path string
2238
Cleanup func()
39+
Source AppSourceKind
2340

2441
composesContent [][]byte
2542
settingsContent [][]byte
@@ -125,6 +142,14 @@ func WithCleanup(f func()) func(*App) error {
125142
}
126143
}
127144

145+
// WithSource sets the source of the app
146+
func WithSource(source AppSourceKind) func(*App) error {
147+
return func(app *App) error {
148+
app.Source = source
149+
return nil
150+
}
151+
}
152+
128153
// WithSettingsFiles adds the specified settings files to the app
129154
func WithSettingsFiles(files ...string) func(*App) error {
130155
return settingsLoader(func() ([][]byte, error) { return readFiles(files...) })

0 commit comments

Comments
 (0)