Skip to content

Commit

Permalink
Fs
Browse files Browse the repository at this point in the history
  • Loading branch information
bep committed Jan 28, 2025
1 parent ee06931 commit cdc8654
Show file tree
Hide file tree
Showing 14 changed files with 351 additions and 109 deletions.
9 changes: 9 additions & 0 deletions common/maps/ordered.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ func NewOrdered[K comparable, T any]() *Ordered[K, T] {
return &Ordered[K, T]{values: make(map[K]T)}
}

// Contains returns whether the map contains the given key.
func (m *Ordered[K, T]) Contains(key K) bool {
if m == nil {
return false
}
_, found := m.values[key]
return found
}

// Set sets the value for the given key.
// Note that insertion order is not affected if a key is re-inserted into the map.
func (m *Ordered[K, T]) Set(key K, value T) {
Expand Down
38 changes: 38 additions & 0 deletions hugofs/dirsmerger.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,41 @@ var AppendDirsMerger overlayfs.DirsMerger = func(lofi, bofi []fs.DirEntry) []fs.

return lofi
}

// DirsMergerPreserveDuplicateFunc returns a DirsMerger that will preserve any duplicate
// as defined by the given func.
func DirsMergerPreserveDuplicateFunc(preserveDuplicate func(fs.DirEntry) bool) overlayfs.DirsMerger {
return func(lofi, bofi []fs.DirEntry) []fs.DirEntry {
for _, fi1 := range bofi {
var found bool
if !preserveDuplicate(fi1) {
for _, fi2 := range lofi {
if fi1.Name() == fi2.Name() {
found = true
break
}
}
}
if !found {
lofi = append(lofi, fi1)
}
}
return lofi
}
}

var FuncDirsMerger2 overlayfs.DirsMerger = func(lofi, bofi []fs.DirEntry) []fs.DirEntry {
for _, bofi := range bofi {
var found bool
for _, lofi := range lofi {
if bofi.Name() == lofi.Name() {
found = true
break
}
}
if !found {
lofi = append(lofi, bofi)
}
}
return lofi
}
3 changes: 1 addition & 2 deletions hugofs/files/classifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ const (
ComponentFolderAssets = "assets"
ComponentFolderI18n = "i18n"

FolderVendor = "_vendor"

FolderVendor = "_vendor"
FolderResources = "resources" // TODO1 remove.
FolderJSConfig = "_jsconfig" // Mounted below /assets with postcss.config.js etc.

Expand Down
4 changes: 4 additions & 0 deletions hugofs/rootmapping_fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func NewRootMappingFs(fs afero.Fs, rms ...RootMapping) (*RootMappingFs, error) {
for _, rm := range rms {
(&rm).clean()

if rm.From == files.FolderVendor {
continue
}

rm.FromBase = files.ResolveComponentFolder(rm.From)

if len(rm.To) < 2 {
Expand Down
31 changes: 21 additions & 10 deletions hugolib/filesystems/basefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package filesystems
import (
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -235,9 +236,6 @@ type SourceFilesystems struct {
Archetypes *SourceFilesystem
Assets *SourceFilesystem

// Note that this can not be mounted. It's currently fixed at the project root.
Vendor *SourceFilesystem

AssetsWithDuplicatesPreserved *SourceFilesystem

RootFss []*hugofs.RootMappingFs
Expand All @@ -246,6 +244,10 @@ type SourceFilesystems struct {
// with any sub module's resource fs layered below.
ResourcesCache afero.Fs // TODO1 remove this.

// A writable filesystem on top of the project's vendor directory
// with any sub module's vendor fs layered.
VendorFs afero.Fs

// The work folder (may be a composite of project and theme components).
Work afero.Fs

Expand Down Expand Up @@ -572,13 +574,13 @@ func (b *sourceFilesystemsBuilder) Build() (*SourceFilesystems, error) {
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.VendorFs = b.theBigFs.overlayVendor
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.Vendor = createView(files.FolderVendor, overlayMountsPreserveDupes)
b.result.AssetsWithDuplicatesPreserved = createView(files.ComponentFolderAssets, overlayMountsPreserveDupes)

contentFs := hugofs.NewComponentFs(
Expand Down Expand Up @@ -632,6 +634,9 @@ func (b *sourceFilesystemsBuilder) createMainOverlayFs(p *paths.Paths) (*filesys
overlayMountsStatic: overlayfs.New(overlayfs.Options{DirsMerger: hugofs.LanguageDirsMerger}),
overlayFull: overlayfs.New(overlayfs.Options{}),
overlayResources: overlayfs.New(overlayfs.Options{FirstWritable: true}),
overlayVendor: overlayfs.New(overlayfs.Options{FirstWritable: true, DirsMerger: hugofs.DirsMergerPreserveDuplicateFunc(func(fi fs.DirEntry) bool {
return fi.Name() == "resources.json"
})}),
}

mods := p.AllModules()
Expand Down Expand Up @@ -682,6 +687,7 @@ func (b *sourceFilesystemsBuilder) createOverlayFs(
collector.overlayMountsFull = appendNopIfEmpty(collector.overlayMountsFull)
collector.overlayFull = appendNopIfEmpty(collector.overlayFull)
collector.overlayResources = appendNopIfEmpty(collector.overlayResources)
collector.overlayVendor = appendNopIfEmpty(collector.overlayVendor)

return nil
}
Expand All @@ -700,7 +706,16 @@ func (b *sourceFilesystemsBuilder) createOverlayFs(
return md.dir, hpaths.AbsPathify(md.dir, path)
}

modBase := collector.sourceProject
if !md.isMainProject {
modBase = collector.sourceModules
}

for i, mount := range md.Mounts() {
if mount.Target == files.FolderVendor {
collector.overlayVendor = collector.overlayVendor.Append(hugofs.NewBasePathFs(modBase, mount.Source))
continue
}
// Add more weight to early mounts.
// When two mounts contain the same filename,
// the first entry wins.
Expand Down Expand Up @@ -748,11 +763,6 @@ func (b *sourceFilesystemsBuilder) createOverlayFs(
}
}

modBase := collector.sourceProject
if !md.isMainProject {
modBase = collector.sourceModules
}

sourceStatic := modBase

rmfs, err := hugofs.NewRootMappingFs(modBase, fromTo...)
Expand Down Expand Up @@ -835,7 +845,8 @@ type filesystemsCollector struct {
overlayMountsStatic *overlayfs.OverlayFs
overlayMountsFull *overlayfs.OverlayFs
overlayFull *overlayfs.OverlayFs
overlayResources *overlayfs.OverlayFs
overlayResources *overlayfs.OverlayFs // TODO1 remove
overlayVendor *overlayfs.OverlayFs

rootFss []*hugofs.RootMappingFs

Expand Down
4 changes: 0 additions & 4 deletions hugolib/hugo_sites_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -709,10 +709,6 @@ func (h *HugoSites) writeVendor(l logg.LevelLogger) error {
return err
}

for _, vf := range v.VendoredResources {
fmt.Println("=== ==", vf.Path, vf.Hash)
}

return nil
}

Expand Down
5 changes: 5 additions & 0 deletions hugolib/integrationtest_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,11 @@ func (s *IntegrationTestBuilder) AddFiles(filenameContent ...string) *Integratio
return s
}

func (s *IntegrationTestBuilder) RemovePublic() *IntegrationTestBuilder {
s.Assert(s.fs.WorkingDirWritable.RemoveAll("public"), qt.IsNil)
return s
}

func (s *IntegrationTestBuilder) RemoveFiles(filenames ...string) *IntegrationTestBuilder {
for _, filename := range filenames {
absFilename := s.absFilename(filename)
Expand Down
1 change: 1 addition & 0 deletions modules/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ func (c *Client) Vendor() error {
}

// Include the resource cache if present.
// TODO1 remove
resourcesDir := filepath.Join(dir, files.FolderResources)
_, err := c.fs.Stat(resourcesDir)
if err == nil {
Expand Down
25 changes: 25 additions & 0 deletions modules/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,11 @@ func (c *collector) applyMounts(moduleImport Import, mod *moduleAdapter) error {
return err
}

mounts, err = c.mountVendorDir(mod, mounts)
if err != nil {
return err
}

mod.mounts = mounts
return nil
}
Expand Down Expand Up @@ -597,6 +602,26 @@ func (c *collector) loadModules() error {
// Matches postcss.config.js etc.
var commonJSConfigs = regexp.MustCompile(`(babel|postcss|tailwind)\.config\.js`)

func (c *collector) mountVendorDir(owner *moduleAdapter, mounts []Mount) ([]Mount, error) {
dir := filepath.Join(owner.Dir(), files.FolderVendor)

add := owner.projectMod
if !add {
if _, err := c.fs.Stat(files.FolderVendor); err == nil {
add = true
}
}

if add {
mounts = append(mounts, Mount{
Source: dir,
Target: files.FolderVendor,
})
}

return mounts, nil
}

func (c *collector) mountCommonJSConfig(owner *moduleAdapter, mounts []Mount) ([]Mount, error) {
for _, m := range mounts {
if strings.HasPrefix(m.Target, files.JsConfigFolderMountPrefix) {
Expand Down
Loading

0 comments on commit cdc8654

Please sign in to comment.