Merge lp:~james-w/pkgme/add-docs into lp:pkgme

Proposed by James Westby
Status: Merged
Merged at revision: 40
Proposed branch: lp:~james-w/pkgme/add-docs
Merge into: lp:pkgme
Prerequisite: lp:~james-w/pkgme/fix-tests
Diff against target: 335 lines (+232/-26)
7 files modified
README.txt (+15/-17)
conf.py (+2/-2)
doc/authors/index.txt (+10/-0)
doc/backends/index.txt (+109/-0)
doc/index.txt (+12/-0)
pkgme/info_elements.py (+15/-7)
pkgme/rstinfo.py (+69/-0)
To merge this branch: bzr merge lp:~james-w/pkgme/add-docs
Reviewer Review Type Date Requested Status
pkgme committers Pending
Review via email: mp+43727@code.launchpad.net

This proposal supersedes a proposal from 2010-12-15.

Description of the change

Hi,

This branch adds some skeleton docs, splitting in to two
target audiences.

I want to get the backend docs to a good state first, as we want
to attract backend authors. I made a start on that documentation, but
the main aim of this branch was to write the sphinx extension.

This extension is similar to autodoc, but it writes out information on
the bits of information that backends can provide. This means that the
documentation will always be in sync with the code.

Thanks,

James

To post a comment you must log in.
lp:~james-w/pkgme/add-docs updated
40. By James Westby

Fix a couple of warts.

Revision history for this message
Barry Warsaw (barry) wrote : Posted in a previous version of this proposal
Download full text (3.4 KiB)

Diff looks pretty good to me, though I think there are a few typos. Also, I get many failures in the test suite (I haven't tried the trunk to see if the same failures are there).

Here are just a few quick suggestions:

=== added file 'doc/backends/index.txt'
--- doc/backends/index.txt 1970-01-01 00:00:00 +0000
+++ doc/backends/index.txt 2010-12-15 23:39:37 +0000
> +pkgme itself is agnostic about the type of project that it is working on, but knows
> +how to put information about a project in to the packaging files such that result

"...into the packaging files such that the result should..."

> +should work, assuming that the information provided is good enough.
> +
> +Every time it needs a bit of information about the project, such as its name, or
> +the dependencies it requires, it asks the backend that is the best match for the
> +project.

"...it asks the matching backend for the project."

> +
> +In this manner, the backends, and so you as a backend author, don't need to know

"In this manner the backends (and you as a backend author), don't need..."

> +However, if it is asked about a Ruby on Rails project then it should report a higher
> +number, the question is just how high. Consider the fact that there may be a
> +generic Ruby backend, which would presumably be able to give some useful information
> +about this project. However, the Ruby backend shouldn't have to detect that this is a
> +Rails project, and know that there is a Rails backend, and so answer "0", as that would

s/and know/or know/

> +There are a couple of places where the backend needs to know something related to packaging.
> +
> +The first of these is in the specification of the build dependencies, where the backend
> +has to provide the list of packages that are needed. While the backend probably has
> +available the list of modules used or similar, it wouldn't be possible for pkgme to
> +translate these to a list of packages while remaining generic.

True, but I wonder if we could provide a set of conveniences for finding
packages. For example, a backend might know the name of an upstream package
it depends on, but not the binary package it must actually depend on. A
search facility (e.g. something like 'aptitude search') might be useful. Or
an API for finding the binary packages produced by a source package. Some of
that can be generalized even if the actual package dependency calculation must
be done by the backend.

> +Therefore one of the things the backend must be able to do is to go from the list of
> +modules to the list of packages that provide them, using whatever means is appropriate.
> +
> +The second area where the backend needs to know something related to packaging is specifying
> +what build system to use. pkgme leaves all the steps of actually building the package, knowing
> +what commands to run to build, what files to put where, up to debhelper. debhelper in turn

"...what files to put where, etc., up to..."

> +delegates some of this work to its buildsystems, which are analogous to pkgme's backends.
> +
> +Therefore pkgme needs to know which buildsystem to instruct debhelper to use, and for this it
> +will query the backend. This means th...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README.txt'
2--- README.txt 2010-12-08 02:00:29 +0000
3+++ README.txt 2010-12-15 02:19:09 +0000
4@@ -1,20 +1,3 @@
5-A Debian packaging generation framework.
6-
7-..
8- This program is free software: you can redistribute it and/or modify
9- it under the terms of the GNU General Public License as published by
10- the Free Software Foundation, either version 3 of the License, or
11- (at your option) any later version.
12-
13- This program is distributed in the hope that it will be useful,
14- but WITHOUT ANY WARRANTY; without even the implied warranty of
15- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16- GNU General Public License for more details.
17-
18- You should have received a copy of the GNU General Public License
19- along with this program. If not, see <http://www.gnu.org/licenses/>.
20-
21-
22 =====
23 pkgme
24 =====
25@@ -89,3 +72,18 @@
26 :glob:
27
28 *
29+..
30+ This program is free software: you can redistribute it and/or modify
31+ it under the terms of the GNU General Public License as published by
32+ the Free Software Foundation, either version 3 of the License, or
33+ (at your option) any later version.
34+
35+ This program is distributed in the hope that it will be useful,
36+ but WITHOUT ANY WARRANTY; without even the implied warranty of
37+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38+ GNU General Public License for more details.
39+
40+ You should have received a copy of the GNU General Public License
41+ along with this program. If not, see <http://www.gnu.org/licenses/>.
42+
43+
44
45=== modified file 'conf.py'
46--- conf.py 2010-11-10 22:42:51 +0000
47+++ conf.py 2010-12-15 02:19:09 +0000
48@@ -22,7 +22,7 @@
49
50 # Add any Sphinx extension module names here, as strings. They can be extensions
51 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
52-extensions = ['sphinx.ext.autodoc']
53+extensions = ['sphinx.ext.autodoc', 'pkgme.rstinfo']
54
55 # Add any paths that contain templates here, relative to this directory.
56 templates_path = ['../../_templates']
57@@ -34,7 +34,7 @@
58 #source_encoding = 'utf-8'
59
60 # The master toctree document.
61-master_doc = 'README'
62+master_doc = 'doc/index'
63
64 # General information about the project.
65 project = u'pkgme'
66
67=== added directory 'doc'
68=== added directory 'doc/authors'
69=== added file 'doc/authors/index.txt'
70--- doc/authors/index.txt 1970-01-01 00:00:00 +0000
71+++ doc/authors/index.txt 2010-12-15 02:19:09 +0000
72@@ -0,0 +1,10 @@
73+=====
74+pkgme
75+=====
76+
77+Welcome to pkgme, a tool that will help you package your application for Debian/Ubuntu.
78+
79+pkgme takes care of creating the files needed for packaging, by inspecting your
80+code. As long as your project follows the conventions of one of the languages/project
81+types that pkgme supports pkgme will be able to generate working packaging without
82+you having to deal with any of the details.
83
84=== added directory 'doc/backends'
85=== added file 'doc/backends/index.txt'
86--- doc/backends/index.txt 1970-01-01 00:00:00 +0000
87+++ doc/backends/index.txt 2010-12-15 02:19:09 +0000
88@@ -0,0 +1,109 @@
89+==============
90+pkgme backends
91+==============
92+
93+pkgme backends provide the project specific information that is needed to generate
94+the packaging. They examine the project in question and provide the information to
95+the best of their ability.
96+
97+Each backend deals with a particular language, or project type, for instance their
98+could be backends for Vala, Ruby on Rails, Python Django, C with autotools, GNOME,
99+KDE, CMake, etc.
100+
101+How they work
102+-------------
103+
104+pkgme itself is agnostic about the type of project that it is working on, but knows
105+how to put information about a project in to the packaging files such that result
106+should work, assuming that the information provided is good enough.
107+
108+Every time it needs a bit of information about the project, such as its name, or
109+the dependencies it requires, it asks the backend that is the best match for the
110+project.
111+
112+In this manner, the backends, and so you as a backend author, don't need to know
113+much about packaging, and pkgme doesn't need to know about every different sort of
114+project that there is.
115+
116+Selecting a backend
117+-------------------
118+
119+When pkgme is asked to create the packaging for a project, it firsts selects the
120+backend that is most suited to the task. To do this it asks each backend to report
121+a score of how well it thinks that it can handle that project.
122+
123+A Ruby on Rails backend would presumably not be able to handle a Python project
124+very well, so if asked to report a score for a Python project it should return
125+"0".
126+
127+However, if it is asked about a Ruby on Rails project then it should report a higher
128+number, the question is just how high. Consider the fact that there may be a
129+generic Ruby backend, which would presumably be able to give some useful information
130+about this project. However, the Ruby backend shouldn't have to detect that this is a
131+Rails project, and know that there is a Rails backend, and so answer "0", as that would
132+be very brittle. In addition, there may be a backend that is specifically for
133+Ruby on Rails, using particular conventions and addons, which would want to out-score
134+the generic Rails backend when appropriate.
135+
136+Assigning all the scores up-front isn't a good idea though, so we use the following
137+guildelines:
138+
139+ * 0 - no information can be provided about the project (e.g. a Ruby backend with a Python project).
140+ * 10 - some information can be provided, but the backend is generic (e.g. Ruby backend).
141+ * 20 - some information can be provided, and the backend is more generic than just language (e.g. Ruby on Rails backend).
142+ * 30 - some information can be provided, and the backend is highly specialised.
143+
144+When there are many backends that are closely related we can assign scores more carefully
145+to those backend, but this scheme will suffice for now.
146+
147+Getting the info
148+----------------
149+
150+When pkgme needs to get a bit of information about the project, such as its name, or
151+the dependencies required to build, it asks the backend that it selected. The backend
152+is expected to do its best to provide that information, but not to provide it if it can't
153+do so, otherwise the generated packaging wouldn't work.
154+
155+The backend can use any means it likes to get the information, parsing files in
156+conventional locations, scanning the tree.
157+
158+Interface with packaging
159+------------------------
160+
161+There are a couple of places where the backend needs to know something related to packaging.
162+
163+The first of these is in the specification of the build dependencies, where the backend
164+has to provide the list of packages that are needed. While the backend probably has
165+available the list of modules used or similar, it wouldn't be possible for pkgme to
166+translate these to a list of packages while remaining generic.
167+
168+Therefore one of the things the backend must be able to do is to go from the list of
169+modules to the list of packages that provide them, using whatever means is appropriate.
170+
171+The second area where the backend needs to know something related to packaging is specifying
172+what build system to use. pkgme leaves all the steps of actually building the package, knowing
173+what commands to run to build, what files to put where, up to debhelper. debhelper in turn
174+delegates some of this work to its buildsystems, which are analogous to pkgme's backends.
175+
176+Therefore pkgme needs to know which buildsystem to instruct debhelper to use, and for this it
177+will query the backend. This means that the backend should know which debhelper buildsystem
178+is appropriate for the project. If you are implementing a backend for which there isn't yet
179+a debhelper buildsystem, you will also have to implement that in order to enjoy completely
180+automated packaging.
181+
182+.. FIXME: reference for the currently available debhelper backends.
183+.. FIXME: reference for implementing a debhelper buildsystem.
184+
185+Implementing a backend
186+----------------------
187+
188+.. FIXME: Explain how to implement a backend
189+
190+
191+Information that pkgme may request
192+----------------------------------
193+
194+.. This outputs information on the info that a backend can provide, based
195+ on introspecting the code. See pkgme.rstinfo for the code that does
196+ this.
197+.. pkgme_info_elements::
198
199=== added file 'doc/index.txt'
200--- doc/index.txt 1970-01-01 00:00:00 +0000
201+++ doc/index.txt 2010-12-15 02:19:09 +0000
202@@ -0,0 +1,12 @@
203+=====
204+pkgme
205+=====
206+
207+pkgme is a tool to automate the creation of Debian packaging.
208+
209+.. toctree::
210+ :maxdepth: 1
211+
212+ pkgme for application authors <authors/index>
213+ Adding support for your project type to pkgme <backends/index>
214+ The pkgme README </README>
215
216=== modified file 'pkgme/info_elements.py'
217--- pkgme/info_elements.py 2010-12-13 01:44:04 +0000
218+++ pkgme/info_elements.py 2010-12-15 02:19:09 +0000
219@@ -43,7 +43,7 @@
220 class PackageName(InfoElement):
221
222 name = "package_name"
223- description = "The nane of the package."
224+ description = "The name of the package."
225 required = True
226
227
228@@ -59,7 +59,10 @@
229 name = "maintainer"
230 description = """The maintainer of the package.
231
232- Should be in the form Name <email>.
233+ Should be in the form::
234+
235+ Name <email>
236+
237 """
238 required = True
239
240@@ -84,11 +87,16 @@
241 name = "architecture"
242 description = """The architecture(s) to build the binary package for.
243
244- This can be:
245- - any: to build on every architecture (arch-dependent)
246- - all: to build once and use the result on all architecture
247- (arch-independent)
248- - a list of architectures (arch-dependent)
249+ This can be one of the following.
250+
251+ any
252+ to build on every architecture (arch-dependent).
253+ all
254+ to build once and use the result on all architecture
255+ (arch-independent).
256+ a list of architectures (arch-dependent)
257+ to build on specific architectures only.
258+
259 """
260 required = True
261
262
263=== added file 'pkgme/rstinfo.py'
264--- pkgme/rstinfo.py 1970-01-01 00:00:00 +0000
265+++ pkgme/rstinfo.py 2010-12-15 02:19:09 +0000
266@@ -0,0 +1,69 @@
267+from docutils import nodes
268+from docutils.statemachine import ViewList
269+from sphinx.util.compat import Directive
270+from sphinx.util.docstrings import prepare_docstring
271+
272+from pkgme.package_files import default_package_file_group
273+
274+
275+class PkgmeInfoElementsDirective(Directive):
276+
277+ def get_elements(self):
278+ return default_package_file_group.get_elements()
279+
280+ def split_required(self, elements):
281+ required = set()
282+ not_required = set()
283+ for element in elements:
284+ if element.required:
285+ required.add(element)
286+ else:
287+ not_required.add(element)
288+ return required, not_required
289+
290+ def sort_elements(self, elements):
291+ new_elements = list(elements)
292+ new_elements.sort(key=lambda x: x.name)
293+ return new_elements
294+
295+ def get_node_for_element(self, element):
296+ item = nodes.definition_list_item()
297+ term = nodes.term()
298+ term += nodes.Text(element.name)
299+ definition = nodes.definition()
300+ description = ViewList()
301+ for i, line in enumerate(prepare_docstring(element.description)):
302+ description.append(
303+ line,
304+ 'description attribute of %s info element' % element.name,
305+ i)
306+ self.state.nested_parse(description, 0, definition)
307+ if element.default is not None:
308+ para = nodes.paragraph()
309+ definition += para
310+ para += nodes.Text("The default value is ")
311+ para += nodes.literal(element.default, element.default)
312+ item += term
313+ item += definition
314+ return item
315+
316+ def build_definition_list(self, elements):
317+ node = nodes.definition_list()
318+ for element in self.sort_elements(elements):
319+ node += self.get_node_for_element(element)
320+ return node
321+
322+ def run(self):
323+ elements = self.get_elements()
324+ required, not_required = self.split_required(elements)
325+ node = nodes.paragraph()
326+ node.document = self.state.document
327+ node += nodes.Text("The following elements are required, and must be provided if asked for to produce any packaging.")
328+ node += self.build_definition_list(required)
329+ node += nodes.Text("The following elements are optional, and do not have to be provided to produce packaging.")
330+ node += self.build_definition_list(not_required)
331+ return [node]
332+
333+
334+def setup(app):
335+ app.add_directive('pkgme_info_elements', PkgmeInfoElementsDirective)

Subscribers

People subscribed via source and target branches

to all changes: