Skip to content
This repository has been archived by the owner on Jan 28, 2022. It is now read-only.

Commit

Permalink
Add support for pushing JAR/WAR/ZIP files
Browse files Browse the repository at this point in the history
  • Loading branch information
sclevine committed May 21, 2017
1 parent 80afb7d commit bf351d8
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 24 deletions.
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ Notably, CF Local:

```
USAGE:
cf local stage <name> [ (-b <name> | -b <URL>) (-s <app> | -f <app>) ]
cf local stage <name> [ (-b <name> | -b <URL>) (-p <dir> | -p <zip>) ]
[ (-s <app> | -f <app>) ]
cf local run <name> [ (-i <ip>) (-p <port>) (-d <dir>) ]
[ (-s <app>) (-f <app>) ]
cf local export <name> [ (-r <ref>) ]
Expand All @@ -44,6 +45,10 @@ STAGE OPTIONS:
Default: (uses detection)
-b <url> Use a buildpack specified by URL (git or zip-over-HTTP).
Default: (uses detection)
-p <dir> Use the specified directory as the app directory.
Default: current working directory
-p <zip> Use the specified zip file contents as the app directory.
Default: current working directory
-s <app> Use the service bindings from the specified remote CF app
instead of the service bindings in local.yml.
Default: (uses local.yml)
Expand Down Expand Up @@ -124,20 +129,20 @@ applications:
## Install

```bash
$ ./cflocal-v0.9.0-macos
Plugin successfully installed. Current version: 0.9.0
$ ./cflocal-v0.11.0-macos
Plugin successfully installed. Current version: 0.11.0
```
***Or***
```bash
$ cf install-plugin cflocal-0.9.0-macos
$ cf install-plugin cflocal-0.11.0-macos

**Attention: Plugins are binaries written by potentially untrusted authors. Install and use plugins at your own risk.**

Do you want to install the plugin cflocal-0.9.0-macos?> y
Do you want to install the plugin cflocal-0.11.0-macos?> y

Installing plugin cflocal-0.9.0-macos...
Installing plugin cflocal-0.11.0-macos...
OK
Plugin cflocal v0.9.0 successfully installed.
Plugin cflocal v0.11.0 successfully installed.
```
***Or***
```bash
Expand All @@ -148,9 +153,9 @@ $ cf install-plugin -r CF-Community cflocal
Do you want to install the plugin cflocal?> y
Looking up 'cflocal' from repository 'CF-Community'
11354404 bytes downloaded...
Installing plugin cflocal-0.8.0-macos...
Installing plugin cflocal-0.11.0-macos...
OK
Plugin cflocal v0.8.0 successfully installed.
Plugin cflocal v0.11.0 successfully installed.
```
Note: The version available in the 'CF-Community' plugin repo may not always be the latest available.

Expand All @@ -163,10 +168,6 @@ OK
Plugin cflocal successfully uninstalled.
```

## Known Issues

* JAR files currently must be unzipped to push

## Security Notes

* Service forwarding tunnels are not active during staging
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.10.0
0.11.0
5 changes: 3 additions & 2 deletions cf/cmd/stage.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Stage struct {
}

type stageOptions struct {
name, buildpack string
name, buildpack, app string
serviceApp, forwardApp string
}

Expand All @@ -42,7 +42,7 @@ func (s *Stage) Run(args []string) error {
if err != nil {
return err
}
appTar, err := s.FS.TarApp(".")
appTar, err := s.FS.TarApp(options.app)
if err != nil {
return err
}
Expand Down Expand Up @@ -91,6 +91,7 @@ func (*Stage) options(args []string) (*stageOptions, error) {

return options, parseOptions(args, func(name string, set *flag.FlagSet) {
options.name = name
set.StringVar(&options.app, "p", ".", "")
set.StringVar(&options.buildpack, "b", "", "")
set.StringVar(&options.serviceApp, "s", "", "")
set.StringVar(&options.forwardApp, "f", "", "")
Expand Down
5 changes: 3 additions & 2 deletions cf/cmd/stage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ var _ = Describe("Stage", func() {
}

mockConfig.EXPECT().Load().Return(localYML, nil)
mockFS.EXPECT().TarApp(".").Return(appTar, nil)
mockFS.EXPECT().TarApp("some-app-dir").Return(appTar, nil)
mockApp.EXPECT().Services("some-service-app").Return(services, nil)
mockApp.EXPECT().Forward("some-forward-app", services).Return(forwardedServices, forwardConfig, nil)
mockFS.EXPECT().OpenFile("./.some-app.cache").Return(cache, int64(100), nil)
Expand All @@ -109,7 +109,7 @@ var _ = Describe("Stage", func() {
mockFS.EXPECT().WriteFile("./some-app.droplet").Return(dropletFile, nil),
)

Expect(cmd.Run([]string{"stage", "some-app", "-b", "some-buildpack", "-s", "some-service-app", "-f", "some-forward-app"})).To(Succeed())
Expect(cmd.Run([]string{"stage", "some-app", "-b", "some-buildpack", "-p", "some-app-dir", "-s", "some-service-app", "-f", "some-forward-app"})).To(Succeed())
Expect(appTar.Result()).To(BeEmpty())
Expect(droplet.Result()).To(BeEmpty())
Expect(dropletFile.Result()).To(Equal("some-droplet"))
Expand All @@ -119,6 +119,7 @@ var _ = Describe("Stage", func() {
})

// TODO: test not providing a buildpack
// TODO: test not providing an app dir
// TODO: test with empty cache
})
})
55 changes: 50 additions & 5 deletions fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fs

import (
"io"
"io/ioutil"
"os"
"path/filepath"
"regexp"
Expand All @@ -12,23 +13,67 @@ import (

type FS struct{}

func (f *FS) TarApp(path string) (io.ReadCloser, error) {
absPath, err := filepath.Abs(path)
func (f *FS) TarApp(path string) (app io.ReadCloser, err error) {
var absPath, appDir string

absPath, err = filepath.Abs(path)
if err != nil {
return nil, err
}
files, err := appFiles(absPath)

zipper := appfiles.ApplicationZipper{}
if zipper.IsZipFile(absPath) {
appDir, err = ioutil.TempDir("", "cflocal-zip")
if err != nil {
return nil, err
}
defer func() {
if err != nil {
os.RemoveAll(appDir)
return
}
app = &closeWrapper{
ReadCloser: app,
After: func() error {
return os.RemoveAll(appDir)
},
}
}()
if err := zipper.Unzip(absPath, appDir); err != nil {
return nil, err
}
} else {
appDir, err = filepath.EvalSymlinks(absPath)
if err != nil {
return nil, err
}
}
files, err := appFiles(appDir)
if err != nil {
return nil, err
}
return archive.TarWithOptions(absPath, &archive.TarOptions{
return archive.TarWithOptions(appDir, &archive.TarOptions{
IncludeFiles: files,
})
}

type closeWrapper struct {
io.ReadCloser
After func() error
}

func (c *closeWrapper) Close() (err error) {
defer func() {
if afterErr := c.After(); err == nil {
err = afterErr
}
}()
return c.ReadCloser.Close()
}

func appFiles(path string) ([]string, error) {
var files []string
err := appfiles.ApplicationFiles{}.WalkAppFiles(path, func(relpath string, fullpath string) error {
err := appfiles.ApplicationFiles{}.WalkAppFiles(path, func(relpath, _ string) error {
filename := filepath.Base(relpath)
switch {
case
Expand Down
8 changes: 7 additions & 1 deletion plugin/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package plugin
const Usage = ShortUsage + "\n" + LongUsage

const ShortUsage = `
cf local stage <name> [ (-b <name> | -b <URL>) (-s <app> | -f <app>) ]
cf local stage <name> [ (-b <name> | -b <URL>) (-p <dir> | -p <zip>) ]
[ (-s <app> | -f <app>) ]
cf local run <name> [ (-i <ip>) (-p <port>) (-d <dir>) ]
[ (-s <app>) (-f <app>) ]
cf local export <name> [ (-r <ref>) ]
Expand All @@ -23,6 +24,11 @@ STAGE OPTIONS:
Default: (uses detection)
-b <url> Use a buildpack specified by URL (git or zip-over-HTTP).
Default: (uses detection)
-p <dir> Use the specified directory as the app directory.
Default: current working directory
-p <zip> Use the specified ZIP file contents as the app directory.
Note that JAR and WAR files use ZIP file format.
Default: current working directory
-s <app> Use the service bindings from the specified remote CF app
instead of the service bindings in local.yml.
Default: (uses local.yml)
Expand Down

0 comments on commit bf351d8

Please sign in to comment.