Prepare optional spell catalog inputs
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/adapters/storage"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifactpolicy"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifacts"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/audio"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
||||
@@ -64,6 +65,7 @@ func (prepareStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*S
|
||||
glossaryInput := stableInputSource(env.Config.StableInputs.GlossaryFile, env.Config.Session.Inputs.GlossaryFile, sessionSrc)
|
||||
playersInput := stableInputSource(env.Config.StableInputs.PlayersFile, env.Config.Session.Inputs.PlayersFile, sessionSrc)
|
||||
partyInput := stableInputSource(env.Config.StableInputs.PartyFile, env.Config.Session.Inputs.PartyFile, sessionSrc)
|
||||
spellCatalogInput := stableInputSource(env.Config.StableInputs.SpellCatalogFile, env.Config.Session.Inputs.SpellCatalogFile, sessionSrc)
|
||||
|
||||
speakersSrc, err := resolveConfigRelativePath(speakersInput)
|
||||
if err != nil {
|
||||
@@ -85,6 +87,17 @@ func (prepareStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*S
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("prepare: party path: %w", err)
|
||||
}
|
||||
spellCatalogConfigured := strings.TrimSpace(spellCatalogInput.Path) != ""
|
||||
spellCatalogSrc := ""
|
||||
if spellCatalogConfigured {
|
||||
spellCatalogSrc, err = resolveConfigRelativePath(spellCatalogInput)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("prepare: spell catalog path: %w", err)
|
||||
}
|
||||
if err := requireRegularReadableFile(spellCatalogSrc, "spell catalog"); err != nil {
|
||||
return nil, fmt.Errorf("prepare: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, required := range []struct {
|
||||
path string
|
||||
@@ -106,7 +119,7 @@ func (prepareStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*S
|
||||
return nil, fmt.Errorf("prepare: resolve audio inputs: %w", err)
|
||||
}
|
||||
|
||||
inputs := make([]manifest.InputRecord, 0, 8+len(resolvedLocalAudio))
|
||||
inputs := make([]manifest.InputRecord, 0, 9+len(resolvedLocalAudio))
|
||||
registerInput := func(kind, path, checksum string) {
|
||||
inputs = append(inputs, manifest.InputRecord{Kind: kind, Path: path, Checksum: checksum})
|
||||
}
|
||||
@@ -155,18 +168,36 @@ func (prepareStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*S
|
||||
}
|
||||
registerInput("pipeline_resolved", pipelineDst, pipelineChecksum)
|
||||
|
||||
for _, cfgFile := range []struct {
|
||||
type preparedConfigFile struct {
|
||||
kind string
|
||||
src string
|
||||
dst string
|
||||
source string
|
||||
}{
|
||||
}
|
||||
preparedConfigFiles := []preparedConfigFile{
|
||||
{kind: "speakers", src: speakersSrc, dst: filepath.Join(paths.InputsDir, "speakers.yml"), source: speakersInput.Source},
|
||||
{kind: "autocorrect", src: autocorrectSrc, dst: filepath.Join(paths.InputsDir, "autocorrect.yml"), source: autocorrectInput.Source},
|
||||
{kind: "glossary", src: glossarySrc, dst: filepath.Join(paths.InputsDir, "glossary.yml"), source: glossaryInput.Source},
|
||||
{kind: "players", src: playersSrc, dst: filepath.Join(paths.InputsDir, "players.yml"), source: playersInput.Source},
|
||||
{kind: "party", src: partySrc, dst: filepath.Join(paths.InputsDir, "party.yml"), source: partyInput.Source},
|
||||
} {
|
||||
}
|
||||
spellDescriptor, ok := artifactpolicy.DescribePreparedInputSource(artifactpolicy.SourceInputSpellCatalog)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("prepare: spell catalog prepared-input descriptor is unavailable")
|
||||
}
|
||||
spellCatalogDst := filepath.Join(paths.InputsDir, spellDescriptor.Filename)
|
||||
if spellCatalogConfigured {
|
||||
preparedConfigFiles = append(preparedConfigFiles, preparedConfigFile{
|
||||
kind: spellDescriptor.ManifestKind,
|
||||
src: spellCatalogSrc,
|
||||
dst: spellCatalogDst,
|
||||
source: spellCatalogInput.Source,
|
||||
})
|
||||
} else if err := fileops.RemoveFileUnderRoot(paths.Root, spellCatalogDst); err != nil {
|
||||
return nil, fmt.Errorf("prepare: remove obsolete spell catalog: %w", err)
|
||||
}
|
||||
|
||||
for _, cfgFile := range preparedConfigFiles {
|
||||
checksum, err := copyFileIfChanged(env.ArtifactStore, cfgFile.src, cfgFile.dst)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("prepare: materialize %s: %w", cfgFile.kind, err)
|
||||
@@ -585,6 +616,28 @@ func requireFile(path string, label string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func requireRegularReadableFile(path string, label string) error {
|
||||
if strings.TrimSpace(path) == "" {
|
||||
return fmt.Errorf("%s path is required", label)
|
||||
}
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("open %s %q: %w", label, path, err)
|
||||
}
|
||||
info, statErr := file.Stat()
|
||||
closeErr := file.Close()
|
||||
if statErr != nil {
|
||||
return fmt.Errorf("stat %s %q: %w", label, path, statErr)
|
||||
}
|
||||
if !info.Mode().IsRegular() {
|
||||
return fmt.Errorf("%s %q is not a regular file", label, path)
|
||||
}
|
||||
if closeErr != nil {
|
||||
return fmt.Errorf("close %s %q: %w", label, path, closeErr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isFlac(path string) bool {
|
||||
return strings.EqualFold(filepath.Ext(path), ".flac")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user