root/trunk/README

Revision 5, 14.9 kB (checked in by grig, 7 years ago)

Project layout reorg: moved all top-level files and dirs to trunk.

Line 
1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 Cheesecake: How tasty is your code?
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5 .. contents:: **Table of Contents**
6
7 Summary
8 -------
9
10 The idea of the Cheesecake project is to rank Python packages based on various
11 empirical "kwalitee" factors, such as:
12
13  * whether the package can be downloaded from PyPI given its name
14  * whether the package can be downloaded from a full URL
15  * whether the package can be unpacked
16  * whether the unpack directory is the same as the package name
17  * whether the package can be installed into an alternate directory
18  * existence of certain files such as README, INSTALL, LICENSE, setup.py etc.
19  * existence of certain directories such as doc, test, demo, examples
20  * percentage of modules/functions/classes/methods with docstrings
21  * percentage of functions/methods that are unit tested (not currently
22    implemented)
23  * average pylint score for all non-test and non-demo modules
24
25 Currently, the Cheesecake index is computed for invidual packages obtained
26 through a variety of methods (detailed below). One of the goals of the
27 Cheesecake project is to automatically compute the Cheesecake index for
28 all packages uploaded to the PyPI Cheese Shop (possibly at upload time) and
29 to maintain a collection of Web pages with statistics related to the
30 various indexes of the packages.
31
32 Cheesecake currently computes 3 types of indexes:
33
34  * installability index
35  * documentation index
36  * code kwalitee index
37
38 The algorithms for computing each index type are detailed below.
39
40 Why Cheesecake?
41 ---------------
42
43 The concept of "kwalitee" originated in the Perl community. Here's a relevant
44 quote:
45
46   *It looks like quality, it sounds like quality, but it's not quite quality.*
47
48 Kwalitee is an empiric measure of how good a specific body of code is. It
49 defines quality indicators and measures the code along them. It is currently
50 used by the `CPANTS Testing Service <http://cpants.dev.zsi.at/index.html>`_
51 to evaluate the 'goodness' of CPAN packages.
52
53 Since the Python package repository (aka `PyPI <http://www.python.org/pypi>`_)
54 is hosted at the Cheese Shop,
55 it stands to reason that the quality indicator of a PyPI package should be
56 called the Cheesecake index!
57
58 Usage examples
59 --------------
60
61 To compute the Cheesecake index for a given project, run the cheesecake.py
62 module from the command line and indicate either:
63
64  * the package short name (e.g. twill) or
65  * the package URL (e.g. http://darcs.idyll.org/~t/projects/twill-0.7.4.tar.gz) or
66  * the package path on the file system (e.g. /tmp/twill-latest.tar.gz)
67
68 In all cases, the cheesecake module will attempt to download the package
69 if necessary, then to unpack it in a sandbox directory (/tmp/cheesecake_sandbox
70 by default). If either of these operations fails, the Cheesecake index for
71 the package will be 0. If the package can be successfully unpacked, the
72 cheesecake module will compute the values for a variety of indexes detailed
73 in the algorithm given at the end of this file.
74
75 If the package can be successfully downloaded and unpacked, a log file is
76 created in the sandbox directory and named <package>.log (e.g. the log file
77 for twill-0.7.4.tar.gz is /tmp/cheesecake_sandbox/twill-0.7.4.tar.gz.log).
78 The log file is not automatically deleted after the Cheesecake index is
79 computed, since its purpose is to be inspected for debug information.
80
81 Command-line examples:
82
83  1. Compute the Cheesecake index for the Durus package by using setuptools
84     utilities to download the package from PyPI::
85
86       python cheesecake.py --name=Durus
87
88  2. Compute the Cheesecake index for the Durus package by indicating its URL::
89
90       python cheesecake.py --url=http://www.mems-exchange.org/software/durus/Durus-3.1.tar.gz
91
92  3. Compute the Cheesecake index for the twill package by indicating its path
93     on the local file system::
94
95       python cheesecake.py --path=/tmp/twill-latest.tar.gz
96
97  4. To increase the verbosity of the output, use the -v or --verbose option.
98     For more options, run cheesecake.py with -h or --help.
99
100 Obtaining the source code
101 -------------------------
102
103 The Cheesecake project has not yet been released as a tarball or
104 a Python egg. You can obtain the source code from SourceForge via CVS::
105
106   cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/cheesecake co -P cheesecake
107
108 Mailing list
109 ------------
110
111 Developer mailing list: http://lists.sourceforge.net/lists/listinfo/cheesecake-devel
112
113 License
114 -------
115
116 Cheesecake is licensed under the Python Software Foundation license,
117 the same license that governs Python itself. The text of the license is
118 available in the ``LICENSE`` file in the source code distribution and
119 can also be downloaded from
120 http://www.opensource.org/licenses/PythonSoftFoundation.php.
121
122 Author contact info
123 -------------------
124
125 Grig Gheorghiu
126
127 Email: <grig at gheorghiu dot net>
128
129 Web site:  http://agiletesting.blogspot.com
130
131 Algorithm for computing the Cheesecake index
132 --------------------------------------------
133
134 The cheesecake.py module uses the following constants::
135
136  INDEX_PYPI_DOWNLOAD = 50
137  INDEX_PYPI_DISTANCE = 5
138  INDEX_URL_DOWNLOAD  = 25
139  INDEX_UNPACK        = 25
140  INDEX_UNPACK_DIR    = 15
141  INDEX_INSTALL       = 50
142  INDEX_FILE_CRITICAL = 15
143  INDEX_FILE          = 10
144  INDEX_FILE_PYC      = 20
145  INDEX_DIR_CRITICAL  = 25
146  INDEX_DIR           = 20
147  INDEX_DIR_EMPTY     = 5
148
149  MAX_INDEX_DOCSTRINGS = 100 # max. percentage of modules/classes/methods/functions with docstrings
150  MAX_INDEX_PYLINT     = 100 # max. pylint score
151
152 **Step 0**
153
154 Initialize the Cheesecake index to 0. Also initialize to 0
155 the partial Cheesecake indexes for installability, documentation
156 and code kwalitee.
157
158 Compute the maximum overall Cheesecake index that can be reached by
159 any given package, which is the sum::
160
161  INDEX_PYPI_DOWNLOAD +
162  INDEX_UNPACK + INDEX_UNPACK_DIR +
163  INDEX_INSTALL +
164  MAX_INDEX_DOCSTRINGS + MAX_INDEX_PYLINT +
165  (INDEX_FILE * number_of_expected_files) +
166  (INDEX_FILE_CRITICAL * number_of_expected_critical_files) +
167  (INDEX_DIR * number_of_expected_dirs) +
168  (INDEX_DIR_CRITICAL * number_of_expected_critical_dirs)
169
170 Compute the maximum Cheesecake index for installability, which is the sum::
171
172  INDEX_PYPI_DOWNLOAD +
173  INDEX_UNPACK + INDEX_UNPACK_DIR +
174  INDEX_INSTALL
175
176 Compute the maximum Cheesecake index for documentation, which is the sum::
177
178  (INDEX_FILE * number_of_expected_files) +
179  (INDEX_FILE_CRITICAL * number_of_expected_critical_files) +
180  (INDEX_DIR * number_of_expected_dirs) +
181  (INDEX_DIR_CRITICAL * number_of_expected_critical_dirs) +
182  MAX_INDEX_DOCSTRINGS
183
184 Compute the maximum Cheesecake index for code kwalitee, which is currently::
185
186  MAX_INDEX_PYLINT
187
188 **Step 1a**
189
190 If short name of the package was specified with ``-n`` or ``--name``,
191 try to download the package from the PyPI index page by following the links to
192 the package home page and the package download URL (this is accomplished
193 using setuptools utilities).
194
195 If not successful, exit with a Cheesecake index of 0. If successful and
196 package was found at the Cheese Shop, add ``INDEX_PYPI_DOWNLOAD`` to
197 the overall Cheesecake index and to the installability Cheesecake index.
198
199 If successful but package was not found at the Cheese Shop, add
200 ``INDEX_PYPI_DOWNLOAD - (INDEX_PYPI_DISTANCE * number_of_links_to_package)``
201 to the overall Cheesecake index and to the installability Cheesecake index.
202
203 **Step 1b**
204
205 If full URL of the package was specified with ``-u`` or ``--url``,
206 try to download the package from the specified URL.
207
208 If not successful, exit with a Cheesecake index of 0. If successful,
209 add ``INDEX_URL_DOWNLOAD`` to the overall Cheesecake index and to
210 the installability Cheesecake index.
211
212 **Step 1c**
213
214 If path to package on local file system was specified with ``-p`` or
215 ``--path``, copy the package to the sandbox directory.
216
217 **Step 2**
218
219 Unpack the package (currently supported archive types are zip and
220 tar.gz/tgz; in the near future we will support Python Eggs.)
221
222 If not successful, exit with a Cheesecake index of 0. If successful, add
223 ``INDEX_UNPACK`` to the overall Cheesecake index and to the installability
224 Cheesecake index.
225
226 **Step 3**
227
228 Check that the unpack directory has the same name as the package name
229 (i.e. when unpacking twill-0.7.4.tar.gz, we expect the unpack directory
230 to be twill-0.7.4.)
231
232 If the unpack directory name is the same as the package name, add
233 ``INDEX_UNPACK_DIR``
234 to the overall Cheesecake index and to the installability Cheesecake index.
235
236 **Step 4**
237
238 Install the package to a temporary directory in a non-default location.
239 If successful, add ``INDEX_INSTALL`` to the overall Cheesecake index and to the
240 installability Cheesecake index.
241
242 **Step 5**
243
244 Check for existence of specific files.
245 For each file found, add ``INDEX_FILE`` to the overall
246 Cheesecake index and to the documentation Cheesecake index.
247 If the file is deemed critical, add ``INDEX_FILE_CRITICAL`` instead.
248
249 The following special files ("cheese_files") are currently checked::
250
251     cheese_files = ["install", "changelog",
252                     "news", "faq",
253                     "todo", "thanks", "announce",
254                     "ez_setup.py",
255                    ]
256
257 The following files are currently deemed critical::
258
259     critical_cheese_files = ["readme", "license", "setup.py"]
260
261 To check if a file FILE is among the cheese files, the following regular
262 expression is used::
263
264     re.search(r"^%s(\.txt)*" % cheese_file, file, re.IGNORECASE)
265
266 **Step 6**
267
268 Check for existence of specific directories.
269 For each directory found, add ``INDEX_DIR`` to the overall Cheesecake
270 index and to the documentation Cheesecake index.
271 If the directory is deemed critical, add ``INDEX_DIR_CRITICAL`` instead.
272 If the directory is found empty, add ``INDEX_DIR_EMPTY`` instead.
273
274 The following directories ("cheese_dirs") are currently checked::
275
276     cheese_dirs = ["example", "demo"]
277
278 The following directories are currently deemed critical::
279
280     critical_cheese_dirs = ["doc", "test"]
281
282 To check if a directory DIR is among the cheese directories,
283 the following regular expression is used::
284
285     re.search(r"^%s" % cheese_dir, DIR, re.ignorecase)
286
287 **Step 7**
288
289 Check for existence of .pyc files. If found, decrease the score
290 by subtracting ``INDEX_FILE_PYC`` from the overall Cheesecake index
291 and from the documentation Cheesecake index.
292
293 **Step 8**
294
295 Compute the percentage of modules/classes/methods/functions that have
296 docstrings associated with them. Only Python modules that are not in test,
297 doc, demo and example directories are checked.
298 Round up the percentage and add it to the overall Cheesecake index and to the
299 documentation Cheesecake index.
300
301 **Step 9**
302
303 If pylint is present on the system, run pylint against all Python files
304 that are not in the test, docs or demo directories.
305 Average the non-negative pylint scores, multiply the average by 10 and
306 add it to the overall Cheesecake index and to the code kwalitee
307 Cheesecake index.
308  
309 **Step 10**
310
311 For each of the partial Cheesecake index types (installability,
312 documentation and code kwalitee), display the absolute Cheesecake
313 index for that type as the sum of all indexes of that type computed in
314 the previous steps.
315 Also display the relative Cheesecake index for that type as the percentage
316 of ``(absolute_index / maximum_index)``.
317
318 Display the absolute Cheesecake index for the package as the sum of all
319 indexes computed in the previous steps. Also display the relative Cheesecake
320 index for the package as the percentage of ``(absolute_index / maximum_index)``.
321
322 Sample output
323 -------------
324
325 ::
326
327  $ python cheesecake.py -n Durus
328  [cheesecake:console] Trying to download package durus from PyPI using setuptools utilities
329  [cheesecake:console] Downloaded package Durus-3.1.tar.gz from http://www.mems-exchange.org/software/durus/Durus-3.1.tar.gz
330  [cheesecake:console] Detailed info available in log file /tmp/cheesecake_sandbox/durus.log
331  [cheesecake:console] A given package can currently reach a MAXIMUM number of 555 points
332  [cheesecake:console] Starting computation of Cheesecake index for package 'Durus-3.1.tar.gz'
333
334  [cheesecake:console] Starting computation of INSTALLABILITY index (max. points = 140)
335  index_pypi_download .....................  45 (downloaded package Durus-3.1.tar.gz following 1 link from PyPI)
336  index_unpack ............................  25 (package untar-ed successfully)
337  index_unpack_dir ........................  15 (unpack directory is Durus-3.1 as expected)
338  index_install ...........................  50 (package installed in /tmp/cheesecake_sandbox/tmp_install_Durus-3.1)
339  ---------------------------------------------
340  INSTALLABILITY INDEX (ABSOLUTE) ......... 135
341  INSTALLABILITY INDEX (RELATIVE) .........  96 (135 out of a maximum of 140 points is 96%)
342
343  [cheesecake:console] Starting computation of DOCUMENTATION index (max. points = 415)
344  index_file_announce .....................   0 (file not found)
345  index_file_changelog ....................   0 (file not found)
346  index_file_ez_setup.py ..................   0 (file not found)
347  index_file_faq ..........................  10 (file found)
348  index_file_install ......................  10 (file found)
349  index_file_license ......................  15 (critical file found)
350  index_file_news .........................   0 (file not found)
351  index_file_readme .......................  15 (critical file found)
352  index_file_setup.py .....................  15 (critical file found)
353  index_file_thanks .......................   0 (file not found)
354  index_file_todo .........................   0 (file not found)
355  index_dir_demo ..........................   0 (directory not found)
356  index_dir_doc ...........................  25 (critical directory found)
357  index_dir_example .......................   0 (directory not found)
358  index_dir_test ..........................  25 (critical directory found)
359  index_docstrings ........................  42 (found 104/249=41.77% modules/classes/methods/functions with docstrings)
360  ---------------------------------------------
361  DOCUMENTATION INDEX (ABSOLUTE) .......... 157
362  DOCUMENTATION INDEX (RELATIVE) ..........  37 (157 out of a maximum of 415 points is 37%)
363  
364  [cheesecake:console] Starting computation of CODE KWALITEE index (max. points = 100)
365  index_pylint ............................  64 (average score is 6.30 out of 10)
366  ---------------------------------------------
367  CODE KWALITEE INDEX (ABSOLUTE) ..........  64
368  CODE KWALITEE INDEX (RELATIVE) ..........  64 (64 out of a maximum of 100 points is 64%)
369  
370  =============================================
371  OVERALL CHEESECAKE INDEX (ABSOLUTE) ..... 356
372  OVERALL CHEESECAKE INDEX (RELATIVE) .....  64 (356 out of a maximum of 555 points is 64%)
373
374 Future plans
375 ------------
376 Cheesecake is under very active development. The immediate goal is to add the unit test
377 index measurement, followed by other metrics inspired from the
378 `kwalitee indicators <http://cpants.dev.zsi.at/kwalitee.html>`_.
379 Please edit the `IndexMeasurementIdeas <http://tracos.org/cheesecake/wiki/IndexMeasurementIdeas>`_
380 Wiki page to add things that you would like to see covered
381 by the Cheesecake metrics.
382
383 .. footer:: Generated with rst2html.py from the
384    `docutils <http://docutils.sourceforge.net/>`_
385    distribution. Last modified 2005-12-20 by
386    `Grig Gheorghiu <http://agiletesting.blogspot.com>`_.
Note: See TracBrowser for help on using the browser.