new: port the python template bodies to manifests
CI / build (push) Failing after 2m55s
CI / test (push) Skipped
CI / snap (push) Skipped

This commit is contained in:
2026-09-18 15:20:22 +02:00
parent fa399f64b2
commit 0235ec6457
5 changed files with 80 additions and 62 deletions
+10 -1
View File
@@ -356,7 +356,16 @@ static TEMPLATE_SOURCES: &[TemplateSources] = &[
TemplateSources {
id: TemplateId::PYTHON,
manifest: include_str!("../../../data/templates/python/manifest.yml"),
tpls: &[],
tpls: &[
(
"pyproject.toml.tpl",
include_str!("../../../data/templates/python/pyproject.toml.tpl"),
),
(
"__init__.py.tpl",
include_str!("../../../data/templates/python/__init__.py.tpl"),
),
],
hooks: Some(&python::HOOKS),
},
TemplateSources {
+38 -54
View File
@@ -4,18 +4,18 @@
//! …`) with a deliberately minimal line-oriented reader (see
//! [`read_pyproject`]) — pkh has no TOML dependency, and only a handful of
//! keys matter here. A bare `setup.py`/`setup.cfg` project falls back to
//! setuptools without the `pybuild-plugin-pyproject` helper. The manifest's
//! Build-Depends/architecture are the fresh-skeleton baseline the hooks
//! here resolve for an existing project (backend package, pyproject
//! presence, C-extension hints); the skeleton bodies stay in Rust until
//! they move into the manifest's `files:` list (the module name of
//! `[project.scripts]` is derived, not substituted).
//! setuptools without the `pybuild-plugin-pyproject` helper. The skeleton
//! bodies are manifest data (`data/templates/python/manifest.yml`),
//! named by the `{module_name}` placeholder this module derives from the
//! package name; the manifest's Build-Depends/architecture are the
//! fresh-skeleton baseline the hooks here resolve for an existing project
//! (backend package, pyproject presence, C-extension hints).
use std::path::Path;
use regex::Regex;
use super::{OutputFile, ProbeResult, TemplateHooks, source_dir_of};
use super::{ProbeResult, TemplateHooks, source_dir_of};
use crate::new::options::NewOptions;
/// The logic half of the python template.
@@ -122,46 +122,12 @@ fn c_extension_hints(opts: &NewOptions) -> bool {
}
impl TemplateHooks for Hooks {
/// A minimal setuptools-based `pyproject.toml` with one console script,
/// plus the one-module package providing it.
fn skeleton_files(&self, opts: &NewOptions) -> Vec<OutputFile> {
let module = module_name(opts);
vec![
OutputFile::new(
"pyproject.toml",
format!(
"[build-system]\n\
requires = [\"setuptools\"]\n\
build-backend = \"setuptools.build_meta\"\n\
\n\
[project]\n\
name = \"{name}\"\n\
version = \"{version}\"\n\
description = \"{summary}\"\n\
requires-python = \">=3.8\"\n\
\n\
[project.scripts]\n\
{command} = \"{module}:main\"\n",
name = opts.name,
version = opts.upstream_version,
summary = opts.summary,
command = opts.command,
module = module,
),
),
OutputFile::new(
format!("{module}/__init__.py"),
format!(
"\"\"\"Placeholder for {name}, generated by `pkh new`.\"\"\"\n\
\n\
\n\
def main() -> None:\n\
\x20 print(\"Hello from {command}!\")\n",
name = opts.name,
command = opts.command,
),
),
]
/// The `{module_name}` value of the manifest's skeleton bodies (see
/// [`module_name`]): the derived Python identifier naming the skeleton
/// package directory and the console-script entry point of
/// `pyproject.toml`.
fn context(&self, opts: &NewOptions) -> Vec<(String, String)> {
vec![("module_name".to_string(), module_name(opts))]
}
/// Amend the manifest's Build-Depends (the fresh-skeleton baseline)
@@ -385,23 +351,41 @@ mod tests {
"dh $@ --with python3 --buildsystem=pybuild"
);
// Skeleton (manifest data): pyproject.toml + the module package,
// byte-exact.
let skeleton = template.skeleton(&o);
assert_eq!(skeleton.len(), 2);
let pyproject = skeleton
.iter()
.find(|f| f.path == "pyproject.toml")
.expect("pyproject skeleton");
assert!(
pyproject
.contents
.contains("build-backend = \"setuptools.build_meta\"")
assert_eq!(
pyproject.contents,
"[build-system]\n\
requires = [\"setuptools\"]\n\
build-backend = \"setuptools.build_meta\"\n\
\n\
[project]\n\
name = \"mytool\"\n\
version = \"0.1.0\"\n\
description = \"A tool\"\n\
requires-python = \">=3.8\"\n\
\n\
[project.scripts]\n\
mytool = \"mytool:main\"\n"
);
assert!(pyproject.contents.contains("name = \"mytool\""));
assert!(pyproject.contents.contains("mytool = \"mytool:main\""));
let module = skeleton
.iter()
.find(|f| f.path == "mytool/__init__.py")
.expect("module skeleton");
assert!(module.contents.contains("def main()"));
assert_eq!(
module.contents,
"\"\"\"Placeholder for mytool, generated by `pkh new`.\"\"\"\n\
\n\
\n\
def main() -> None:\n\
\x20 print(\"Hello from mytool!\")\n"
);
}
/// dpkg names may carry `+`/`.` and start with a digit — none of which a