Update BuildAndPackage
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
package topdata
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.westgate.pw/ShadowsOverWestgate/sow-tools/internal/erf"
|
||||
"gitea.westgate.pw/ShadowsOverWestgate/sow-tools/internal/project"
|
||||
@@ -19,6 +22,17 @@ const (
|
||||
)
|
||||
|
||||
func BuildPackage(p *project.Project, progress func(string)) (PackageResult, error) {
|
||||
if progress == nil {
|
||||
progress = func(string) {}
|
||||
}
|
||||
nativeResult, err := packagedBuildResult(p)
|
||||
if err != nil {
|
||||
return PackageResult{}, err
|
||||
}
|
||||
return packageBuiltTopData(p, nativeResult, progress)
|
||||
}
|
||||
|
||||
func BuildAndPackage(p *project.Project, progress func(string)) (PackageResult, error) {
|
||||
if progress == nil {
|
||||
progress = func(string) {}
|
||||
}
|
||||
@@ -29,6 +43,13 @@ func BuildPackage(p *project.Project, progress func(string)) (PackageResult, err
|
||||
return packageBuiltTopData(p, nativeResult, progress)
|
||||
}
|
||||
|
||||
func BuildPackageFromBuild(p *project.Project, nativeResult BuildResult, progress func(string)) (PackageResult, error) {
|
||||
if progress == nil {
|
||||
progress = func(string) {}
|
||||
}
|
||||
return packageBuiltTopData(p, nativeResult, progress)
|
||||
}
|
||||
|
||||
func packageBuiltTopData(p *project.Project, nativeResult BuildResult, progress func(string)) (PackageResult, error) {
|
||||
if progress == nil {
|
||||
progress = func(string) {}
|
||||
@@ -207,3 +228,103 @@ func copyFile(dst, src string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func packagedBuildResult(p *project.Project) (BuildResult, error) {
|
||||
if !p.HasTopData() {
|
||||
return BuildResult{}, errors.New("topdata is not configured for this project")
|
||||
}
|
||||
|
||||
buildDir := p.TopDataBuildDir()
|
||||
output2DA := filepath.Join(buildDir, "2da")
|
||||
outputTLK := filepath.Join(buildDir, "tlk")
|
||||
if _, err := os.Stat(output2DA); err != nil {
|
||||
return BuildResult{}, fmt.Errorf("topdata build output missing: run build-topdata first")
|
||||
}
|
||||
if _, err := os.Stat(outputTLK); err != nil {
|
||||
return BuildResult{}, fmt.Errorf("topdata tlk output missing: run build-topdata first")
|
||||
}
|
||||
|
||||
files2DA, oldest2DA, err := countCompiledFiles(output2DA, ".2da")
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
filesTLK, oldestTLK, err := countCompiledFiles(outputTLK, ".tlk")
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
if files2DA == 0 {
|
||||
return BuildResult{}, fmt.Errorf("topdata build output missing: run build-topdata first")
|
||||
}
|
||||
if filesTLK != 1 {
|
||||
return BuildResult{}, fmt.Errorf("expected exactly 1 compiled tlk output, found %d", filesTLK)
|
||||
}
|
||||
|
||||
newestSource, newestPath, err := newestTopDataSource(p.TopDataSourceDir())
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
oldestBuild := oldest2DA
|
||||
if oldestBuild.IsZero() || (!oldestTLK.IsZero() && oldestTLK.Before(oldestBuild)) {
|
||||
oldestBuild = oldestTLK
|
||||
}
|
||||
if !newestSource.IsZero() && !oldestBuild.IsZero() && newestSource.After(oldestBuild) {
|
||||
return BuildResult{}, fmt.Errorf("topdata build output is older than source file %s; run build-topdata first", newestPath)
|
||||
}
|
||||
|
||||
return BuildResult{
|
||||
Mode: "native",
|
||||
Output2DADir: output2DA,
|
||||
OutputTLKDir: outputTLK,
|
||||
Files2DA: files2DA,
|
||||
FilesTLK: filesTLK,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func countCompiledFiles(dir, extension string) (int, time.Time, error) {
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return 0, time.Time{}, fmt.Errorf("read compiled output dir %s: %w", dir, err)
|
||||
}
|
||||
count := 0
|
||||
oldest := time.Time{}
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() || !strings.EqualFold(filepath.Ext(entry.Name()), extension) {
|
||||
continue
|
||||
}
|
||||
info, err := entry.Info()
|
||||
if err != nil {
|
||||
return 0, time.Time{}, fmt.Errorf("stat compiled output %s: %w", filepath.Join(dir, entry.Name()), err)
|
||||
}
|
||||
count++
|
||||
if oldest.IsZero() || info.ModTime().Before(oldest) {
|
||||
oldest = info.ModTime()
|
||||
}
|
||||
}
|
||||
return count, oldest, nil
|
||||
}
|
||||
|
||||
func newestTopDataSource(sourceDir string) (time.Time, string, error) {
|
||||
newest := time.Time{}
|
||||
newestPath := ""
|
||||
err := filepath.WalkDir(sourceDir, func(path string, d fs.DirEntry, walkErr error) error {
|
||||
if walkErr != nil {
|
||||
return walkErr
|
||||
}
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
info, err := d.Info()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if newest.IsZero() || info.ModTime().After(newest) {
|
||||
newest = info.ModTime()
|
||||
newestPath = path
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return time.Time{}, "", fmt.Errorf("scan topdata sources: %w", err)
|
||||
}
|
||||
return newest, newestPath, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user