diff --git a/Makefile b/Makefile index 37f6c6b..c5fc7bc 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ install: ## compile and install the executable go install ${LDFLAGS} ${PACKAGE}/cmd/gojekyll lint: ## lint the package - gometalinter ./... + gometalinter ./... --disable=gotype test: ## test the package go test ./... diff --git a/cmd/gojekyll/commands.go b/cmd/gojekyll/commands.go index 2785724..7228a8e 100644 --- a/cmd/gojekyll/commands.go +++ b/cmd/gojekyll/commands.go @@ -14,14 +14,14 @@ import ( "github.com/osteele/gojekyll/helpers" "github.com/osteele/gojekyll/pages" "github.com/osteele/gojekyll/server" - "github.com/osteele/gojekyll/sites" + "github.com/osteele/gojekyll/site" "github.com/osteele/liquid" ) // main sets this var commandStartTime = time.Now() -func buildCommand(site *sites.Site) error { +func buildCommand(site *site.Site) error { logger.path("Destination:", site.DestDir()) logger.label("Generating...", "") count, err := site.Build(buildOptions) @@ -33,12 +33,12 @@ func buildCommand(site *sites.Site) error { return nil } -func cleanCommand(site *sites.Site) error { +func cleanCommand(site *site.Site) error { logger.label("Cleaner:", "Removing %s...", site.DestDir()) return site.Clean(buildOptions) } -func benchmarkCommand(site *sites.Site) (err error) { +func benchmarkCommand(site *site.Site) (err error) { for i := 0; time.Since(commandStartTime) < 10*time.Second; i++ { // skip this the first time, since the caller has already // started the profile and loaded the site once. @@ -57,12 +57,12 @@ func benchmarkCommand(site *sites.Site) (err error) { return nil } -func serveCommand(site *sites.Site) error { +func serveCommand(site *site.Site) error { server := server.Server{Site: site} return server.Run(*open, func(label, value string) { logger.label(label, value) }) } -func routesCommand(site *sites.Site) error { +func routesCommand(site *site.Site) error { logger.label("Routes:", "") urls := []string{} for u, p := range site.Routes { @@ -78,7 +78,7 @@ func routesCommand(site *sites.Site) error { return nil } -func renderCommand(site *sites.Site) error { +func renderCommand(site *site.Site) error { p, err := pageFromPathOrRoute(site, *renderPath) if err != nil { return err @@ -91,7 +91,7 @@ func renderCommand(site *sites.Site) error { // If path starts with /, it's a URL path. Else it's a file path relative // to the site source directory. -func pageFromPathOrRoute(s *sites.Site, path string) (pages.Document, error) { +func pageFromPathOrRoute(s *site.Site, path string) (pages.Document, error) { if path == "" { path = "/" } @@ -111,7 +111,7 @@ func pageFromPathOrRoute(s *sites.Site, path string) (pages.Document, error) { } } -func varsCommand(site *sites.Site) (err error) { +func varsCommand(site *site.Site) (err error) { var data interface{} switch { case strings.HasPrefix(*variablePath, "site"): diff --git a/cmd/gojekyll/main.go b/cmd/gojekyll/main.go index bd2fe46..073c456 100644 --- a/cmd/gojekyll/main.go +++ b/cmd/gojekyll/main.go @@ -6,13 +6,13 @@ import ( "runtime/pprof" "github.com/osteele/gojekyll/config" - "github.com/osteele/gojekyll/sites" + "github.com/osteele/gojekyll/site" "gopkg.in/alecthomas/kingpin.v2" ) // Command-line options var ( - buildOptions sites.BuildOptions + buildOptions site.BuildOptions configFlags = config.Flags{} profile = false quiet = false @@ -102,8 +102,8 @@ func run(cmd string) error { // nolint: gocyclo } // Load the site, and print the common banner settings. -func loadSite(source string, flags config.Flags) (*sites.Site, error) { - site, err := sites.NewSiteFromDirectory(source, flags) +func loadSite(source string, flags config.Flags) (*site.Site, error) { + site, err := site.FromDirectory(source, flags) if err != nil { return nil, err } diff --git a/collections/collection.go b/collection/collection.go similarity index 94% rename from collections/collection.go rename to collection/collection.go index e977714..135c8d8 100644 --- a/collections/collection.go +++ b/collection/collection.go @@ -1,4 +1,4 @@ -package collections +package collection import ( "path/filepath" @@ -24,8 +24,8 @@ type Site interface { OutputExt(pathname string) string } -// NewCollection creates a new Collection -func NewCollection(s Site, name string, metadata map[string]interface{}) *Collection { +// New creates a new Collection +func New(s Site, name string, metadata map[string]interface{}) *Collection { return &Collection{ Name: name, Metadata: metadata, diff --git a/collections/collection_test.go b/collection/collection_test.go similarity index 69% rename from collections/collection_test.go rename to collection/collection_test.go index 0c78636..147084f 100644 --- a/collections/collection_test.go +++ b/collection/collection_test.go @@ -1,4 +1,4 @@ -package collections +package collection import ( "testing" @@ -16,40 +16,40 @@ func (c siteMock) Site() interface{} { return c } func TestNewCollection(t *testing.T) { site := siteMock{config.Default()} - c1 := NewCollection(site, "c", map[string]interface{}{"output": true}) + c1 := New(site, "c", map[string]interface{}{"output": true}) require.Equal(t, true, c1.Output()) require.Equal(t, "_c/", c1.PathPrefix()) - c2 := NewCollection(site, "c", map[string]interface{}{}) + c2 := New(site, "c", map[string]interface{}{}) require.Equal(t, false, c2.Output()) } func TestPermalinkPattern(t *testing.T) { site := siteMock{config.Default()} - c1 := NewCollection(site, "c", map[string]interface{}{}) + c1 := New(site, "c", map[string]interface{}{}) require.Contains(t, c1.PermalinkPattern(), ":collection") - c2 := NewCollection(site, "c", map[string]interface{}{"permalink": "out"}) + c2 := New(site, "c", map[string]interface{}{"permalink": "out"}) require.Equal(t, "out", c2.PermalinkPattern()) - c3 := NewCollection(site, "posts", map[string]interface{}{}) + c3 := New(site, "posts", map[string]interface{}{}) require.Contains(t, c3.PermalinkPattern(), "/:year/:month/:day/:title") } func TestReadPosts(t *testing.T) { site := siteMock{config.FromString("source: testdata")} - c := NewCollection(site, "posts", map[string]interface{}{}) + c := New(site, "posts", map[string]interface{}{}) require.NoError(t, c.ReadPages()) require.Len(t, c.Pages(), 1) site = siteMock{config.FromString("source: testdata\nunpublished: true")} - c = NewCollection(site, "posts", map[string]interface{}{}) + c = New(site, "posts", map[string]interface{}{}) require.NoError(t, c.ReadPages()) require.Len(t, c.Pages(), 2) site = siteMock{config.FromString("source: testdata\nfuture: true")} - c = NewCollection(site, "posts", map[string]interface{}{}) + c = New(site, "posts", map[string]interface{}{}) require.NoError(t, c.ReadPages()) require.Len(t, c.Pages(), 2) } diff --git a/collections/read.go b/collection/read.go similarity index 99% rename from collections/read.go rename to collection/read.go index e589781..2e0177d 100644 --- a/collections/read.go +++ b/collection/read.go @@ -1,4 +1,4 @@ -package collections +package collection import ( "fmt" diff --git a/collections/sort.go b/collection/sort.go similarity index 95% rename from collections/sort.go rename to collection/sort.go index 5dd66f4..b13d3ae 100644 --- a/collections/sort.go +++ b/collection/sort.go @@ -1,4 +1,4 @@ -package collections +package collection import ( "github.com/osteele/gojekyll/pages" diff --git a/collections/strategies.go b/collection/strategies.go similarity index 96% rename from collections/strategies.go rename to collection/strategies.go index 21b6c71..142eb94 100644 --- a/collections/strategies.go +++ b/collection/strategies.go @@ -1,4 +1,4 @@ -package collections +package collection import ( "time" @@ -7,7 +7,7 @@ import ( ) // A collectionStrategy encapsulates behavior differences between the _post -// collection and other collections. +// collection and other collection. type collectionStrategy interface { addDate(filename string, fm map[string]interface{}) collectible(filename string) bool diff --git a/collections/testdata/_drafts/2017-07-01-draft.md b/collection/testdata/_drafts/2017-07-01-draft.md similarity index 100% rename from collections/testdata/_drafts/2017-07-01-draft.md rename to collection/testdata/_drafts/2017-07-01-draft.md diff --git a/collections/testdata/_posts/2017-06-10-birthday.md b/collection/testdata/_posts/2017-06-10-birthday.md similarity index 100% rename from collections/testdata/_posts/2017-06-10-birthday.md rename to collection/testdata/_posts/2017-06-10-birthday.md diff --git a/collections/testdata/_posts/2017-07-01-unpublished.md b/collection/testdata/_posts/2017-07-01-unpublished.md similarity index 100% rename from collections/testdata/_posts/2017-07-01-unpublished.md rename to collection/testdata/_posts/2017-07-01-unpublished.md diff --git a/collections/testdata/_posts/8017-01-01-future.md b/collection/testdata/_posts/8017-01-01-future.md similarity index 100% rename from collections/testdata/_posts/8017-01-01-future.md rename to collection/testdata/_posts/8017-01-01-future.md diff --git a/pages/drops.go b/pages/drops.go new file mode 100644 index 0000000..92270e6 --- /dev/null +++ b/pages/drops.go @@ -0,0 +1,93 @@ +package pages + +import ( + "path" + "path/filepath" + + "github.com/osteele/gojekyll/helpers" + "github.com/osteele/gojekyll/templates" +) + +// ToLiquid returns the attributes of the template page object. +// See https://jekyllrb.com/docs/variables/#page-variables +func (f *file) ToLiquid() interface{} { + var ( + relpath = "/" + filepath.ToSlash(f.relpath) + base = path.Base(relpath) + ext = path.Ext(relpath) + ) + + return templates.MergeVariableMaps(f.frontMatter, map[string]interface{}{ + "path": relpath, + "modified_time": f.fileModTime, + "name": base, + "basename": helpers.TrimExt(base), + "extname": ext, + }) +} + +// ToLiquid is in the liquid.Drop interface. +func (p *page) ToLiquid() interface{} { + var ( + relpath = p.relpath + ext = filepath.Ext(relpath) + root = helpers.TrimExt(p.relpath) + base = filepath.Base(root) + ) + + data := map[string]interface{}{ + "path": relpath, + "url": p.Permalink(), + // TODO output + + // not documented, but present in both collection and non-collection pages + "permalink": p.Permalink(), + + // TODO only in non-collection pages: + // TODO dir + // TODO name + // TODO next previous + + // TODO Documented as present in all pages, but de facto only defined for collection pages + "id": base, + "title": base, // TODO capitalize + // TODO excerpt category? categories tags + // TODO slug + "categories": p.Categories(), + "tags": p.Tags(), + + // TODO Only present in collection pages https://jekyllrb.com/docs/collections/#documents + "relative_path": p.Path(), + // TODO collection(name) + + // TODO undocumented; only present in collection pages: + "ext": ext, + } + for k, v := range p.frontMatter { + switch k { + // doc implies these aren't present, but they appear to be present in a collection page: + // case "layout", "published": + case "permalink": + // omit this, in order to use the value above + default: + data[k] = v + } + } + if p.content != nil { + data["content"] = string(*p.content) + // TODO excerpt + } + return data +} + +// MarshalYAML is part of the yaml.Marshaler interface +// The variables subcommand uses this. +func (f *file) MarshalYAML() (interface{}, error) { + return f.ToLiquid(), nil +} + +// MarshalYAML is part of the yaml.Marshaler interface +// The variables subcommand uses this. +func (p *page) MarshalYAML() (interface{}, error) { + return p.ToLiquid(), nil +} diff --git a/pages/file.go b/pages/file.go index 1ca0db8..39c33fa 100644 --- a/pages/file.go +++ b/pages/file.go @@ -3,8 +3,6 @@ package pages import ( "fmt" "os" - "path" - "path/filepath" "reflect" "sort" "strings" @@ -71,30 +69,6 @@ func NewFile(filename string, c Container, relpath string, defaults map[string]i return p, nil } -// ToLiquid returns the attributes of the template page object. -// See https://jekyllrb.com/docs/variables/#page-variables -func (f *file) ToLiquid() interface{} { - var ( - relpath = "/" + filepath.ToSlash(f.relpath) - base = path.Base(relpath) - ext = path.Ext(relpath) - ) - - return templates.MergeVariableMaps(f.frontMatter, map[string]interface{}{ - "path": relpath, - "modified_time": f.fileModTime, - "name": base, - "basename": helpers.TrimExt(base), - "extname": ext, - }) -} - -// MarshalYAML is part of the yaml.Marshaler interface -// The variables subcommand uses this. -func (f *file) MarshalYAML() (interface{}, error) { - return f.ToLiquid(), nil -} - // Categories is in the File interface func (f *file) Categories() []string { return sortedStringValue(f.frontMatter["categories"]) diff --git a/pages/page.go b/pages/page.go index 26f86ff..4e458f4 100644 --- a/pages/page.go +++ b/pages/page.go @@ -5,10 +5,8 @@ import ( "fmt" "io" "io/ioutil" - "path/filepath" "time" - "github.com/osteele/gojekyll/helpers" "github.com/osteele/gojekyll/templates" "github.com/osteele/liquid/generics" ) @@ -39,66 +37,6 @@ func newPage(filename string, f file) (*page, error) { }, nil } -// ToLiquid is in the liquid.Drop interface. -func (p *page) ToLiquid() interface{} { - var ( - relpath = p.relpath - ext = filepath.Ext(relpath) - root = helpers.TrimExt(p.relpath) - base = filepath.Base(root) - ) - - data := map[string]interface{}{ - "path": relpath, - "url": p.Permalink(), - // TODO output - - // not documented, but present in both collection and non-collection pages - "permalink": p.Permalink(), - - // TODO only in non-collection pages: - // TODO dir - // TODO name - // TODO next previous - - // TODO Documented as present in all pages, but de facto only defined for collection pages - "id": base, - "title": base, // TODO capitalize - // TODO excerpt category? categories tags - // TODO slug - "categories": p.Categories(), - "tags": p.Tags(), - - // TODO Only present in collection pages https://jekyllrb.com/docs/collections/#documents - "relative_path": p.Path(), - // TODO collection(name) - - // TODO undocumented; only present in collection pages: - "ext": ext, - } - for k, v := range p.frontMatter { - switch k { - // doc implies these aren't present, but they appear to be present in a collection page: - // case "layout", "published": - case "permalink": - // omit this, in order to use the value above - default: - data[k] = v - } - } - if p.content != nil { - data["content"] = string(*p.content) - // TODO excerpt - } - return data -} - -// MarshalYAML is part of the yaml.Marshaler interface -// The variables subcommand uses this. -func (p *page) MarshalYAML() (interface{}, error) { - return p.ToLiquid(), nil -} - // TemplateContext returns the local variables for template evaluation func (p *page) TemplateContext(rc RenderingContext) map[string]interface{} { return map[string]interface{}{ diff --git a/server/server.go b/server/server.go index d457b71..878a769 100644 --- a/server/server.go +++ b/server/server.go @@ -11,13 +11,13 @@ import ( "time" "github.com/jaschaephraim/lrserver" - "github.com/osteele/gojekyll/sites" + "github.com/osteele/gojekyll/site" "github.com/pkg/browser" ) // Server serves the site on HTTP. type Server struct { - Site *sites.Site + Site *site.Site mu sync.Mutex lr *lrserver.Server } diff --git a/sites/build.go b/site/build.go similarity index 98% rename from sites/build.go rename to site/build.go index a96dced..975bd67 100644 --- a/sites/build.go +++ b/site/build.go @@ -1,4 +1,4 @@ -package sites +package site import ( "fmt" diff --git a/sites/data.go b/site/data.go similarity index 98% rename from sites/data.go rename to site/data.go index 8bb8e84..176f1a1 100644 --- a/sites/data.go +++ b/site/data.go @@ -1,4 +1,4 @@ -package sites +package site import ( "fmt" diff --git a/sites/drop.go b/site/drop.go similarity index 98% rename from sites/drop.go rename to site/drop.go index a40a5dd..227e3c2 100644 --- a/sites/drop.go +++ b/site/drop.go @@ -1,4 +1,4 @@ -package sites +package site import ( "time" diff --git a/sites/posts.go b/site/posts.go similarity index 85% rename from sites/posts.go rename to site/posts.go index f864aef..caf1682 100644 --- a/sites/posts.go +++ b/site/posts.go @@ -1,11 +1,11 @@ -package sites +package site import ( - "github.com/osteele/gojekyll/collections" + "github.com/osteele/gojekyll/collection" "github.com/osteele/gojekyll/pages" ) -func (s *Site) findPostCollection() *collections.Collection { +func (s *Site) findPostCollection() *collection.Collection { for _, c := range s.Collections { if c.Name == "posts" { return c diff --git a/sites/load.go b/site/read.go similarity index 88% rename from sites/load.go rename to site/read.go index ddcd9fc..5bd6ec8 100644 --- a/sites/load.go +++ b/site/read.go @@ -1,19 +1,19 @@ -package sites +package site import ( "io/ioutil" "os" "path/filepath" - "github.com/osteele/gojekyll/collections" + "github.com/osteele/gojekyll/collection" "github.com/osteele/gojekyll/config" "github.com/osteele/gojekyll/helpers" "github.com/osteele/gojekyll/pages" ) -// NewSiteFromDirectory reads the configuration file, if it exists. -func NewSiteFromDirectory(source string, flags config.Flags) (*Site, error) { - s := NewSite(flags) +// FromDirectory reads the configuration file, if it exists. +func FromDirectory(source string, flags config.Flags) (*Site, error) { + s := New(flags) configPath := filepath.Join(source, "_config.yml") bytes, err := ioutil.ReadFile(configPath) switch { @@ -44,7 +44,7 @@ func (s *Site) Load() error { // Reload reloads the config file and pages. // If there's an error loading the config file, it has no effect. func (s *Site) Reload() error { - copy, err := NewSiteFromDirectory(s.SourceDir(), s.flags) + copy, err := FromDirectory(s.SourceDir(), s.flags) if err != nil { return err } @@ -52,7 +52,7 @@ func (s *Site) Reload() error { return s.Load() } -// readFiles scans the source directory and creates pages and collections. +// readFiles scans the source directory and creates pages and collection. func (s *Site) readFiles() error { s.Routes = make(map[string]pages.Document) @@ -97,7 +97,7 @@ func (s *Site) AddDocument(p pages.Document, output bool) { // It adds each collection's pages to the site map, and creates a template site variable for each collection. func (s *Site) ReadCollections() error { for name, data := range s.config.Collections { - c := collections.NewCollection(s, name, data) + c := collection.New(s, name, data) s.Collections = append(s.Collections, c) if err := c.ReadPages(); err != nil { return err diff --git a/sites/site.go b/site/site.go similarity index 94% rename from sites/site.go rename to site/site.go index df8347f..897ce8f 100644 --- a/sites/site.go +++ b/site/site.go @@ -1,11 +1,11 @@ -package sites +package site import ( "fmt" "path/filepath" "strings" - "github.com/osteele/gojekyll/collections" + "github.com/osteele/gojekyll/collection" "github.com/osteele/gojekyll/config" "github.com/osteele/gojekyll/helpers" "github.com/osteele/gojekyll/pages" @@ -17,7 +17,7 @@ import ( // Site is a Jekyll site. type Site struct { ConfigFile *string - Collections []*collections.Collection + Collections []*collection.Collection // Variables map[string]interface{} Routes map[string]pages.Document // URL path -> Page, only for output pages @@ -53,7 +53,7 @@ func (s *Site) OutputPages() []pages.Document { // Pages returns all the pages, output or not. func (s *Site) Pages() []pages.Document { return s.docs } -// AbsDir is in the collections.Site interface. +// AbsDir is in the collection.Site interface. func (s *Site) AbsDir() string { d, err := filepath.Abs(s.SourceDir()) if err != nil { @@ -62,7 +62,7 @@ func (s *Site) AbsDir() string { return d } -// Config is in the collections.Site interface. +// Config is in the collection.Site interface. func (s *Site) Config() *config.Config { return &s.config } @@ -75,8 +75,8 @@ func (s *Site) Site() interface{} { // PathPrefix is in the page.Container interface. func (s *Site) PathPrefix() string { return "" } -// NewSite creates a new site record, initialized with the site defaults. -func NewSite(flags config.Flags) *Site { +// New creates a new site record, initialized with the site defaults. +func New(flags config.Flags) *Site { s := &Site{config: config.Default(), flags: flags} s.config.ApplyFlags(flags) return s diff --git a/sites/site_test.go b/site/site_test.go similarity index 86% rename from sites/site_test.go rename to site/site_test.go index f14b5ad..8f8e353 100644 --- a/sites/site_test.go +++ b/site/site_test.go @@ -1,4 +1,4 @@ -package sites +package site import ( "testing" @@ -8,7 +8,7 @@ import ( ) func TestIsMarkdown(t *testing.T) { - s := NewSite(config.Flags{}) + s := New(config.Flags{}) require.Equal(t, "", s.PathPrefix()) require.False(t, s.KeepFile("random")) require.True(t, s.KeepFile(".git")) diff --git a/sites/write.go b/site/write.go similarity index 99% rename from sites/write.go rename to site/write.go index 4b49012..cf19910 100644 --- a/sites/write.go +++ b/site/write.go @@ -1,4 +1,4 @@ -package sites +package site import ( "fmt"