Skip to content

fix: align output path pattern resolution with documented behavior#2473

Open
Myriad-Dreamin wants to merge 4 commits intomainfrom
fix-output-path-pattern-regressions
Open

fix: align output path pattern resolution with documented behavior#2473
Myriad-Dreamin wants to merge 4 commits intomainfrom
fix-output-path-pattern-regressions

Conversation

@Myriad-Dreamin
Copy link
Copy Markdown
Owner

Closes #2400.

Summary

  • preserve multi-dot source stems and README-like names when applying export extensions
  • keep explicit $dir/$name outputs for workspace-root files inside the workspace instead of resolving to /...
  • make an empty tinymist.outputPath resolve like the documented default $root/$dir/$name

Testing

  • cargo fmt --check --all
  • cargo test -p tinymist-task --features no-content-hint test_substitute_path -- --nocapture
  • cargo test -p tinymist-task --features no-content-hint primitives::tests::test_substitute_default_path_matches_documented_behavior -- --exact --nocapture
  • cargo test -p tinymist --no-default-features --features export,system,no-content-hint task::export::tests::test_prepare_output_path_preserves_multi_dot_pdf_names -- --exact --nocapture
  • cargo test -p tinymist --no-default-features --features export,system,no-content-hint task::export::tests::test_prepare_output_path_explicit_dir_name_matches_default -- --exact --nocapture

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes Tinymist export output-path pattern resolution to match documented behavior, addressing regressions around multi-dot filenames and workspace-root exports.

Changes:

  • Adjust PathPattern substitution so empty tinymist.outputPath resolves like the documented default and $dir doesn’t accidentally become filesystem-rooted for workspace-root files.
  • Update export path preparation to resolve relative output paths against the workspace root and preserve multi-dot stems when applying artifact extensions.
  • Add regression tests and an OpenSpec requirements spec capturing the expected semantics.

Reviewed changes

Copilot reviewed 4 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
openspec/specs/output-path-patterns/spec.md Adds a spec for output-path pattern semantics and regression scenarios.
openspec/changes/archive/2026-04-04-fix-output-path-pattern-regressions/tasks.md Marks the spec-driven change tasks as completed.
openspec/changes/archive/2026-04-04-fix-output-path-pattern-regressions/specs/output-path-patterns/spec.md Archives the added output-path pattern requirements for the change record.
openspec/changes/archive/2026-04-04-fix-output-path-pattern-regressions/README.md Summarizes the archived change for issue #2400.
openspec/changes/archive/2026-04-04-fix-output-path-pattern-regressions/proposal.md Provides rationale and intended behavior changes for the regression fix.
openspec/changes/archive/2026-04-04-fix-output-path-pattern-regressions/.openspec.yaml Adds OpenSpec metadata for the archived change.
crates/tinymist/src/task/export.rs Changes how export output paths are rooted and how extensions are applied; adds export-path regression tests.
crates/tinymist-task/src/primitives.rs Fixes $dir substitution and empty-pattern default resolution; adds substitution regression tests.

Comment on lines +385 to +399
let write_to = Self::append_extension(write_to, task.extension());

Ok(Some(write_to))
}

fn append_extension(path: PathBuf, extension: &str) -> PathBuf {
let Some(file_name) = path.file_name() else {
return path.with_file_name(format!("main.{extension}"));
};

let mut file_name = file_name.to_os_string();
file_name.push(".");
file_name.push(extension);
path.with_file_name(file_name)
}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

append_extension always appends .{extension} to the existing filename, which can produce duplicated extensions (e.g. an outputPath pattern like $root/$dir/$name.pdf or a page_number_template that already includes .png will become ...pdf.pdf / ...png.png). This is a behavior change from the previous with_extension semantics and is likely to break existing configurations. Consider detecting an existing matching extension and avoiding re-appending (and/or normalizing the filename before applying the artifact extension).

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +2
## ADDED Requirements

Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This spec file under openspec/specs/ uses the archive-style heading ## ADDED Requirements and lacks the standard # <name> Specification title + ## Purpose section used by other specs in this directory (e.g. openspec/specs/math-module-field-completion/spec.md). To keep the specs consistent and discoverable, please reformat this file to follow the established spec template (title, purpose, then requirements).

Suggested change
## ADDED Requirements
# Output Path Patterns Specification
## Purpose
Define how Tinymist resolves output path pattern variables in `tinymist.outputPath`, with particular focus on preserving the full `$name` source stem, handling empty `$dir` values as workspace-relative paths, and ensuring that explicit `$dir/$name` output patterns match the default export location.
## Requirements

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression: tinymist.outputPath doing unexpected things in 0.14.2 and newer

2 participants