-
Notifications
You must be signed in to change notification settings - Fork 39
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
Support static files #45
Changes from all commits
ecb9acc
a07d76c
391d98b
6b30843
27dad44
7f52827
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ package run // import "gnorm.org/gnorm/run" | |
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"os/exec" | ||
|
@@ -47,7 +49,7 @@ func Generate(env environ.Values, cfg *Config) error { | |
return err | ||
} | ||
} | ||
return nil | ||
return copyStaticFiles(env, cfg.StaticDir, cfg.OutputDir) | ||
} | ||
|
||
func generateSchemas(env environ.Values, cfg *Config, db *data.DBData) error { | ||
|
@@ -162,3 +164,65 @@ func doPostRun(env environ.Values, file string, postrun []string) error { | |
} | ||
return nil | ||
} | ||
|
||
// copyStaticFiles copies files recursively from src directory to dest directory | ||
// while preserving the directory structure | ||
func copyStaticFiles(env environ.Values, src string, dest string) error { | ||
if src == "" || dest == "" { | ||
return nil | ||
} | ||
stat, err := os.Stat(src) | ||
if err != nil { | ||
return err | ||
} | ||
if !stat.IsDir() { | ||
return fmt.Errorf("Outputdir specifies a directory path that already exists as file %s", dest) | ||
} | ||
var dstat os.FileInfo | ||
dstat, err = os.Stat(dest) | ||
if err != nil { | ||
if os.IsNotExist(err) { | ||
err = os.MkdirAll(dest, stat.Mode()) | ||
if err != nil { | ||
return err | ||
} | ||
dstat = stat | ||
} else { | ||
return err | ||
} | ||
} | ||
if !dstat.IsDir() { | ||
return fmt.Errorf("%s is not a directory", dest) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you make this "Outputdir specifies a directory path that already exists as file %q" . or something like that? it'll make the error more clear to the user. |
||
} | ||
return filepath.Walk(src, func(path string, info os.FileInfo, err error) error { | ||
if err != nil { | ||
return err | ||
} | ||
if info.IsDir() { | ||
return nil | ||
} | ||
base := filepath.Dir(path) | ||
rel, err := filepath.Rel(src, base) | ||
if err != nil { | ||
return err | ||
} | ||
o := filepath.Join(dest, rel) | ||
err = os.MkdirAll(o, stat.Mode()) | ||
if err != nil { | ||
return err | ||
} | ||
f, err := os.Open(path) | ||
if err != nil { | ||
return err | ||
} | ||
defer f.Close() | ||
|
||
t, err := os.OpenFile(filepath.Join(o, filepath.Base(path)), os.O_RDWR|os.O_TRUNC|os.O_CREATE, info.Mode()) | ||
if err != nil { | ||
return err | ||
} | ||
defer t.Close() | ||
_, err = io.Copy(t, f) | ||
return err | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,9 @@ import ( | |
"io/ioutil" | ||
"log" | ||
"os" | ||
"path/filepath" | ||
"reflect" | ||
"sort" | ||
"testing" | ||
"text/template" | ||
|
||
|
@@ -41,3 +44,48 @@ func TestAtomicGenerate(t *testing.T) { | |
t.Fatalf("Expected file to be unchanged, but was different. Expected: %q, got: %q", original, b) | ||
} | ||
} | ||
|
||
func TestCopyStaticFiles(t *testing.T) { | ||
originPaths := []string{ | ||
"base/base.md", | ||
"base/level_one/level_one.md", | ||
"base/level_two/level_two.md", | ||
} | ||
source := "testdata" | ||
dest := "static_asset" | ||
|
||
err := copyStaticFiles(environ.Values{}, source, dest) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer func() { | ||
err := os.RemoveAll(dest) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
}() | ||
|
||
// make sure the structure is preserved | ||
var newPaths []string | ||
filepath.Walk(dest, func(path string, info os.FileInfo, err error) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since you have a well-known list of files you're looking for, you can probably use ioutil.ReadDir and the code will be easier to follow. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are checking the order of files in nested directories. ReadDir reads the content of one directories, I think walk here is a better fit rather than calling ReadDil a couple of times which we will also be walking the directory tree. |
||
if err != nil { | ||
return err | ||
} | ||
if info.IsDir() { | ||
return nil | ||
} | ||
r, err := filepath.Rel(dest, path) | ||
if err != nil { | ||
return err | ||
} | ||
newPaths = append(newPaths, r) | ||
return nil | ||
}) | ||
|
||
sort.Strings(originPaths) | ||
sort.Strings(newPaths) | ||
|
||
if !reflect.DeepEqual(originPaths, newPaths) { | ||
t.Errorf("expected %v to equal %v", newPaths, originPaths) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mention this defaults to "."