forked from pawamoy/copier-uv
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcopier.yml
More file actions
248 lines (221 loc) · 9.28 KB
/
copier.yml
File metadata and controls
248 lines (221 loc) · 9.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# CONFIGURATION -------------------------
_min_copier_version: "9.13"
_envops:
autoescape: false
keep_trailing_newline: true
_subdirectory: project
_templates_suffix: .jinja
_preserve_symlinks: true
_jinja_extensions:
- copier_template_extensions.TemplateExtensionLoader
- extensions.py:CurrentYearExtension
- extensions.py:GitExtension
- extensions.py:SlugifyExtension
# Files to skip if they already exist in the destination.
# NOTE: pyproject.toml and prek.toml are intentionally NOT here.
# During `copier adopt`, we want these to merge with conflict markers so users
# get template improvements (poe tasks, ruff config, hooks). During `copier update`,
# copier performs a 3-way merge that preserves user customizations.
# Files to skip on update: hand-edited (README/CHANGELOG/source) OR generated (uv.lock).
# uv.lock is regenerated by `uv sync` from pyproject.toml; the template ships one for
# its own dev env but it must never land in a user project — a stale lockfile clobbers
# the working one and trips uv on the next sync.
_skip_if_exists:
- CHANGELOG.md
- README.md
- "src/{{ python_package_import_name }}/__init__.py"
- "tests/__init__.py"
- "tests/test_{{ python_package_import_name }}.py"
- uv.lock
_exclude:
- "{% if repository_provider != 'github.com' %}.github{% endif %}"
- "{% if repository_provider != 'gitlab.com' %}.gitlab-ci.yml{% endif %}"
- "{% if not use_ci %}.github/workflows/ci.yml{% endif %}"
- "{% if not use_ci %}.github/workflows/copier-update.yml{% endif %}"
- "{% if not use_ci %}.gitlab-ci.yml{% endif %}"
- "{% if not use_docs %}.github/workflows/docs.yml{% endif %}"
- "{% if not use_docs %}zensical.toml{% endif %}"
- "{% if not use_docs %}docs{% endif %}"
- "{% if not use_semantic_release %}.github/workflows/release.yml{% endif %}"
- "{% if not publish_to_mcp_registry %}.github/workflows/mcp-registry-publish.yml{% endif %}"
- "{% if not use_blacksmith_runners %}.github/actionlint.yaml{% endif %}"
- "{% if project_visibility == 'internal' %}CODE_OF_CONDUCT.md{% endif %}"
- "{% if project_visibility == 'internal' %}CONTRIBUTING.md{% endif %}"
- "{% if project_visibility == 'internal' %}SECURITY.md{% endif %}"
- "{% if project_visibility == 'internal' %}LICENSE{% endif %}"
- "{% if project_visibility == 'internal' %}docs/code_of_conduct.md{% endif %}"
- "{% if project_visibility == 'internal' %}docs/contributing.md{% endif %}"
- "{% if project_visibility == 'internal' %}docs/license.md{% endif %}"
- "{% if project_visibility == 'internal' %}.github/FUNDING.yml{% endif %}"
# PROMPT --------------------------------
project_name:
type: str
help: Your project name
project_description:
type: str
help: Your project description
project_type:
type: str
help: What type of project is this?
default: app
choices:
Application (with CLI entry point — uv init --app): app
Library (importable package, no CLI — uv init --lib): lib
project_visibility:
type: str
help: "Project visibility (public = open-source scaffolding, internal = skip community files)"
default: public
choices:
Public (open-source with LICENSE, CoC, CONTRIBUTING, SECURITY): public
Internal (company/private — skip open-source scaffolding): internal
author_fullname:
type: str
help: Your full name
default: "{{ git_user_name }}"
author_email:
type: str
help: Your email
default: "{{ git_user_email }}"
author_username:
type: str
help: Your username (e.g. on GitHub)
default: "{{ git_user_username }}"
repository_provider:
type: str
help: Your repository hosting platform
default: github.com
choices:
- github.com
- gitlab.com
repository_host:
type: str
help: "Repository hostname (e.g. gitlab.company.com for self-hosted)"
default: "{{ repository_provider }}"
repository_namespace:
type: str
help: Your repository namespace (username or organization)
default: "{{ author_username }}"
repository_name:
type: str
help: Your repository name
default: "{{ project_name | slugify }}"
when: false
copyright_license:
type: str
help: Your project's license
default: ISC
when: "{{ project_visibility == 'public' }}"
choices:
Academic Free License v3.0: AFL-3.0
Apache License 2.0: Apache-2.0
Artistic License 2.0: Artistic-2.0
BSD 2-Clause "Simplified" License: BSD-2-Clause
BSD 3-Clause Clear License: BSD-3-Clause-Clear
BSD 3-Clause "New" or "Revised" License: BSD-3-Clause
Boost Software License 1.0: BSL-1.0
Creative Commons Attribution 4.0 International: CC-BY-4.0
Creative Commons Attribution Share Alike 4.0 International: CC-BY-SA-4.0
Creative Commons Zero v1.0 Universal: CC0-1.0
Do What The F*ck You Want To Public License: WTFPL
Educational Community License v2.0: ECL-2.0
Eclipse Public License 1.0: EPL-1.0
Eclipse Public License 2.0: EPL-2.0
European Union Public License 1.1: EUPL-1.1
European Union Public License 1.2: EUPL-1.2
GNU Affero General Public License v3.0: AGPL-3.0
GNU General Public License v2.0 only: GPL-2.0
GNU General Public License v3.0 only: GPL-3.0
GNU Lesser General Public License v2.1 only: LGPL-2.1
GNU Lesser General Public License v3.0 only: LGPL-3.0
ISC License: ISC
LaTeX Project Public License v1.3c: LPPL-1.3c
MIT License: MIT
Mozilla Public License 2.0: MPL-2.0
Microsoft Public License: MS-PL
Microsoft Reciprocal License: MS-RL
University of Illinois/NCSA Open Source License: NCSA
SIL Open Font License 1.1: OFL-1.1
Open Software License 3.0: OSL-3.0
PostgreSQL License: PostgreSQL
The Unlicense: Unlicense
zlib License: Zlib
python_package_distribution_name:
type: str
help: Your Python package distribution name (for `pip install NAME`)
default: "{{ project_name | slugify }}"
when: false
python_package_import_name:
type: str
help: Your Python package import name (for `import NAME` in Python code)
default: "{{ project_name | slugify('_') }}"
when: false
python_package_command_line_name:
type: str
help: Your CLI name if any (for use in the shell)
default: "{{ project_name | slugify }}"
when: false
use_docs:
type: bool
help: "Generate docs site scaffolding? (zensical, docs/, GitHub Pages workflow)"
default: true
use_ci:
type: bool
help: "Enable CI workflow? (testing, linting, type checking)"
default: "{{ project_visibility == 'public' }}"
use_semantic_release:
type: bool
help: "Enable semantic-release workflow? (automated versioning, changelog, releases)"
default: "{{ use_ci }}"
when: "{{ use_ci }}"
publish_to_pypi:
type: bool
help: Will you publish this package to PyPI?
default: "{{ use_semantic_release and project_visibility == 'public' }}"
when: "{{ use_semantic_release }}"
publish_to_mcp_registry:
type: bool
help: Will you publish this server to the MCP Registry?
default: false
when: "{{ use_semantic_release }}"
use_custom_pypi_index:
type: bool
help: "Use a custom/private PyPI index? (Artifactory, Nexus, etc.)"
default: false
custom_pypi_index_url:
type: str
help: "Custom PyPI index URL"
default: ""
when: "{{ use_custom_pypi_index }}"
use_blacksmith_runners:
type: bool
help: Use Blacksmith.sh runners? (2x faster, 75% more cost-efficient than GitHub-hosted)
default: "{{ use_ci and repository_provider == 'github.com' }}"
when: "{{ use_ci and repository_provider == 'github.com' }}"
configure_repo_settings:
type: bool
help: "Configure GitHub repo settings on copy/update? (delete-branch-on-merge, enable-auto-merge — runs `gh repo edit`)"
default: true
when: "{{ repository_provider == 'github.com' }}"
# TASKS --------------------------------
_tasks:
# Always run
- "chmod +x scripts/*.sh scripts/*.py 2>/dev/null || true"
# Sync deps in the real destination only. On `copier update` copier renders the OLD and
# NEW template versions into temp dirs (copier._main.{old,new}_copy.*) AND merges into
# the actual project; tasks fire in all three. Guarding on .git skips the temp dirs
# (they have no .git) so sync runs once instead of three times. `copy` operations are a
# single render so we run unconditionally there.
- "if [ \"{{ _copier_operation }}\" = \"copy\" ] || [ -d .git ]; then uv sync --upgrade; fi"
# Update only — reinstall hooks (fresh copy has no .git yet)
- command: "if [ -d .git ]; then uv run prek install; fi"
when: "{{ _copier_operation in ('update', 'recopy') }}"
# GitHub repo settings — idempotent, runs on copy and update
- command: "command -v gh >/dev/null && gh repo view --json nameWithOwner -q .nameWithOwner >/dev/null 2>&1 && gh repo edit --delete-branch-on-merge --enable-auto-merge && echo '✓ Enabled delete-branch-on-merge and auto-merge' || true"
when: "{{ configure_repo_settings | default(false) }}"
# Copy — setup instructions
- command: "printf '\\n🎉 Project created!\\n\\n ✓ Dependencies installed\\n\\nTo finish setup:\\n git init && uv run prek install && bash scripts/prek-autoupdate.sh\\n Create your source files in src/ and tests/\\n'"
when: "{{ _copier_operation == 'copy' }}"
# Update — minimal output (poe update-template handles prek autoupdate).
# Same .git guard as uv sync above: skip the temp-dir renders so the 🎉 only prints once.
- command: "if [ -d .git ]; then printf '\\n🎉 Template updated!\\n\\n ✓ Dependencies synced\\n ✓ Git hooks reinstalled\\n'; fi"
when: "{{ _copier_operation in ('update', 'recopy') }}"