Resolve canonical parties with campaign configuration
This commit is contained in:
93
internal/config/party_resolution.go
Normal file
93
internal/config/party_resolution.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/fileops"
|
||||
)
|
||||
|
||||
const maxPartyDocumentBytes = 8 << 20
|
||||
|
||||
func resolvePartyInput(input ResolvedInputFile) (ResolvedParty, error) {
|
||||
configuredPath := strings.TrimSpace(input.Path)
|
||||
if configuredPath == "" {
|
||||
return ResolvedParty{}, fmt.Errorf("party input path is required")
|
||||
}
|
||||
configPath := strings.TrimSpace(input.ConfigPath)
|
||||
if configPath == "" {
|
||||
return ResolvedParty{}, fmt.Errorf("party input %q has no declaring configuration path", configuredPath)
|
||||
}
|
||||
path := configuredPath
|
||||
if !filepath.IsAbs(path) {
|
||||
path = filepath.Join(filepath.Dir(configPath), path)
|
||||
}
|
||||
path = filepath.Clean(path)
|
||||
raw, err := fileops.ReadRegularFile(path, maxPartyDocumentBytes)
|
||||
if err != nil {
|
||||
return ResolvedParty{}, fmt.Errorf("read party input %q: %w", path, err)
|
||||
}
|
||||
document, err := ParseParty(raw)
|
||||
if err != nil {
|
||||
return ResolvedParty{}, fmt.Errorf("parse party input %q: %w", path, err)
|
||||
}
|
||||
resolved := ResolvedParty{
|
||||
Mode: document.Mode,
|
||||
Source: PartySource{
|
||||
Path: path,
|
||||
ConfigPath: configPath,
|
||||
Source: input.Source,
|
||||
},
|
||||
Canonical: document.Canonical,
|
||||
}
|
||||
if document.IsCanonical() {
|
||||
return resolved, nil
|
||||
}
|
||||
return resolveLegacyParty(resolved)
|
||||
}
|
||||
|
||||
func campaignPartyInput(campaignPath string, campaign *CampaignConfig) (ResolvedInputFile, error) {
|
||||
if campaign == nil {
|
||||
return ResolvedInputFile{}, fmt.Errorf("campaign config is required")
|
||||
}
|
||||
if strings.TrimSpace(campaign.Inputs.PartyFile) == "" {
|
||||
return ResolvedInputFile{}, fmt.Errorf("campaign.inputs.party_file is required")
|
||||
}
|
||||
return ResolvedInputFile{
|
||||
Path: campaign.Inputs.PartyFile,
|
||||
ConfigPath: campaignPath,
|
||||
Source: "campaign_config",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func resolveCampaignParty(campaignPath string, campaign *CampaignConfig) (ResolvedParty, error) {
|
||||
input, err := campaignPartyInput(campaignPath, campaign)
|
||||
if err != nil {
|
||||
return ResolvedParty{}, err
|
||||
}
|
||||
return resolvePartyInput(input)
|
||||
}
|
||||
|
||||
func validateCanonicalPartySelection(campaign *CampaignConfig, session *SessionConfig) error {
|
||||
if campaign == nil {
|
||||
return fmt.Errorf("campaign config is required")
|
||||
}
|
||||
if strings.TrimSpace(campaign.Inputs.PlayersFile) != "" {
|
||||
return fmt.Errorf("campaign.inputs.players_file is not allowed with a canonical party")
|
||||
}
|
||||
if session == nil {
|
||||
return nil
|
||||
}
|
||||
if strings.TrimSpace(session.Inputs.PlayersFile) != "" {
|
||||
return fmt.Errorf("session.inputs.players_file is not allowed with a canonical party")
|
||||
}
|
||||
if strings.TrimSpace(session.Inputs.PartyFile) != "" {
|
||||
return fmt.Errorf("session.inputs.party_file cannot override a canonical campaign party")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func virtualPlayersInput() ResolvedInputFile {
|
||||
return ResolvedInputFile{Source: "derived_from_party"}
|
||||
}
|
||||
Reference in New Issue
Block a user