(zilch lang go): introduce proper vfs record
This should hopefully make the code a bit clearer, and is preparation for Rust support.
This commit is contained in:
parent
0c575ca0e4
commit
fc8aea8fb4
5 changed files with 228 additions and 162 deletions
|
|
@ -52,10 +52,10 @@ func (s *DirStat) Sys() any {
|
|||
}
|
||||
|
||||
type Input struct {
|
||||
// directory -> filename -> path
|
||||
Files map[string]map[string]string `json:"files"`
|
||||
GOARCH string `json:"GOARCH"`
|
||||
GOOS string `json:"GOOS"`
|
||||
// list of [directory, filename, target path] (target path is empty, if directory marker)
|
||||
Files [][3]string `json:"files"`
|
||||
GOARCH string `json:"GOARCH"`
|
||||
GOOS string `json:"GOOS"`
|
||||
}
|
||||
|
||||
type Output struct {
|
||||
|
|
@ -66,6 +66,11 @@ type Output struct {
|
|||
Embeds map[string][][]string `json:"embeds"`
|
||||
}
|
||||
|
||||
type FileOrDir struct {
|
||||
Directory []string
|
||||
File string
|
||||
}
|
||||
|
||||
func main() {
|
||||
inputFile, err := os.Open(os.Args[1])
|
||||
if err != nil {
|
||||
|
|
@ -77,6 +82,37 @@ func main() {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
files := make(map[string]*FileOrDir)
|
||||
for _, file := range input.Files {
|
||||
directory := file[0]
|
||||
filename := file[1]
|
||||
contents := file[2]
|
||||
|
||||
dirslash := directory
|
||||
|
||||
if directory != "" {
|
||||
dirslash = directory + "/"
|
||||
}
|
||||
|
||||
if contents == "" {
|
||||
_, ok := files[dirslash+filename]
|
||||
if !ok {
|
||||
files[dirslash+filename] = &FileOrDir{}
|
||||
}
|
||||
} else {
|
||||
files[dirslash+filename] = &FileOrDir{File: contents}
|
||||
}
|
||||
|
||||
parent, ok := files[directory]
|
||||
if !ok {
|
||||
parent = &FileOrDir{}
|
||||
files[directory] = parent
|
||||
}
|
||||
|
||||
parent.Directory = append(parent.Directory, dirslash+filename)
|
||||
}
|
||||
|
||||
ctx := build.Context{
|
||||
GOARCH: input.GOARCH,
|
||||
GOOS: input.GOOS,
|
||||
|
|
@ -89,40 +125,26 @@ func main() {
|
|||
return nil, fs.ErrNotExist
|
||||
}
|
||||
|
||||
dir = path.Clean(dir[5:])
|
||||
if dir == "." {
|
||||
dir = "/"
|
||||
}
|
||||
dir = path.Clean(dir[5:])[1:]
|
||||
|
||||
if !strings.HasSuffix(dir, "/") {
|
||||
dir += "/"
|
||||
}
|
||||
contents, ok := files[dir]
|
||||
|
||||
dircontents, ok := input.Files[dir]
|
||||
if !ok {
|
||||
return nil, fs.ErrNotExist
|
||||
}
|
||||
|
||||
infos := make([]fs.FileInfo, len(dircontents))
|
||||
i := 0
|
||||
for name, file := range dircontents {
|
||||
stat, err := os.Stat(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
infos[i] = &WrappedStat{FileInfo: stat, newName: name}
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
for key := range input.Files {
|
||||
if path.Dir(key) == dir {
|
||||
base := path.Base(key)
|
||||
if strings.HasPrefix(base, ".") || strings.HasPrefix(base, "_") || base == "testdata" {
|
||||
continue
|
||||
infos := make([]fs.FileInfo, len(contents.Directory))
|
||||
for i, filename := range contents.Directory {
|
||||
file := files[filename]
|
||||
if file.File != "" {
|
||||
stat, err := os.Stat(file.File)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
infos = append(infos, &DirStat{base})
|
||||
infos[i] = &WrappedStat{FileInfo: stat, newName: path.Base(filename)}
|
||||
} else {
|
||||
infos[i] = &DirStat{path.Base(filename)}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,16 +158,13 @@ func main() {
|
|||
return nil, fs.ErrNotExist
|
||||
}
|
||||
|
||||
pth = path.Clean(pth[5:])
|
||||
dirname, fname := path.Split(pth)
|
||||
if dirname == "." {
|
||||
dirname = "/"
|
||||
}
|
||||
dir := input.Files[dirname]
|
||||
pth = path.Clean(pth[5:])[1:]
|
||||
fmt.Printf("-> OpenFile(%q)\n", pth)
|
||||
fil := files[pth]
|
||||
|
||||
data, err := os.Open(dir[fname])
|
||||
data, err := os.Open(fil.File)
|
||||
if err != nil {
|
||||
return data, fmt.Errorf("OpenFile(%q; %q[%q]; %q): %w", opth, dirname, fname, dir[fname], err)
|
||||
return data, fmt.Errorf("OpenFile(%q; %q): %w", opth, pth, err)
|
||||
}
|
||||
return data, err
|
||||
},
|
||||
|
|
@ -156,18 +175,11 @@ func main() {
|
|||
return false
|
||||
}
|
||||
|
||||
dir = path.Clean(dir[5:])
|
||||
if dir == "." {
|
||||
dir = "/"
|
||||
}
|
||||
dir = path.Clean(dir[5:])[1:]
|
||||
|
||||
if !strings.HasSuffix(dir, "/") {
|
||||
dir += "/"
|
||||
}
|
||||
|
||||
_, ok := input.Files[dir]
|
||||
fmt.Printf("IsDir -> %q, %v\n", dir, ok)
|
||||
return ok
|
||||
contents, ok := files[dir]
|
||||
fmt.Printf("IsDir -> %q, %v, %v\n", dir, contents, ok)
|
||||
return ok && contents.File == ""
|
||||
},
|
||||
|
||||
HasSubdir: func(root, dir string) (rel string, ok bool) {
|
||||
|
|
@ -179,17 +191,21 @@ func main() {
|
|||
}
|
||||
|
||||
var filenames []string
|
||||
for dirname, files := range input.Files {
|
||||
for filename := range files {
|
||||
filenames = append(filenames, filepath.Join(dirname, filename))
|
||||
for _, filedata := range input.Files {
|
||||
if filedata[2] != "" {
|
||||
filenames = append(filenames, filepath.Join(filedata[0], filedata[1]))
|
||||
}
|
||||
}
|
||||
|
||||
files := make(map[string]Output)
|
||||
outfiles := make(map[string]Output)
|
||||
|
||||
for dir, filelist := range files {
|
||||
if filelist.File != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
for dir, filelist := range input.Files {
|
||||
isGo := false
|
||||
for file := range filelist {
|
||||
for _, file := range filelist.Directory {
|
||||
if strings.HasSuffix(file, ".go") {
|
||||
isGo = true
|
||||
break
|
||||
|
|
@ -203,13 +219,16 @@ func main() {
|
|||
}
|
||||
|
||||
base := path.Base(dir)
|
||||
if base == "." {
|
||||
base = ""
|
||||
}
|
||||
|
||||
if !isGo || strings.HasPrefix(base, "_") || strings.HasPrefix(base, ".") || base == "testdata" {
|
||||
fmt.Printf(" skipping (not go)\n")
|
||||
continue
|
||||
}
|
||||
|
||||
pkg, err := ctx.Import(".", path.Clean("/code"+dir), 0)
|
||||
pkg, err := ctx.Import(".", path.Clean("/code/"+dir), 0)
|
||||
if err != nil {
|
||||
if _, ok := err.(*build.NoGoError); ok {
|
||||
continue
|
||||
|
|
@ -267,13 +286,17 @@ func main() {
|
|||
sort.Strings(matchedFiles)
|
||||
var split [][]string
|
||||
for _, match := range matchedFiles {
|
||||
split = append(split, []string{match[len(dir):], filepath.Dir(match) + "/", filepath.Base(match)})
|
||||
dirname := filepath.Dir(match)
|
||||
if dirname == "." {
|
||||
dirname = ""
|
||||
}
|
||||
split = append(split, []string{match[len(dir)+1:], dirname, filepath.Base(match)})
|
||||
}
|
||||
|
||||
out.Embeds[pattern] = split
|
||||
}
|
||||
|
||||
files[dir] = out
|
||||
outfiles[dir] = out
|
||||
}
|
||||
|
||||
out, err := os.OpenFile(os.Getenv("out"), os.O_CREATE|os.O_RDWR, 0666)
|
||||
|
|
@ -281,7 +304,7 @@ func main() {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(out).Encode(files); err != nil {
|
||||
if err := json.NewEncoder(out).Encode(outfiles); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue