[CalendarServer-changes] [15480] CalendarServer/trunk/Contributing.rst

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 22 09:44:04 PDT 2016


Revision: 15480
          http://trac.calendarserver.org//changeset/15480
Author:   sagen at apple.com
Date:     2016-03-22 09:44:04 -0700 (Tue, 22 Mar 2016)
Log Message:
-----------
Replacement for HACKING.rst

Added Paths:
-----------
    CalendarServer/trunk/Contributing.rst

Added: CalendarServer/trunk/Contributing.rst
===================================================================
--- CalendarServer/trunk/Contributing.rst	                        (rev 0)
+++ CalendarServer/trunk/Contributing.rst	2016-03-22 16:44:04 UTC (rev 15480)
@@ -0,0 +1,425 @@
+Developer's Guide to Contributing to the Calendar Server
+========================================================
+
+If you are interested in contributing to the Calendar and Contacts
+Server project, please read this document.
+
+
+Participating in the Community
+==============================
+
+The Calendar and Contacts Server began in 1996 -- an open source
+project sponsored and hosted by Apple Inc. (http://www.apple.com/).
+The project is now hosted at GitHub, and although it lives within
+the "apple" namespace it's stil a true open-source project under
+an Apache license.  Contributions from other developers are welcome,
+and, as with all open development projects, may lead to "commit
+access" and a voice in the future of the project.
+
+The community exists mainly through mailing lists and a GitHub
+repository. To participate, go to:
+
+[FIXME: new mailing list link?]
+  http://trac.calendarserver.org/projects/calendarserver/wiki/MailLists
+
+and join the appropriate mailing lists.  We also use IRC, as described
+here:
+
+[FIXME: new IRC link?]
+  http://trac.calendarserver.org/projects/calendarserver/wiki/IRC
+
+There are many ways to join the project.  One may write code, test the
+software and file bugs, write documentation, etc.
+
+The issue tracking database is here:
+
+  https://github.com/apple/ccs-calendarserver/issues
+
+To help manage the issues database, read over the issue summaries,
+looking and testing for issues that are either invalid, or are
+duplicates of other issues. Both kinds are very common, the first
+because bugs often get unknowingly fixed as side effects of other
+changes in the code, and the second because people sometimes file an
+issue without noticing that it has already been reported. If you are
+not sure about an issue, post a question to
+
+[FIXME: new address?]
+calendarserver-dev at lists.macosforge.org.
+
+Before filing bugs, please take a moment to perform a quick search to
+see if someone else has already filed your bug.  In that case, add a
+comment to the existing bug if appropriate and monitor it, rather than
+filing a duplicate.
+
+
+Obtaining the Code
+==================
+
+The source code to the Calendar and Contacts Server is available via
+Git at this repository URL:
+
+  https://github.com/apple/ccs-calendarserver.git
+
+
+Directory Layout
+================
+
+A rough guide to the source tree:
+
+ * ``doc/`` - User and developer documentation, including relevant
+   protocol specifications and extensions.
+
+ * ``bin/`` - Executable programs.
+
+ * ``conf/`` - Configuration files.
+
+ * ``calendarserver/`` - Source code for the Calendar and Contacts
+   Server
+
+ * ``twistedcaldav/`` - Source code for CalDAV library
+
+ * ``twisted/`` - Files required to set up the Calendar and Contacts
+   Server as a Twisted service.  Twisted (http://twistedmatrix.com/)
+   is a networking framework upon which the Calendar and Contacts
+   Server is built.
+
+ * ``locales/`` - Localization files.
+
+ * ``contrib/`` - Extra stuff that works with the Calendar and
+   Contacts Server, or that helps integrate with other software
+   (including operating systems), but that the Calendar and Contacts
+   Server does not depend on.
+
+ * ``support/`` - Support files of possible use to developers.
+
+
+Coding Standards
+================
+
+The vast majority of the Calendar and Contacts Server is written in
+the Python programming language.  When writing Python code for the
+Calendar and Contacts Server, please observe the following
+conventions.
+
+Please note that all of our code at present does not follow these
+standards, but that does not mean that one shouldn't bother to do so.
+On the contrary, code changes that do nothing but reformat code to
+comply with these standards are welcome, and code changes that do not
+conform to these standards are discouraged.
+
+**We require Python 2.6 or higher.** It therefore is OK to write code
+that does not work with Python versions older than 2.6.
+
+Read PEP-8:
+
+  http://www.python.org/dev/peps/pep-0008/
+
+For the most part, our code should follow PEP-8, with a few exceptions
+and a few additions.  It is also useful to review the Twisted Coding
+Standard, from which we borrow some standards, though we don't
+strictly follow it:
+
+   http://twistedmatrix.com/trac/browser/trunk/doc/development/policy/coding-standard.xhtml?format=raw
+
+Key items to follow, and specifics:
+
+ * Indent level is 4 spaces.
+
+ * Never indent code with tabs.  Always use spaces.
+
+PEP-8 items we do not follow:
+
+ * PEP-8 recommends using a backslash to break long lines up:
+
+   ::
+
+     if width == 0 and height == 0 and \
+         color == 'red' and emphasis == 'strong' or \
+         highlight > 100:
+             raise ValueError("sorry, you lose")
+
+   Don't do that, it's gross, and the indentation for the ``raise`` line
+   gets confusing.  Use parentheses:
+
+   ::
+
+     if (
+         width == 0 and
+         height == 0 and
+         color == "red" and
+         emphasis == "strong" or
+         highlight > 100
+     ):
+         raise ValueError("sorry, you lose")
+
+   Just don't do it the way PEP-8 suggests:
+
+   ::
+
+     if width == 0 and height == 0 and (color == 'red' or
+                                        emphasis is None):
+         raise ValueError("I don't think so")
+
+   Because that's just silly.
+
+Additions:
+
+ * Close parentheses and brackets such as ``()``, ``[]`` and ``{}`` at the
+   same indent level as the line in which you opened it:
+
+   ::
+
+     launchAtTarget(
+         target="David",
+         object=PaperWad(
+             message="Yo!",
+             crumpleFactor=0.7,
+         ),
+         speed=0.4,
+     )
+
+ * Long lines are often due to long strings.  Try to break strings up
+   into multiple lines:
+
+   ::
+
+     processString(
+        "This is a very long string with a lot of text. "
+        "Fortunately, it is easy to break it up into parts "
+        "like this."
+     )
+
+   Similarly, callables that take many arguments can be broken up into
+   multiple lines, as in the ``launchAtTarget()`` example above.
+
+ * Breaking generator expressions and list comprehensions into
+   multiple lines can improve readability.  For example:
+
+   ::
+
+     myStuff = (
+         item.obtainUsefulValue()
+         for item in someDataStore
+         if item.owner() == me
+     )
+
+ * Import symbols (especially class names) from modules instead of
+   importing modules and referencing the symbol via the module unless
+   it doesn't make sense to do so.  For example:
+
+   ::
+
+     from subprocess import Popen
+
+     process = Popen(...)
+
+   Instead of:
+
+   ::
+
+     import subprocess
+
+     process = subprocess.Popen(...)
+
+   This makes code shorter and makes it easier to replace one implementation
+   with another.
+
+ * All files should have an ``__all__`` specification.  Put them at the
+   top of the file, before imports (PEP-8 puts them at the top, but
+   after the imports), so you can see what the public symbols are for
+   a file right at the top.
+
+ * It is more important that symbol names are meaningful than it is
+   that they be concise.  ``x`` is rarely an appropriate name for a
+   variable.  Avoid contractions: ``transmogrifierStatus`` is more useful
+   to the reader than ``trmgStat``.
+
+ * A deferred that will be immediately returned may be called ``d``:
+
+   ::
+
+     d = doThisAndThat()
+     d.addCallback(onResult)
+     d.addErrback(onError)
+     return d
+
+ * Do not use ``deferredGenerator``.  Use ``inlineCallbacks`` instead.
+
+ * That said, avoid using ``inlineCallbacks`` when chaining deferreds
+   is straightforward, as they are more expensive.  Use
+   ``inlineCallbacks`` when necessary for keeping code maintainable,
+   such as when creating serialized deferreds in a for loop.
+
+ * ``_`` may be used to denote unused callback arguments:
+
+   ::
+
+     def onCompletion(_):
+       # Don't care about result of doThisAndThat() in here;
+       # we only care that it has completed.
+       doNextThing()
+
+     d = doThisAndThat()
+     d.addCallback(onCompletion)
+     return d
+
+ * Do not prefix symbols with ``_`` unless they might otherwise be
+   exposed as a public symbol: a private method name should begin with
+   ``_``, but a locally scoped variable should not, as there is no
+   danger of it being exposed. Locally scoped variables are already
+   private.
+
+ * Per twisted convention, use camel-case (``fuzzyWidget``,
+   ``doThisAndThat()``) for symbol names instead of using underscores
+   (``fuzzy_widget``, ``do_this_and_that()``).
+
+   Use of underscores is reserved for implied dispatching and the like
+   (eg. ``http_FOO()``).  See the Twisted Coding Standard for details.
+
+ * Do not use ``%``-formatting:
+
+   ::
+
+     error = "Unexpected value: %s" % (value,)
+
+   Use PEP-3101 formatting instead:
+
+   ::
+
+     error = "Unexpected value: {value}".format(value=value)
+
+ * If you must use ``%``-formatting for some reason, always use a tuple as
+   the format argument, even when only one value is being provided:
+
+   ::
+
+     error = "Unexpected value: %s" % (value,)
+
+   Never use the non-tuple form:
+
+   ::
+
+     error = "Unexpected value: %s" % value
+
+   Which is allowed in Python, but results in a programming error if
+   ``type(value) is tuple and len(value) != 1``.
+
+ * Don't use a trailing ``,`` at the end of a tuple if it's on one line:
+
+   ::
+
+     numbers = (1,2,3,) # No
+     numbers = (1,2,3)  # Yes
+
+   The trailing comma is desirable on multiple lines, though, as that makes
+   re-ordering items easy, and avoids a diff on the last line when adding
+   another:
+
+   ::
+
+     strings = (
+       "This is a string.",
+       "And so is this one.",
+       "And here is yet another string.",
+     )
+
+ * Docstrings are important.  All public symbols (anything declared in
+   ``__all__``) must have a correct docstring.  The script
+   ``docs/Developer/gendocs`` will generate the API documentation using
+   ``pydoctor``.  See the ``pydoctor`` documentation for details on the
+   formatting:
+
+     http://codespeak.net/~mwh/pydoctor/
+
+   Note: existing docstrings need a complete review.
+
+ * Use PEP-257 as a guideline for docstrings.
+
+ * Begin all multi-line docstrings with 3 double quotes and a
+   newline:
+
+   ::
+
+     def doThisAndThat(...):
+       """
+       Do this, and that.
+       ...
+       """
+
+
+Best Practices
+==============
+
+ * If a callable is going to return a Deferred some of the time, it
+   should return a deferred all of the time.  Return ``succeed(value)``
+   instead of ``value`` if necessary.  This avoids forcing the caller
+   to check as to whether the value is a deferred or not (eg. by using
+   ``maybeDeferred()``), which is both annoying to code and potentially
+   expensive at runtime.
+
+ * Be proactive about closing files and file-like objects.
+
+   For a lot of Python software, letting Python close the stream for
+   you works fine, but in a long-lived server that's processing many
+   data streams at a time, it is important to close them as soon as
+   possible.
+
+   On some platforms (eg. Windows), deleting a file will fail if the
+   file is still open.  By leaving it up to Python to decide when to
+   close a file, you may find yourself being unable to reliably delete
+   it.
+
+   The most reliable way to ensure that a stream is closed is to put
+   the call to ``close()`` in a ``finally`` block:
+
+   ::
+
+     stream = file(somePath)
+     try:
+       ... do something with stream ...
+     finally:
+       stream.close()
+
+
+Testing
+=======
+
+Be sure that all of the units tests pass before you commit new code.
+Code that breaks units tests may be reverted without further
+discussion; it is up to the committer to fix the problem and try
+again.
+
+Note that repeatedly committing code that breaks units tests presents
+a possible time sink for other developers, and is not looked upon
+favorably.
+
+Units tests can be run rather easily by executing the ``./bin/test`` script
+at the top of the Calendar and Contacts Server source tree.  By
+default, it will run all of the Calendar and Contacts Server tests
+followed by all of the Twisted tests.  You can run specific tests by
+specifying them as arguments like this:
+
+   ::
+
+    ./bin/test twistedcaldav.static
+
+All non-trivial public callables must have unit tests.  (Note we don't
+don't totally comply with this rule; that's a problem we'd like to
+fix.)  All other callables should have unit tests.
+
+Units tests are written using the ``twisted.trial`` framework.  Test
+module names should start with ``test_``.  Twisted has some tips on
+writing tests here:
+
+  http://twistedmatrix.com/projects/core/documentation/howto/testing.html
+
+  http://twistedmatrix.com/trac/browser/trunk/doc/development/policy/test-standard.xhtml?format=raw
+
+We also use CalDAVTester (which is a companion to the Calendar and
+Contacts Server in the same Mac OS Forge project), which performs more
+"black box"-type testing against the server to ensure compliance with
+the CalDAV protocol.  That requires running the server with a test
+configuration and then running CalDAVTester against it.  For
+information about CalDAVTester is available here:
+
+  https://github.com/apple/ccs-caldavtester
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20160322/a6676942/attachment-0001.html>


More information about the calendarserver-changes mailing list