Skip to content

Commit

Permalink
Merge pull request #8 from rabadin/add-perm-feat
Browse files Browse the repository at this point in the history
feat: add option to set permissions on the downloaded files
  • Loading branch information
rabadin authored Jul 26, 2023
2 parents 747e21e + 2a1fa14 commit bd4ba7e
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 6 deletions.
5 changes: 4 additions & 1 deletion cmd/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func init() {
downloadCmd.Flags().String("dir", ".", "Target directory where to store the files")
downloadCmd.Flags().StringArray("tag", []string{}, "Only download the resources with the given tag")
downloadCmd.Flags().StringArray("notag", []string{}, "Only download the resources without the given tag")
downloadCmd.Flags().String("perm", "", "Optional permissions for the downloaded files (e.g. '644')")
}

var downloadCmd = &cobra.Command{
Expand All @@ -33,6 +34,8 @@ func runFetch(cmd *cobra.Command, args []string) {
FatalIfNotNil(err)
notags, err := cmd.Flags().GetStringArray("notag")
FatalIfNotNil(err)
err = lock.Download(dir, tags, notags)
perm, err := cmd.Flags().GetString("perm")
FatalIfNotNil(err)
err = lock.Download(dir, tags, notags, perm)
FatalIfNotNil(err)
}
23 changes: 21 additions & 2 deletions internal/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"context"
"fmt"
"os"
"strconv"

toml "github.com/pelletier/go-toml/v2"
)
Expand Down Expand Up @@ -71,12 +72,30 @@ func (l *Lock) DeleteResource(path string) {
l.conf.Resource = newStatements
}

const NoFileMode = os.FileMode(0)

// strToFileMode converts a string to a os.FileMode.
func strToFileMode(perm string) (os.FileMode, error) {
if perm == "" {
return NoFileMode, nil
}
parsed, err := strconv.ParseUint(perm, 8, 32)
if err != nil {
return NoFileMode, err
}
return os.FileMode(parsed), nil
}

// Download gets all the resources in this lock file and moves them to
// the destination directory.
func (l *Lock) Download(dir string, tags []string, notags []string) error {
func (l *Lock) Download(dir string, tags []string, notags []string, perm string) error {
if stat, err := os.Stat(dir); err != nil || !stat.IsDir() {
return fmt.Errorf("'%s' is not a directory", dir)
}
mode, err := strToFileMode(perm)
if err != nil {
return fmt.Errorf("'%s' is not a valid permission definition", perm)
}

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
Expand Down Expand Up @@ -133,7 +152,7 @@ func (l *Lock) Download(dir string, tags []string, notags []string) error {
for _, r := range filteredResources {
resource := r
go func() {
err := resource.Download(dir, ctx)
err := resource.Download(dir, mode, ctx)
errorCh <- err
}()
}
Expand Down
32 changes: 31 additions & 1 deletion internal/lock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,29 @@ func TestDuplicateResource(t *testing.T) {
assert.Contains(t, err.Error(), "already present")
}

func TestStrToFileMode(t *testing.T) {
cases := []struct {
Input string
Err bool
Expected string
}{
{"", false, NoFileMode.String()},
{"bogus", true, ""},
{"666", false, "-rw-rw-rw-"},
{"741", false, "-rwxr----x"},
}
for _, c := range cases {
t.Run(c.Input, func(t *testing.T) {
res, err := strToFileMode(c.Input)
if c.Err {
assert.NotNil(t, err)
} else {
assert.Equal(t, res.String(), c.Expected)
}
})
}
}

func TestDownload(t *testing.T) {
httpContent := []byte(`abcdef`)
handler := func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -86,10 +109,12 @@ func TestDownload(t *testing.T) {
[[Resource]]
Urls = ['http://localhost:%d/test.html']
Integrity = 'sha256-vvV+x/U6bUC+tkCngKY5yDvCmsipgW8fxsXG3Nk8RyE='`, port))
perm := "467"
strPerm := "-r--rw-rwx"
lock, err := NewLock(path, false)
assert.Nil(t, err)
dir := tmpDir(t)
err = lock.Download(dir, []string{}, []string{})
err = lock.Download(dir, []string{}, []string{}, perm)
if err != nil {
t.Fatal(err)
}
Expand All @@ -100,4 +125,9 @@ func TestDownload(t *testing.T) {
t.Fatal(err)
}
assert.Equal(t, httpContent, content)
stats, err := os.Stat(resFile)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, stats.Mode().Perm().String(), strPerm)
}
8 changes: 6 additions & 2 deletions internal/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func GetUrltoTempFile(u string, ctx context.Context) (string, error) {
return getUrl(u, fileName, ctx)
}

func (l *Resource) Download(dir string, ctx context.Context) error {
func (l *Resource) Download(dir string, mode os.FileMode, ctx context.Context) error {
ok := false
algo, err := getAlgoFromIntegrity(l.Integrity)
if err != nil {
Expand All @@ -102,10 +102,14 @@ func (l *Resource) Download(dir string, ctx context.Context) error {
} else {
localName = path.Base(u)
}
err = os.Rename(lpath, filepath.Join(dir, localName))
resPath := filepath.Join(dir, localName)
err = os.Rename(lpath, resPath)
if err != nil {
return err
}
if mode != NoFileMode {
os.Chmod(resPath, mode.Perm())
}
ok = true
}
if !ok {
Expand Down

0 comments on commit bd4ba7e

Please sign in to comment.