1+ #!/usr/bin/env python
2+ """Post-generation script for cookiecutter."""
3+
4+ import os
5+ import datetime
6+
7+ license_type = "{{cookiecutter.license}}"
8+ author = "{{cookiecutter.author_name}}"
9+ year = datetime .datetime .now ().year
10+
11+
12+ def generate_mit_license ():
13+ """Generate MIT license file."""
14+ mit_license = f"""MIT License
15+
16+ Copyright (c) { year } { author }
17+
18+ Permission is hereby granted, free of charge, to any person obtaining a copy
19+ of this software and associated documentation files (the "Software"), to deal
20+ in the Software without restriction, including without limitation the rights
21+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22+ copies of the Software, and to permit persons to whom the Software is
23+ furnished to do so, subject to the following conditions:
24+
25+ The above copyright notice and this permission notice shall be included in all
26+ copies or substantial portions of the Software.
27+
28+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34+ SOFTWARE.
35+ """
36+ with open ("LICENSE" , "w" ) as f :
37+ f .write (mit_license )
38+
39+
40+ def generate_bsd3_license ():
41+ """Generate BSD-3 license file."""
42+ bsd3_license = f"""BSD 3-Clause License
43+
44+ Copyright (c) { year } , { author }
45+ All rights reserved.
46+
47+ Redistribution and use in source and binary forms, with or without
48+ modification, are permitted provided that the following conditions are met:
49+
50+ 1. Redistributions of source code must retain the above copyright notice, this
51+ list of conditions and the following disclaimer.
52+
53+ 2. Redistributions in binary form must reproduce the above copyright notice,
54+ this list of conditions and the following disclaimer in the documentation
55+ and/or other materials provided with the distribution.
56+
57+ 3. Neither the name of the copyright holder nor the names of its
58+ contributors may be used to endorse or promote products derived from
59+ this software without specific prior written permission.
60+
61+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
62+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
65+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
67+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
68+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
69+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
70+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71+ """
72+ with open ("LICENSE" , "w" ) as f :
73+ f .write (bsd3_license )
74+
75+
76+ def generate_gpl3_license ():
77+ """Generate GPL-3.0 license file."""
78+ # This would be the full GPL-3.0 license, but it's very long
79+ # Here we'll just write a reference to the standard license
80+ gpl3_license = f"""Copyright (C) { year } { author }
81+
82+ This program is free software: you can redistribute it and/or modify
83+ it under the terms of the GNU General Public License as published by
84+ the Free Software Foundation, either version 3 of the License, or
85+ (at your option) any later version.
86+
87+ This program is distributed in the hope that it will be useful,
88+ but WITHOUT ANY WARRANTY; without even the implied warranty of
89+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
90+ GNU General Public License for more details.
91+
92+ You should have received a copy of the GNU General Public License
93+ along with this program. If not, see <https://www.gnu.org/licenses/>.
94+ """
95+ with open ("LICENSE" , "w" ) as f :
96+ f .write (gpl3_license )
97+
98+
99+ def generate_apache2_license ():
100+ """Generate Apache-2.0 license file."""
101+ apache2_license = f""" Apache License
102+ Version 2.0, January 2004
103+ http://www.apache.org/licenses/
104+
105+ Copyright { year } { author }
106+
107+ Licensed under the Apache License, Version 2.0 (the "License");
108+ you may not use this file except in compliance with the License.
109+ You may obtain a copy of the License at
110+
111+ http://www.apache.org/licenses/LICENSE-2.0
112+
113+ Unless required by applicable law or agreed to in writing, software
114+ distributed under the License is distributed on an "AS IS" BASIS,
115+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
116+ See the License for the specific language governing permissions and
117+ limitations under the License.
118+ """
119+ with open ("LICENSE" , "w" ) as f :
120+ f .write (apache2_license )
121+
122+
123+ if __name__ == "__main__" :
124+ if license_type == "MIT" :
125+ generate_mit_license ()
126+ elif license_type == "BSD-3" :
127+ generate_bsd3_license ()
128+ elif license_type == "GPL-3.0" :
129+ generate_gpl3_license ()
130+ elif license_type == "Apache-2.0" :
131+ generate_apache2_license ()
132+ else :
133+ print (f"Unsupported license type: { license_type } " )
134+
135+ # Create test directory if tests are included
136+ if "{{cookiecutter.include_tests}}" == "y" :
137+ if not os .path .exists ("tests" ):
138+ os .makedirs ("tests" )
139+ with open ("tests/__init__.py" , "w" ) as f :
140+ f .write ("""Test package for {{cookiecutter.package_name}}.""" )
141+
142+ # Create a basic test file
143+ with open ("tests/test_cli.py" , "w" ) as f :
144+ f .write ("""#!/usr/bin/env python
145+ """ Test CLI for {{cookiecutter .package_name }}."""
146+
147+ from __future__ import annotations
148+
149+ import os
150+ import pathlib
151+ import subprocess
152+ import sys
153+
154+ import pytest
155+
156+ import {{cookiecutter.package_name}}
157+
158+
159+ def test_run():
160+ """ Test run ."""
161+ # Test that the function doesn't error
162+ proc = {{cookiecutter.package_name}}.run(cmd="echo", cmd_args=["hello"])
163+ assert proc is None
164+
165+ # Test when G_IS_TEST is set, it returns the proc
166+ os.environ["{{cookiecutter.package_name.upper()}}_IS_TEST"] = "1"
167+ proc = {{cookiecutter.package_name}}.run(cmd="echo", cmd_args=["hello"])
168+ assert isinstance(proc, subprocess.Popen)
169+ assert proc.returncode == 0
170+ del os.environ["{{cookiecutter.package_name.upper()}}_IS_TEST"]
171+ """ )
172+
173+ # Create docs directory if docs are included
174+ if "{{cookiecutter.include_docs}}" == "y" :
175+ if not os .path .exists ("docs" ):
176+ os .makedirs ("docs" )
177+ with open ("docs/index.md" , "w" ) as f :
178+ f .write ("""# {{cookiecutter.project_name}}
179+
180+ {{cookiecutter.project_description}}
181+
182+ ## Installation
183+
184+ ```bash
185+ pip install {{cookiecutter.package_name}}
186+ ```
187+
188+ ## Usage
189+
190+ ```bash
191+ {{cookiecutter.package_name}}
192+ ```
193+
194+ This will detect the type of repository in your current directory and run the appropriate VCS command.
195+ """ )
196+
197+ # Create GitHub Actions workflows if included
198+ if "{{cookiecutter.include_github_actions}}" == "y" :
199+ if not os .path .exists (".github/workflows" ):
200+ os .makedirs (".github/workflows" )
201+ with open (".github/workflows/tests.yml" , "w" ) as f :
202+ f .write ("""name: tests
203+
204+ on:
205+ push:
206+ branches: [main]
207+ pull_request:
208+ branches: [main]
209+
210+ jobs:
211+ build:
212+ runs-on: ubuntu-latest
213+ strategy:
214+ matrix:
215+ python-version: ['3.9', '3.10', '3.11']
216+
217+ steps:
218+ - uses: actions/checkout@v3
219+ - name: Set up Python ${{ matrix.python-version }}
220+ uses: actions/setup-python@v4
221+ with:
222+ python-version: ${{ matrix.python-version }}
223+ - name: Install dependencies
224+ run: |
225+ python -m pip install --upgrade pip
226+ pip install uv
227+ uv pip install -e .
228+ uv pip install pytest pytest-cov
229+ - name: Test with pytest
230+ run: |
231+ uv pip install pytest
232+ pytest
233+ """ )
234+
235+ print ("Project generated successfully!" )
0 commit comments