diff options
Diffstat (limited to 'hugolib/filesystems/basefs.go')
-rw-r--r-- | hugolib/filesystems/basefs.go | 441 |
1 files changed, 208 insertions, 233 deletions
diff --git a/hugolib/filesystems/basefs.go b/hugolib/filesystems/basefs.go index a7c2a6271..b37fb8cb4 100644 --- a/hugolib/filesystems/basefs.go +++ b/hugolib/filesystems/basefs.go @@ -19,12 +19,12 @@ import ( "fmt" "io" "os" - "path" "path/filepath" "strings" "sync" "github.com/bep/overlayfs" + "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/htesting" "github.com/gohugoio/hugo/hugofs/glob" @@ -60,9 +60,12 @@ type BaseFs struct { // SourceFilesystems contains the different source file systems. *SourceFilesystems - // The project source. + // The source filesystem (needs absolute filenames). SourceFs afero.Fs + // The project source. + ProjectSourceFs afero.Fs + // The filesystem used to publish the rendered site. // This usually maps to /my-project/public. PublishFs afero.Fs @@ -95,67 +98,84 @@ func (f *fakeLockfileMutex) Lock() (func(), error) { } // Tries to acquire a build lock. -func (fs *BaseFs) LockBuild() (unlock func(), err error) { - return fs.buildMu.Lock() +func (b *BaseFs) LockBuild() (unlock func(), err error) { + return b.buildMu.Lock() } -// TODO(bep) we can get regular files in here and that is fine, but -// we need to clean up the naming. -func (fs *BaseFs) WatchDirs() []hugofs.FileMetaInfo { - var dirs []hugofs.FileMetaInfo - for _, dir := range fs.AllDirs() { - if dir.Meta().Watch { - dirs = append(dirs, dir) - } - } - return dirs -} +func (b *BaseFs) WatchFilenames() []string { + var filenames []string + sourceFs := b.SourceFs + + for _, rfs := range b.RootFss { + for _, component := range files.ComponentFolders { + fis, err := rfs.Mounts(component) + if err != nil { + continue + } + + for _, fim := range fis { + meta := fim.Meta() + if !meta.Watch { + continue + } + + if !fim.IsDir() { + filenames = append(filenames, meta.Filename) + continue + } + + w := hugofs.NewWalkway(hugofs.WalkwayConfig{ + Fs: sourceFs, + Root: meta.Filename, + WalkFn: func(path string, fi hugofs.FileMetaInfo) error { + if !fi.IsDir() { + return nil + } + if fi.Name() == ".git" || + fi.Name() == "node_modules" || fi.Name() == "bower_components" { + return filepath.SkipDir + } + filenames = append(filenames, fi.Meta().Filename) + return nil + }, + }) + + w.Walk() + } -func (fs *BaseFs) AllDirs() []hugofs.FileMetaInfo { - var dirs []hugofs.FileMetaInfo - for _, dirSet := range [][]hugofs.FileMetaInfo{ - fs.Archetypes.Dirs, - fs.I18n.Dirs, - fs.Data.Dirs, - fs.Content.Dirs, - fs.Assets.Dirs, - fs.Layouts.Dirs, - // fs.Resources.Dirs, - fs.StaticDirs, - } { - dirs = append(dirs, dirSet...) + } } - return dirs + return filenames } -// RelContentDir tries to create a path relative to the content root from -// the given filename. The return value is the path and language code. -func (b *BaseFs) RelContentDir(filename string) string { - for _, dir := range b.SourceFilesystems.Content.Dirs { - dirname := dir.Meta().Filename - if strings.HasPrefix(filename, dirname) { - rel := path.Join(dir.Meta().Path, strings.TrimPrefix(filename, dirname)) - return strings.TrimPrefix(rel, filePathSeparator) +func (b *BaseFs) mountsForComponent(component string) []hugofs.FileMetaInfo { + var result []hugofs.FileMetaInfo + for _, rfs := range b.RootFss { + dirs, err := rfs.Mounts(component) + if err == nil { + result = append(result, dirs...) } } - // Either not a content dir or already relative. - return filename + return result } // AbsProjectContentDir tries to construct a filename below the most // relevant content directory. func (b *BaseFs) AbsProjectContentDir(filename string) (string, string, error) { isAbs := filepath.IsAbs(filename) - for _, dir := range b.SourceFilesystems.Content.Dirs { - meta := dir.Meta() + for _, fi := range b.mountsForComponent(files.ComponentFolderContent) { + if !fi.IsDir() { + continue + } + meta := fi.Meta() if !meta.IsProject { continue } if isAbs { if strings.HasPrefix(filename, meta.Filename) { - return strings.TrimPrefix(filename, meta.Filename), filename, nil + return strings.TrimPrefix(filename, meta.Filename+filePathSeparator), filename, nil } } else { contentDir := strings.TrimPrefix(strings.TrimPrefix(meta.Filename, meta.BaseDir), filePathSeparator) + filePathSeparator @@ -173,7 +193,10 @@ func (b *BaseFs) AbsProjectContentDir(filename string) (string, string, error) { // A filename on the form "posts/mypage.md", put it inside // the first content folder, usually <workDir>/content. // Pick the first project dir (which is probably the most important one). - for _, dir := range b.SourceFilesystems.Content.Dirs { + for _, dir := range b.SourceFilesystems.Content.mounts() { + if !dir.IsDir() { + continue + } meta := dir.Meta() if meta.IsProject { return filename, filepath.Join(meta.Filename, filename), nil @@ -186,14 +209,14 @@ func (b *BaseFs) AbsProjectContentDir(filename string) (string, string, error) { // ResolveJSConfigFile resolves the JS-related config file to a absolute // filename. One example of such would be postcss.config.js. -func (fs *BaseFs) ResolveJSConfigFile(name string) string { +func (b *BaseFs) ResolveJSConfigFile(name string) string { // First look in assets/_jsconfig - fi, err := fs.Assets.Fs.Stat(filepath.Join(files.FolderJSConfig, name)) + fi, err := b.Assets.Fs.Stat(filepath.Join(files.FolderJSConfig, name)) if err == nil { return fi.(hugofs.FileMetaInfo).Meta().Filename } // Fall back to the work dir. - fi, err = fs.Work.Stat(name) + fi, err = b.Work.Stat(name) if err == nil { return fi.(hugofs.FileMetaInfo).Meta().Filename } @@ -201,27 +224,6 @@ func (fs *BaseFs) ResolveJSConfigFile(name string) string { return "" } -// MakePathRelative creates a relative path from the given filename. -// It returns both the component name (e.g. layouts) and the path relative to that. -func (fs *BaseFs) MakePathRelative(filename string) (string, string) { - for _, sfs := range fs.FileSystems() { - if sfs.Contains(filename) { - if s, found := sfs.MakePathRelative(filename); found { - return sfs.Name, s - } - } - } - // May be a static file. - if s := fs.MakeStaticPathRelative(filename); s != "" { - return files.ComponentFolderStatic, s - } - // Fall back to relative to the working dir. - if strings.HasPrefix(filename, fs.workingDir) { - return "", strings.TrimPrefix(filename, fs.workingDir) - } - return "", "" -} - // SourceFilesystems contains the different source file systems. These can be // composite file systems (theme and project etc.), and they have all root // set to the source type the provides: data, i18n, static, layouts. @@ -233,6 +235,10 @@ type SourceFilesystems struct { Archetypes *SourceFilesystem Assets *SourceFilesystem + AssetsWithDuplicatesPreserved *SourceFilesystem + + RootFss []*hugofs.RootMappingFs + // Writable filesystem on top the project's resources directory, // with any sub module's resource fs layered below. ResourcesCache afero.Fs @@ -246,23 +252,7 @@ type SourceFilesystems struct { // When in non-multihost mode there will be one entry in this map with a blank key. Static map[string]*SourceFilesystem - // All the /static dirs (including themes/modules). - StaticDirs []hugofs.FileMetaInfo -} - -// FileSystems returns the FileSystems relevant for the change detection -// in server mode. -// Note: This does currently not return any static fs. -func (s *SourceFilesystems) FileSystems() []*SourceFilesystem { - return []*SourceFilesystem{ - s.Content, - s.Assets, - s.Data, - s.I18n, - s.Layouts, - s.Archetypes, - // TODO(bep) static - } + conf config.AllProvider } // A SourceFilesystem holds the filesystem for a given source type in Hugo (data, @@ -275,32 +265,12 @@ type SourceFilesystem struct { // This is a virtual composite filesystem. It expects path relative to a context. Fs afero.Fs - // This filesystem as separate root directories, starting from project and down - // to the themes/modules. - Dirs []hugofs.FileMetaInfo - // When syncing a source folder to the target (e.g. /public), this may // be set to publish into a subfolder. This is used for static syncing // in multihost mode. PublishFolder string } -// ContentStaticAssetFs will create a new composite filesystem from the content, -// static, and asset filesystems. The site language is needed to pick the correct static filesystem. -// The order is content, static and then assets. -// TODO(bep) check usage -func (s SourceFilesystems) ContentStaticAssetFs(lang string) afero.Fs { - return overlayfs.New( - overlayfs.Options{ - Fss: []afero.Fs{ - s.Content.Fs, - s.StaticFs(lang), - s.Assets.Fs, - }, - }, - ) -} - // StaticFs returns the static filesystem for the given language. // This can be a composite filesystem. func (s SourceFilesystems) StaticFs(lang string) afero.Fs { @@ -349,24 +319,17 @@ func (s SourceFilesystems) IsContent(filename string) bool { return s.Content.Contains(filename) } -// IsLayout returns true if the given filename is a member of the layouts filesystem. -func (s SourceFilesystems) IsLayout(filename string) bool { - return s.Layouts.Contains(filename) -} - -// IsData returns true if the given filename is a member of the data filesystem. -func (s SourceFilesystems) IsData(filename string) bool { - return s.Data.Contains(filename) -} - -// IsAsset returns true if the given filename is a member of the asset filesystem. -func (s SourceFilesystems) IsAsset(filename string) bool { - return s.Assets.Contains(filename) -} - -// IsI18n returns true if the given filename is a member of the i18n filesystem. -func (s SourceFilesystems) IsI18n(filename string) bool { - return s.I18n.Contains(filename) +// ResolvePaths resolves the given filename to a list of paths in the filesystems. +func (s *SourceFilesystems) ResolvePaths(filename string, checkExists bool) []hugofs.ComponentPath { + var cpss []hugofs.ComponentPath + for _, rfs := range s.RootFss { + cps, err := rfs.ReverseLookup(filename, checkExists) + if err != nil { + panic(err) + } + cpss = append(cpss, cps...) + } + return cpss } // MakeStaticPathRelative makes an absolute static filename into a relative one. @@ -383,19 +346,53 @@ func (s SourceFilesystems) MakeStaticPathRelative(filename string) string { // MakePathRelative creates a relative path from the given filename. func (d *SourceFilesystem) MakePathRelative(filename string) (string, bool) { - for _, dir := range d.Dirs { - meta := dir.(hugofs.FileMetaInfo).Meta() - currentPath := meta.Filename - - if strings.HasPrefix(filename, currentPath) { - rel := strings.TrimPrefix(filename, currentPath) - if mp := meta.Path; mp != "" { - rel = filepath.Join(mp, rel) + cps, err := d.ReverseLookup(filename) + if err != nil { + panic(err) + } + if len(cps) == 0 { + return "", false + } + + return filepath.FromSlash(cps[0].Path), true +} + +// ReverseLookup returns the component paths for the given filename. +func (d *SourceFilesystem) ReverseLookup(filename string) ([]hugofs.ComponentPath, error) { + var cps []hugofs.ComponentPath + hugofs.WalkFilesystems(d.Fs, func(fs afero.Fs) bool { + if rfs, ok := fs.(hugofs.ReverseLookupProvder); ok { + if c, err := rfs.ReverseLookup(filename, true); err == nil { + cps = append(cps, c...) } - return strings.TrimPrefix(rel, filePathSeparator), true + } + return false + }) + return cps, nil +} + +func (d *SourceFilesystem) mounts() []hugofs.FileMetaInfo { + var m []hugofs.FileMetaInfo + hugofs.WalkFilesystems(d.Fs, func(fs afero.Fs) bool { + if rfs, ok := fs.(*hugofs.RootMappingFs); ok { + mounts, err := rfs.Mounts(d.Name) + if err == nil { + m = append(m, mounts...) + } + + } + return false + }) + // Filter out any mounts not belonging to this filesystem. + n := 0 + for _, mm := range m { + if mm.Meta().Component == d.Name { + m[n] = mm + n++ } } - return "", false + m = m[:n] + return m } func (d *SourceFilesystem) RealFilename(rel string) string { @@ -412,7 +409,10 @@ func (d *SourceFilesystem) RealFilename(rel string) string { // Contains returns whether the given filename is a member of the current filesystem. func (d *SourceFilesystem) Contains(filename string) bool { - for _, dir := range d.Dirs { + for _, dir := range d.mounts() { + if !dir.IsDir() { + continue + } if strings.HasPrefix(filename, dir.Meta().Filename) { return true } @@ -420,32 +420,18 @@ func (d *SourceFilesystem) Contains(filename string) bool { return false } -// Path returns the mount relative path to the given filename if it is a member of -// of the current filesystem, an empty string if not. -func (d *SourceFilesystem) Path(filename string) string { - for _, dir := range d.Dirs { - meta := dir.Meta() - if strings.HasPrefix(filename, meta.Filename) { - p := strings.TrimPrefix(strings.TrimPrefix(filename, meta.Filename), filePathSeparator) - if mountRoot := meta.MountRoot; mountRoot != "" { - return filepath.Join(mountRoot, p) - } - return p - } - } - return "" -} - // RealDirs gets a list of absolute paths to directories starting from the given // path. func (d *SourceFilesystem) RealDirs(from string) []string { var dirnames []string - for _, dir := range d.Dirs { - meta := dir.Meta() - dirname := filepath.Join(meta.Filename, from) - _, err := meta.Fs.Stat(from) - + for _, m := range d.mounts() { + if !m.IsDir() { + continue + } + meta := m.Meta() + _, err := d.Fs.Stat(from) if err == nil { + dirname := filepath.Join(meta.Filename, from) dirnames = append(dirnames, dirname) } } @@ -462,8 +448,6 @@ func WithBaseFs(b *BaseFs) func(*BaseFs) error { } } -var counter int - // NewBase builds the filesystems used by Hugo given the paths and options provided.NewBase func NewBase(p *paths.Paths, logger loggers.Logger, options ...func(*BaseFs) error) (*BaseFs, error) { fs := p.Fs @@ -472,7 +456,8 @@ func NewBase(p *paths.Paths, logger loggers.Logger, options ...func(*BaseFs) err } publishFs := hugofs.NewBaseFileDecorator(fs.PublishDir) - sourceFs := hugofs.NewBaseFileDecorator(afero.NewBasePathFs(fs.Source, p.Cfg.BaseConfig().WorkingDir)) + projectSourceFs := hugofs.NewBaseFileDecorator(hugofs.NewBasePathFs(fs.Source, p.Cfg.BaseConfig().WorkingDir)) + sourceFs := hugofs.NewBaseFileDecorator(fs.Source) publishFsStatic := fs.PublishDirStatic var buildMu Lockable @@ -484,6 +469,7 @@ func NewBase(p *paths.Paths, logger loggers.Logger, options ...func(*BaseFs) err b := &BaseFs{ SourceFs: sourceFs, + ProjectSourceFs: projectSourceFs, WorkDir: fs.WorkingDirReadOnly, PublishFs: publishFs, PublishFsStatic: publishFsStatic, @@ -523,14 +509,18 @@ type sourceFilesystemsBuilder struct { func newSourceFilesystemsBuilder(p *paths.Paths, logger loggers.Logger, b *BaseFs) *sourceFilesystemsBuilder { sourceFs := hugofs.NewBaseFileDecorator(p.Fs.Source) - return &sourceFilesystemsBuilder{p: p, logger: logger, sourceFs: sourceFs, theBigFs: b.theBigFs, result: &SourceFilesystems{}} + return &sourceFilesystemsBuilder{ + p: p, logger: logger, sourceFs: sourceFs, theBigFs: b.theBigFs, + result: &SourceFilesystems{ + conf: p.Cfg, + }, + } } -func (b *sourceFilesystemsBuilder) newSourceFilesystem(name string, fs afero.Fs, dirs []hugofs.FileMetaInfo) *SourceFilesystem { +func (b *sourceFilesystemsBuilder) newSourceFilesystem(name string, fs afero.Fs) *SourceFilesystem { return &SourceFilesystem{ Name: name, Fs: fs, - Dirs: dirs, } } @@ -544,64 +534,61 @@ func (b *sourceFilesystemsBuilder) Build() (*SourceFilesystems, error) { b.theBigFs = theBigFs } - createView := func(componentID string) *SourceFilesystem { + createView := func(componentID string, overlayFs *overlayfs.OverlayFs) *SourceFilesystem { if b.theBigFs == nil || b.theBigFs.overlayMounts == nil { - return b.newSourceFilesystem(componentID, hugofs.NoOpFs, nil) + return b.newSourceFilesystem(componentID, hugofs.NoOpFs) } - dirs := b.theBigFs.overlayDirs[componentID] + fs := hugofs.NewComponentFs( + hugofs.ComponentFsOptions{ + Fs: overlayFs, + Component: componentID, + DefaultContentLanguage: b.p.Cfg.DefaultContentLanguage(), + PathParser: b.p.Cfg.PathParser(), + }, + ) - return b.newSourceFilesystem(componentID, afero.NewBasePathFs(b.theBigFs.overlayMounts, componentID), dirs) + return b.newSourceFilesystem(componentID, fs) } - b.result.Archetypes = createView(files.ComponentFolderArchetypes) - b.result.Layouts = createView(files.ComponentFolderLayouts) - b.result.Assets = createView(files.ComponentFolderAssets) + b.result.Archetypes = createView(files.ComponentFolderArchetypes, b.theBigFs.overlayMounts) + b.result.Layouts = createView(files.ComponentFolderLayouts, b.theBigFs.overlayMounts) + b.result.Assets = createView(files.ComponentFolderAssets, b.theBigFs.overlayMounts) b.result.ResourcesCache = b.theBigFs.overlayResources + b.result.RootFss = b.theBigFs.rootFss + + // data and i18n needs a different merge strategy. + overlayMountsPreserveDupes := b.theBigFs.overlayMounts.WithDirsMerger(hugofs.AppendDirsMerger) + b.result.Data = createView(files.ComponentFolderData, overlayMountsPreserveDupes) + b.result.I18n = createView(files.ComponentFolderI18n, overlayMountsPreserveDupes) + b.result.AssetsWithDuplicatesPreserved = createView(files.ComponentFolderAssets, overlayMountsPreserveDupes) + + contentFs := hugofs.NewComponentFs( + hugofs.ComponentFsOptions{ + Fs: b.theBigFs.overlayMountsContent, + Component: files.ComponentFolderContent, + DefaultContentLanguage: b.p.Cfg.DefaultContentLanguage(), + PathParser: b.p.Cfg.PathParser(), + }, + ) - // Data, i18n and content cannot use the overlay fs - dataDirs := b.theBigFs.overlayDirs[files.ComponentFolderData] - dataFs, err := hugofs.NewSliceFs(dataDirs...) - if err != nil { - return nil, err - } - - b.result.Data = b.newSourceFilesystem(files.ComponentFolderData, dataFs, dataDirs) - - i18nDirs := b.theBigFs.overlayDirs[files.ComponentFolderI18n] - i18nFs, err := hugofs.NewSliceFs(i18nDirs...) - if err != nil { - return nil, err - } - b.result.I18n = b.newSourceFilesystem(files.ComponentFolderI18n, i18nFs, i18nDirs) - - contentDirs := b.theBigFs.overlayDirs[files.ComponentFolderContent] - contentBfs := afero.NewBasePathFs(b.theBigFs.overlayMountsContent, files.ComponentFolderContent) - - contentFs, err := hugofs.NewLanguageFs(b.p.Cfg.LanguagesDefaultFirst().AsOrdinalSet(), contentBfs) - if err != nil { - return nil, fmt.Errorf("create content filesystem: %w", err) - } - - b.result.Content = b.newSourceFilesystem(files.ComponentFolderContent, contentFs, contentDirs) - - b.result.Work = afero.NewReadOnlyFs(b.theBigFs.overlayFull) + b.result.Content = b.newSourceFilesystem(files.ComponentFolderContent, contentFs) + b.result.Work = hugofs.NewReadOnlyFs(b.theBigFs.overlayFull) // Create static filesystem(s) ms := make(map[string]*SourceFilesystem) b.result.Static = ms - b.result.StaticDirs = b.theBigFs.overlayDirs[files.ComponentFolderStatic] if b.theBigFs.staticPerLanguage != nil { // Multihost mode for k, v := range b.theBigFs.staticPerLanguage { - sfs := b.newSourceFilesystem(files.ComponentFolderStatic, v, b.result.StaticDirs) + sfs := b.newSourceFilesystem(files.ComponentFolderStatic, v) sfs.PublishFolder = k ms[k] = sfs } } else { - bfs := afero.NewBasePathFs(b.theBigFs.overlayMountsStatic, files.ComponentFolderStatic) - ms[""] = b.newSourceFilesystem(files.ComponentFolderStatic, bfs, b.result.StaticDirs) + bfs := hugofs.NewBasePathFs(b.theBigFs.overlayMountsStatic, files.ComponentFolderStatic) + ms[""] = b.newSourceFilesystem(files.ComponentFolderStatic, bfs) } return b.result, nil @@ -619,8 +606,7 @@ func (b *sourceFilesystemsBuilder) createMainOverlayFs(p *paths.Paths) (*filesys collector := &filesystemsCollector{ sourceProject: b.sourceFs, - sourceModules: hugofs.NewNoSymlinkFs(b.sourceFs, b.logger, false), - overlayDirs: make(map[string][]hugofs.FileMetaInfo), + sourceModules: b.sourceFs, staticPerLanguage: staticFsMap, overlayMounts: overlayfs.New(overlayfs.Options{}), @@ -675,6 +661,7 @@ func (b *sourceFilesystemsBuilder) createOverlayFs( collector.overlayMounts = appendNopIfEmpty(collector.overlayMounts) collector.overlayMountsContent = appendNopIfEmpty(collector.overlayMountsContent) collector.overlayMountsStatic = appendNopIfEmpty(collector.overlayMountsStatic) + collector.overlayMountsFull = appendNopIfEmpty(collector.overlayMountsFull) collector.overlayFull = appendNopIfEmpty(collector.overlayFull) collector.overlayResources = appendNopIfEmpty(collector.overlayResources) @@ -712,15 +699,15 @@ func (b *sourceFilesystemsBuilder) createOverlayFs( base, filename := absPathify(mount.Source) rm := hugofs.RootMapping{ - From: mount.Target, - To: filename, - ToBasedir: base, - Module: md.Module.Path(), - IsProject: md.isMainProject, + From: mount.Target, + To: filename, + ToBase: base, + Module: md.Module.Path(), + ModuleOrdinal: md.ordinal, + IsProject: md.isMainProject, Meta: &hugofs.FileMeta{ Watch: md.Watch(), Weight: mountWeight, - Classifier: files.ContentClassContent, InclusionFilter: inclusionFilter, }, } @@ -747,7 +734,8 @@ func (b *sourceFilesystemsBuilder) createOverlayFs( if !md.isMainProject { modBase = collector.sourceModules } - sourceStatic := hugofs.NewNoSymlinkFs(modBase, b.logger, true) + + sourceStatic := modBase rmfs, err := hugofs.NewRootMappingFs(modBase, fromTo...) if err != nil { @@ -762,11 +750,10 @@ func (b *sourceFilesystemsBuilder) createOverlayFs( return err } - // We need to keep the ordered list of directories for watching and - // some special merge operations (data, i18n). - collector.addDirs(rmfs) - collector.addDirs(rmfsContent) - collector.addDirs(rmfsStatic) + // We need to keep the list of directories for watching. + collector.addRootFs(rmfs) + collector.addRootFs(rmfsContent) + collector.addRootFs(rmfsStatic) if collector.staticPerLanguage != nil { for _, l := range b.p.Cfg.Languages() { @@ -776,7 +763,7 @@ func (b *sourceFilesystemsBuilder) createOverlayFs( rlang := rm.Meta.Lang return rlang == "" || rlang == lang }) - bfs := afero.NewBasePathFs(lfs, files.ComponentFolderStatic) + bfs := hugofs.NewBasePathFs(lfs, files.ComponentFolderStatic) collector.staticPerLanguage[lang] = collector.staticPerLanguage[lang].Append(bfs) } } @@ -792,14 +779,15 @@ func (b *sourceFilesystemsBuilder) createOverlayFs( collector.overlayMounts = collector.overlayMounts.Append(rmfs) collector.overlayMountsContent = collector.overlayMountsContent.Append(rmfsContent) collector.overlayMountsStatic = collector.overlayMountsStatic.Append(rmfsStatic) - collector.overlayFull = collector.overlayFull.Append(afero.NewBasePathFs(modBase, md.dir)) - collector.overlayResources = collector.overlayResources.Append(afero.NewBasePathFs(modBase, getResourcesDir())) + collector.overlayFull = collector.overlayFull.Append(hugofs.NewBasePathFs(modBase, md.dir)) + collector.overlayResources = collector.overlayResources.Append(hugofs.NewBasePathFs(modBase, getResourcesDir())) } return nil } +//lint:ignore U1000 useful for debugging func printFs(fs afero.Fs, path string, w io.Writer) { if fs == nil { return @@ -827,36 +815,23 @@ type filesystemsCollector struct { overlayMounts *overlayfs.OverlayFs overlayMountsContent *overlayfs.OverlayFs overlayMountsStatic *overlayfs.OverlayFs + overlayMountsFull *overlayfs.OverlayFs overlayFull *overlayfs.OverlayFs overlayResources *overlayfs.OverlayFs - // Maps component type (layouts, static, content etc.) an ordered list of - // directories representing the overlay filesystems above. - overlayDirs map[string][]hugofs.FileMetaInfo + rootFss []*hugofs.RootMappingFs // Set if in multihost mode staticPerLanguage map[string]*overlayfs.OverlayFs - - finalizerInit sync.Once } -func (c *filesystemsCollector) addDirs(rfs *hugofs.RootMappingFs) { - for _, componentFolder := range files.ComponentFolders { - c.addDir(rfs, componentFolder) - } -} - -func (c *filesystemsCollector) addDir(rfs *hugofs.RootMappingFs, componentFolder string) { - dirs, err := rfs.Dirs(componentFolder) - - if err == nil { - c.overlayDirs[componentFolder] = append(c.overlayDirs[componentFolder], dirs...) - } +func (c *filesystemsCollector) addRootFs(rfs *hugofs.RootMappingFs) { + c.rootFss = append(c.rootFss, rfs) } type mountsDescriptor struct { modules.Module dir string isMainProject bool - ordinal int + ordinal int // zero based starting from the project. } |