mirror of
https://codeberg.org/git-pages/git-pages.git
synced 2026-05-14 11:11:35 +00:00
This is to prepare for making manifest debug representation accessible. - change `Entry.size` to `uint32` so that it's serialized as a number in protoJSON export - rename `Manifest.files` to `Manifest.contents` - leave size and data for the root directory empty, same as with non-root directories fetched from git
100 lines
2.4 KiB
Go
100 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
func readToManifest(root *os.Root) (*Manifest, error) {
|
|
manifest := Manifest{}
|
|
manifest.Contents = make(map[string]*Entry)
|
|
err := fs.WalkDir(root.FS(), ".", func(path string, dirEntry fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
manifestEntry := Entry{}
|
|
if dirEntry.IsDir() {
|
|
manifestEntry.Type = Type_Directory.Enum()
|
|
} else if dirEntry.Type().IsRegular() {
|
|
data, err := root.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
manifestEntry.Type = Type_InlineFile.Enum()
|
|
manifestEntry.Size = proto.Uint32(uint32(len(data)))
|
|
manifestEntry.Data = data
|
|
} else if dirEntry.Type().Type() == fs.ModeSymlink {
|
|
target, err := root.Readlink(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
manifestEntry.Type = Type_Symlink.Enum()
|
|
manifestEntry.Size = proto.Uint32(uint32(len(target)))
|
|
manifestEntry.Data = []byte(target)
|
|
} else {
|
|
log.Printf("migrate v1: illegal %s/%s\n", root.Name(), path)
|
|
}
|
|
if path == "." {
|
|
path = ""
|
|
}
|
|
manifest.Contents[path] = &manifestEntry
|
|
return nil
|
|
})
|
|
return &manifest, err
|
|
}
|
|
|
|
type ReadDirLinkFS interface { // aaaaahh!!! Why is Go like this!!
|
|
fs.ReadDirFS
|
|
fs.ReadLinkFS
|
|
}
|
|
|
|
func MigrateFromV1(root *os.Root) error {
|
|
data := root.FS().(ReadDirLinkFS)
|
|
|
|
domainDirEntries, err := data.ReadDir("www")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, domainDirEntry := range domainDirEntries {
|
|
domain := domainDirEntry.Name()
|
|
if !domainDirEntry.IsDir() {
|
|
return fmt.Errorf("migrate v1: www/%s: not a directory", domain)
|
|
}
|
|
|
|
projectDirEntries, err := data.ReadDir(filepath.Join("www", domain))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, projectDirEntry := range projectDirEntries {
|
|
projectName := projectDirEntry.Name()
|
|
if projectDirEntry.Type().Type() != fs.ModeSymlink {
|
|
return fmt.Errorf("migrate v1: www/%s/%s: not a symlink", domain, projectName)
|
|
}
|
|
|
|
treeRoot, err := root.OpenRoot(filepath.Join("www", domain, projectName))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
manifest, err := readToManifest(treeRoot)
|
|
if err != nil {
|
|
return fmt.Errorf("migrate v1: read %s/%s: %w", domain, projectName, err)
|
|
}
|
|
|
|
_, err = StoreManifest(fmt.Sprintf("%s/%s", domain, projectName), manifest)
|
|
if err != nil {
|
|
return fmt.Errorf("migrate v1: store %s/%s: %w", domain, projectName, err)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|