a82bdf4734
Every generated source file, README.md and .gitignore now comes from a template that a file of the same name can replace: - <project>/.canon/templates/ for that project, which wins over - ~/.config/canon/templates/ ($XDG_CONFIG_HOME respected) for all projects; canon new reads only these canon templates lists each template, where it comes from and the placeholders it can use. canon templates export [<file>...] [--user] copies built-in texts as a starting point and never overwrites. Overrides are checked strictly: an unknown file name or a placeholder the template does not provide is an error naming the file; hidden files are ignored. Generators take a template_set, so they stay pure. Also: - executor: a symlink to a directory counts as a directory (macOS /var, linked config directories) - plan: add_directory stops at the filesystem root - project: find_project_root, shared by load_project and templates - tests: a templates scenario; scenarios run canon with their own empty XDG_CONFIG_HOME so personal templates cannot affect results Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
25 lines
822 B
C++
25 lines
822 B
C++
#pragma once
|
|
|
|
#include <expected>
|
|
#include <functional>
|
|
#include <map>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
namespace canon {
|
|
|
|
using template_vars = std::map<std::string, std::string, std::less<>>;
|
|
|
|
// Replaces every {{key}} in text with vars[key].
|
|
// Throws std::invalid_argument for an unknown key or an unterminated placeholder.
|
|
// Check user-supplied text with placeholders() first; for built-in templates
|
|
// either failure is a bug that tests should catch.
|
|
[[nodiscard]] std::string render(std::string_view text, const template_vars& vars);
|
|
|
|
// The key of every {{key}} in text, in order of appearance, or why the text
|
|
// cannot be rendered (an unclosed placeholder).
|
|
[[nodiscard]] std::expected<std::vector<std::string>, std::string> placeholders(std::string_view text);
|
|
|
|
} // namespace canon
|