Skip to content

Commit 2c849a9

Browse files
committed
Structure of the Repository
1 parent 2b44ee3 commit 2c849a9

File tree

1 file changed

+291
-2
lines changed

1 file changed

+291
-2
lines changed

docs/writing/structure.rst

Lines changed: 291 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,297 @@ project. We then discuss various perspectives on how to build code which
1919
can be extended and tested reliably.
2020

2121

22-
Structure is Key
23-
----------------
22+
23+
Structure of the Repository
24+
---------------------------
25+
26+
It's Important.
27+
:::::::::::::::
28+
29+
Just as Code Style, API Design, and Automation are essential for a
30+
healthy development cycle, Repository structure is a crucial part of
31+
your project's
32+
`architecture <http://www.amazon.com/gp/product/1257638017/ref=as_li_ss_tl?ie=UTF8&tag=bookforkind-20&linkCode=as2&camp=1789&creative=39095&creativeASIN=1257638017>`__.
33+
34+
When a potential user or contributor lands on your repository's page,
35+
they see a few things:
36+
37+
- Project Name
38+
- Project Description
39+
- Bunch O' Files
40+
41+
Only when they scroll below the fold will the user see your project's
42+
README.
43+
44+
If your repo is a massive dump of files or a nested mess of directories,
45+
they might look elsewhere before even reading your beautiful
46+
documentation.
47+
48+
Dress for the job you want, not the job you have.
49+
50+
Of course, first impressions aren't everything. You and your colleagues
51+
will spend countless hours working with this repository, eventually
52+
becoming intimately familiar with every nook and cranny. The layout of
53+
it is important.
54+
55+
Sample Repository
56+
:::::::::::::::::
57+
58+
**tl;dr**: This is what `Kenneth Reitz <http://kennethreitz.org>`_ recommends.
59+
60+
This repository is `available on
61+
GitHub <https://github.com/kennethreitz/samplemod>`__.
62+
63+
::
64+
65+
README.rst
66+
LICENSE
67+
setup.py
68+
requirements.txt
69+
sample/__init__.py
70+
sample/core.py
71+
sample/helpers.py
72+
docs/conf.py
73+
docs/index.rst
74+
tests/test_basic.py
75+
tests/test_advanced.py
76+
77+
Let's get into some specifics.
78+
79+
The Actual Module
80+
:::::::::::::::::
81+
82+
.. csv-table::
83+
:widths: 20, 40
84+
85+
"Location", "``./sample/`` or ``./sample.py``"
86+
"Purpose", "The code of interest"
87+
88+
89+
Your module package is the core focus of the repository. It should not
90+
be tucked away:
91+
92+
::
93+
94+
./sample/
95+
96+
If your module consists of only a single file, you can place it directly
97+
in the root of your repository:
98+
99+
::
100+
101+
./sample.py
102+
103+
Your library does not belong in an ambiguous src or python subdirectory.
104+
105+
License
106+
:::::::
107+
108+
109+
.. csv-table::
110+
:widths: 20, 40
111+
112+
"Location", "``./LICENSE``"
113+
"Purpose", "Lawyering up."
114+
115+
116+
This is arguably the most important part of your repository, aside from
117+
the source code itself. The full license text and copyright claims
118+
should exist in this file.
119+
120+
If you aren't sure which license you should use for your project, check
121+
out `choosealicense.com <http://choosealicense.com>`_.
122+
123+
Of course, you are also free to publish code without a license, but this
124+
would prevent many people from potentially using your code.
125+
126+
Setup.py
127+
::::::::
128+
129+
.. csv-table::
130+
:widths: 20, 40
131+
132+
"Location", "``./setup.py``"
133+
"Purpose", "Package and distribution management."
134+
135+
136+
If your module package is at the root of your repository, this should
137+
obviously be at the root as well.
138+
139+
Requirements File
140+
:::::::::::::::::
141+
142+
.. csv-table::
143+
:widths: 20, 40
144+
145+
"Location", "``./requirements.txt``"
146+
"Purpose", "Development dependencies."
147+
148+
149+
A `pip requirements
150+
file <http://www.pip-installer.org/en/latest/requirements.html>`__
151+
should be placed at the root of the repository. It should specify the
152+
dependencies required to contribute to the project: testing, building,
153+
and generating documentation.
154+
155+
If your project has no development dependencies, or you prefer
156+
development environment setup via ``setup.py``, this file may be
157+
unnecessary.
158+
159+
Documentation
160+
:::::::::::::
161+
162+
163+
.. csv-table::
164+
:widths: 20, 40
165+
166+
"Location", "``./docs/``"
167+
"Purpose", "Package reference documentation."
168+
169+
There is little reason for this to exist elsewhere.
170+
171+
Test Suite
172+
::::::::::
173+
174+
175+
.. csv-table::
176+
:widths: 20, 40
177+
178+
"Location", "``./test_sample.py`` or ``./tests``"
179+
"Purpose", "Package integration and unit tests."
180+
181+
Starting out, a small test suite will often exist in a single file:
182+
183+
::
184+
185+
./test_sample.py
186+
187+
Once a test suite grows, you can move your tests to a directory, like
188+
so:
189+
190+
::
191+
192+
tests/test_basic.py
193+
tests/test_advanced.py
194+
195+
Obviously, these test modules must import your packaged module to test
196+
it. You can do this a few ways:
197+
198+
- Expect the package to be installed in site-packages.
199+
- Use a simple (but *explicit*) path modification to resolve the
200+
package properly.
201+
202+
I highly recommend the latter. Requiring a developer to run
203+
`setup.py <http://setup.py>`__ develop to test an actively changing
204+
codebase also requires them to have an isolated environment setup for
205+
each instance of the codebase.
206+
207+
To give the individual tests import context, create a tests/context.py
208+
file:
209+
210+
::
211+
212+
import os
213+
import sys
214+
sys.path.insert(0, os.path.abspath('..'))
215+
216+
import sample
217+
218+
Then, within the individual test modules, import the module like so:
219+
220+
::
221+
222+
from .context import sample
223+
224+
This will always work as expected, regardless of installation method.
225+
226+
Some people will assert that you should distribute your tests within
227+
your module itself -- I disagree. It often increases complexity for your
228+
users; many test suites often require additional dependencies and
229+
runtime contexts.
230+
231+
Makefile
232+
::::::::
233+
234+
235+
.. csv-table::
236+
:widths: 20, 40
237+
238+
"Location", "``./Makefile``"
239+
"Purpose", "Generic management tasks."
240+
241+
242+
If you look at most of my projects or any Pocoo project, you'll notice a
243+
Makefile laying around. Why? These projects aren't written in C... In
244+
short, make is a incredibly useful tool for defining generic tasks for
245+
your project.
246+
247+
**Sample Makefile:**
248+
249+
::
250+
251+
init:
252+
pip install -r requirements.txt
253+
254+
test:
255+
py.test tests
256+
257+
Other generic management scripts (e.g. ``manage.py``
258+
or ``fabfile.py``) belong at the root of the repository as well.
259+
260+
Regarding Django Applications
261+
:::::::::::::::::::::::::::::
262+
263+
I've noticed a new trend in Django applications since the release of
264+
Django 1.4. Many developers are structuring their repositories poorly
265+
due to the new bundled application templates.
266+
267+
How? Well, they go to their bare and fresh repository and run the
268+
following, as they always have:
269+
270+
::
271+
272+
$ django-admin.py start-project samplesite
273+
274+
The resulting repository structure looks like this:
275+
276+
::
277+
278+
README.rst
279+
samplesite/manage.py
280+
samplesite/samplesite/settings.py
281+
samplesite/samplesite/wsgi.py
282+
samplesite/samplesite/sampleapp/models.py
283+
284+
Don't do this.
285+
286+
Repetitive paths are confusing for both your tools and your developers.
287+
Unnecessary nesting doesn't help anybody (unless they're nostalgic for
288+
monolithic SVN repos).
289+
290+
Let's do it properly:
291+
292+
::
293+
294+
$ django-admin.py start-project samplesite .
295+
296+
Note the "``.``".
297+
298+
The resulting structure:
299+
300+
::
301+
302+
README.rst
303+
manage.py
304+
samplesite/settings.py
305+
samplesite/wsgi.py
306+
samplesite/sampleapp/models.py
307+
308+
309+
310+
311+
Structure of Code is Key
312+
------------------------
24313

25314
Thanks to the way imports and modules are handled in Python, it is
26315
relatively easy to structure a Python project. Easy, here, means

0 commit comments

Comments
 (0)