Apply configured output directories

This commit is contained in:
2026-08-02 01:38:06 +00:00
parent 0c4c575eea
commit 2af6a5cfd2
4 changed files with 327 additions and 103 deletions

View File

@@ -4,9 +4,7 @@ package app
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"time"
distributoradapter "gitea.maximumdirect.net/eric/weatherreporter/internal/adapters/distributor"
@@ -251,7 +249,7 @@ func GenerateDetailed(ctx context.Context, req GenerateRequest) (*ReportResult,
return nil, err
}
result := initialReportResult(req, resolved, PromptInspectionResult{})
outputPath, err := resolveReportOutputPath(req.WorkingDir, req.OutputPath, resolved)
outputPath, err := resolveReportOutputPath(req.WorkingDir, req.OutputPath, req.Config.Output.Directory, resolved)
if err != nil {
return result, err
}
@@ -302,7 +300,7 @@ func RunBatchDetailed(ctx context.Context, req BatchRequest) (*BatchResult, erro
if _, err := report.BatchForCommandName(string(req.Batch)); err != nil {
return nil, err
}
outputDir, err := resolveOutputDir(req.WorkingDir, req.OutputDir)
outputDir, err := resolveOutputDirWithConfigured(req.WorkingDir, req.OutputDir, req.Config.Output.Directory)
if err != nil {
return nil, err
}
@@ -431,104 +429,6 @@ func batchReportResult(planned plannedBatchReport) BatchReportResult {
}
}
func plannedBatchOutputPath(outputDir string, planned plannedBatchReport) (string, error) {
outputName, err := planned.Resolved.OutputName()
if err != nil {
return "", err
}
return validateOutputPath(filepath.Join(outputDir, outputName))
}
func prepareBatchOutputs(outputDir string, plannedReports []plannedBatchReport) error {
for index := range plannedReports {
outputPath, err := plannedBatchOutputPath(outputDir, plannedReports[index])
if err != nil {
return err
}
plannedReports[index].OutputPath = outputPath
}
return nil
}
func resolveReportOutputPath(workingDir, override string, resolved report.Resolved) (string, error) {
outputName, err := resolved.OutputName()
if err != nil {
return "", err
}
return resolveOutputPath(workingDir, override, outputName)
}
func resolveOutputDir(workingDir, override string) (string, error) {
workingDir, err := validateWorkingDir(workingDir)
if err != nil {
return "", err
}
if override == "" {
return workingDir, nil
}
if strings.TrimSpace(override) == "" {
return "", fmt.Errorf("output directory is required")
}
directory := override
if !filepath.IsAbs(directory) {
directory = filepath.Join(workingDir, directory)
}
directory = filepath.Clean(directory)
if info, err := os.Stat(directory); err == nil && !info.IsDir() {
return "", fmt.Errorf("output directory %q is not a directory", directory)
} else if err != nil && !os.IsNotExist(err) {
return "", fmt.Errorf("inspect output directory %q: %w", directory, err)
}
return directory, nil
}
func resolveOutputPath(workingDir, override, defaultName string) (string, error) {
workingDir, err := validateWorkingDir(workingDir)
if err != nil {
return "", err
}
path := override
if path == "" {
path = defaultName
}
if strings.TrimSpace(path) == "" {
return "", fmt.Errorf("final output path is required")
}
if !filepath.IsAbs(path) {
path = filepath.Join(workingDir, path)
}
return validateOutputPath(path)
}
func validateWorkingDir(workingDir string) (string, error) {
if strings.TrimSpace(workingDir) == "" {
return "", fmt.Errorf("working directory is required")
}
if !filepath.IsAbs(workingDir) {
return "", fmt.Errorf("working directory %q must be absolute", workingDir)
}
return filepath.Clean(workingDir), nil
}
func validateOutputPath(path string) (string, error) {
if strings.TrimSpace(path) == "" {
return "", fmt.Errorf("final output path is required")
}
path = filepath.Clean(path)
if !filepath.IsAbs(path) {
return "", fmt.Errorf("final output path %q must be absolute", path)
}
if filepath.Dir(path) == path {
return "", fmt.Errorf("final output path %q must not be a filesystem root", path)
}
if info, err := os.Stat(path); err == nil && info.IsDir() {
return "", fmt.Errorf("final output path %q is a directory", path)
} else if err != nil && !os.IsNotExist(err) {
return "", fmt.Errorf("inspect final output path %q: %w", path, err)
}
return path, nil
}
func ResolveGenerate(req GenerateRequest, now time.Time) (report.Resolved, error) {
location, err := timeutil.LoadLocation(req.Config.WeatherAPI.Timezone)
if err != nil {