Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds .tsuruignore file support #25

Merged
merged 8 commits into from
Feb 13, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 137 additions & 11 deletions tsuru/client/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package client

import (
"archive/tar"
"bufio"
"bytes"
"compress/gzip"
"encoding/json"
Expand All @@ -18,6 +19,7 @@ import (
"net/url"
"os"
"path"
"path/filepath"
"sort"
"strings"
"sync"
Expand Down Expand Up @@ -231,7 +233,16 @@ func (c *AppDeploy) Run(context *cmd.Context, client *cmd.Client) error {
if err != nil {
return err
}
err = targz(context, file, context.Args...)
var ignore []string
ignorePatterns, _ := readTsuruIgnore()
for _, pattern := range ignorePatterns {
ignPats, errProc := processTsuruIgnore(pattern, context.Args...)
if errProc != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return errProc

}
ignore = append(ignore, ignPats...)
}
err = targz(context, file, ignore, context.Args...)
if err != nil {
return err
}
Expand Down Expand Up @@ -278,10 +289,75 @@ func (c *AppDeploy) Run(context *cmd.Context, client *cmd.Client) error {
return cmd.ErrAbortCommand
}

func targz(ctx *cmd.Context, destination io.Writer, filepaths ...string) error {
func processTsuruIgnore(pattern string, dirPath ...string) ([]string, error) {
var paths []string
old, err := os.Getwd()
if err != nil {
return nil, err
}
defer os.Chdir(old)
for _, dir := range dirPath {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to rename this vars to for _, dirPath := range dirPaths as dir is also used inside the for body.

err = os.Chdir(dir)
if err != nil {
return nil, err
}
wd, err := os.Getwd()
if err != nil {
return nil, err
}
paths, err = filepath.Glob(pattern)
if err != nil {
return nil, err
}
for i := range paths {
if dir == "." {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this if necessary? Couldn't this loop always do paths[i] = filepath.Join(dir, paths[i])?

Copy link
Contributor Author

@arxdsilva arxdsilva Feb 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is, we got this as a bug while uploading static into lab so without It, the path would be only paths[i] and It would never match glob on the root dir

paths[i] = filepath.Join(wd, paths[i])
continue
}
paths[i] = filepath.Join(dir, paths[i])
}
dir, err := os.Open(dir)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to call dir.Close() after the Readdir call.

if err != nil {
return nil, err
}
fis, err := dir.Readdir(0)
if err != nil {
return nil, err
}
for _, f := range fis {
if f.IsDir() {
glob, err := processTsuruIgnore(pattern, filepath.Join(wd, f.Name()))
if err != nil {
return nil, err
}
paths = append(paths, glob...)
}
}
}
return paths, nil
}

func readTsuruIgnore() ([]string, error) {
file, err := os.Open(".tsuruignore")
if err != nil {
return nil, err
}
defer file.Close()
patterns := []string{}
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ScanLines is the default splitter, no need for this line.

for scanner.Scan() {
pattern := scanner.Text()
patterns = append(patterns, pattern)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply patterns = append(patterns, scanner.Text())

}
return patterns, nil
}

func targz(ctx *cmd.Context, destination io.Writer, ignoreList []string, filepaths ...string) error {
var buf bytes.Buffer
tarWriter := tar.NewWriter(&buf)
for _, path := range filepaths {
var cont bool
if path == ".." {
fmt.Fprintf(ctx.Stderr, "Warning: skipping %q", path)
continue
Expand All @@ -290,13 +366,36 @@ func targz(ctx *cmd.Context, destination io.Writer, filepaths ...string) error {
if err != nil {
return err
}
wd, errWd := os.Getwd()
if errWd != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean't return errWd. I think you can also rename errWd to err

}
fiName := filepath.Join(wd, fi.Name())
if fi.IsDir() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think lines 375-383 can be moved to before the if statement (so you can remove the ones in 389-397).

for _, p := range ignoreList {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more efficient for ignoreList to be a var ignoreSet map[string]struct{}. This way you could ignore patterns in O(1) by doing:

if _, inSet := ignoreSet[fiName]; !inSet {
    continue
}

if fiName == p {
cont = true
break
}
}
if cont {
continue
}
if len(filepaths) == 1 && path != "." {
return singleDir(ctx, destination, path)
return singleDir(ctx, destination, path, ignoreList)
}
err = addDir(tarWriter, path)
err = addDir(tarWriter, path, ignoreList)
} else {
err = addFile(tarWriter, path)
for _, p := range ignoreList {
if (fiName == p) || (fi.Name() == ".tsuruignore") {
cont = true
break
}
}
if cont {
continue
}
err = addFile(tarWriter, path, ignoreList)
}
if err != nil {
return err
Expand All @@ -312,7 +411,7 @@ func targz(ctx *cmd.Context, destination io.Writer, filepaths ...string) error {
return err
}

func singleDir(ctx *cmd.Context, destination io.Writer, path string) error {
func singleDir(ctx *cmd.Context, destination io.Writer, path string, ignoreList []string) error {
old, err := os.Getwd()
if err != nil {
return err
Expand All @@ -322,10 +421,10 @@ func singleDir(ctx *cmd.Context, destination io.Writer, path string) error {
if err != nil {
return err
}
return targz(ctx, destination, ".")
return targz(ctx, destination, ignoreList, ".")
}

func addDir(writer *tar.Writer, dirpath string) error {
func addDir(writer *tar.Writer, dirpath string, ignoreList []string) error {
dir, err := os.Open(dirpath)
if err != nil {
return err
Expand All @@ -348,11 +447,38 @@ func addDir(writer *tar.Writer, dirpath string) error {
if err != nil {
return err
}
wd, errWd := os.Getwd()
if errWd != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as before

}
for _, fi := range fis {
fiName := filepath.Join(wd, fi.Name())
if dirpath != "." {
fiName = filepath.Join(wd, dirpath, fi.Name())
}
var cont bool
if fi.IsDir() {
err = addDir(writer, path.Join(dirpath, fi.Name()))
for _, p := range ignoreList {
if fiName == p {
cont = true
break
}
}
if cont {
continue
}
err = addDir(writer, path.Join(dirpath, fi.Name()), ignoreList)
} else {
err = addFile(writer, path.Join(dirpath, fi.Name()))
for _, p := range ignoreList {
if (fiName == p) || (fi.Name() == ".tsuruignore") {
cont = true
break
}
}
if cont {
continue
}
err = addFile(writer, path.Join(dirpath, fi.Name()), ignoreList)
}
if err != nil {
return err
Expand All @@ -361,7 +487,7 @@ func addDir(writer *tar.Writer, dirpath string) error {
return nil
}

func addFile(writer *tar.Writer, filepath string) error {
func addFile(writer *tar.Writer, filepath string, ignoreList []string) error {
f, err := os.Open(filepath)
if err != nil {
return err
Expand Down
Loading