1 / 56

Smoothing Software Project Scripting

Smoothing Software Project Scripting. Mark Ramm reprising his award-winning role as Kevin Dangoor BlueSkyOnMars.com. Python is not compiled. (actually, it is, but that’s not important right now). Python projects certainly do not need. Redistributable files to move around

Angelica
Download Presentation

Smoothing Software Project Scripting

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Smoothing Software Project Scripting • Mark Ramm • reprising his award-winning role as • Kevin Dangoor • BlueSkyOnMars.com

  2. Python is not compiled (actually, it is, but that’s not important right now)

  3. Python projects certainly do not need • Redistributable files to move around • Deployment to other machines • Interaction with source control systems • Documentation that’s built from the source code • Documentation that’s built from a format other than its final display format

  4. If only there was some scripting language that we already knew.

  5. Waitasec. Isn’t Python a scripting language?

  6. Project-related scripts need... • Command line argument handling • Configuration • Often work with files • Sometimes need to use distutils/setuptools, but wish they could do a little more • Need to work with other common tools (Sphinx, svn, virtualenv)

  7. Command-line argument handling • bin/start-server --port 8675309

  8. Configuration • [messages] • greeting=Hello • [thing1] • who=World • message=${messages.greeting}, ${who}

  9. Lots of working with files • import os • if not os.path.exists(“foo”): • os.mkdir(“foo”) • if not os.path.exists(os.path.join(“foo, “bar”)): • open(os.path.join(“foo”, “bar”), “w”).write(“Hi”)

  10. Working with distutils/setuptools • #!/bin/sh • sphinx-build (blah blah blah) • python setup.py sdist upload

  11. Other common tools • sphinx-build ... • subprocess.Popen(“svn info”... • # and do something with the output • virtualenv.create_bootstrap_script(“# more code”)

  12. Do you really want separate scripts for everything? • /usr/local/bin/git /usr/local/bin/git-merge-resolve • /usr/local/bin/git-add /usr/local/bin/git-merge-stupid • /usr/local/bin/git-add--interactive /usr/local/bin/git-merge-subtree • /usr/local/bin/git-am /usr/local/bin/git-merge-tree • /usr/local/bin/git-annotate /usr/local/bin/git-mergetool • /usr/local/bin/git-apply /usr/local/bin/git-mktag • /usr/local/bin/git-archimport /usr/local/bin/git-mktree • /usr/local/bin/git-archive /usr/local/bin/git-mv • /usr/local/bin/git-bisect /usr/local/bin/git-name-rev • /usr/local/bin/git-blame /usr/local/bin/git-pack-objects • /usr/local/bin/git-branch /usr/local/bin/git-pack-redundant • /usr/local/bin/git-bundle /usr/local/bin/git-pack-refs • /usr/local/bin/git-cat-file /usr/local/bin/git-parse-remote • /usr/local/bin/git-check-attr /usr/local/bin/git-patch-id • /usr/local/bin/git-check-ref-format /usr/local/bin/git-peek-remote • /usr/local/bin/git-checkout /usr/local/bin/git-prune • /usr/local/bin/git-checkout-index /usr/local/bin/git-prune-packed • /usr/local/bin/git-cherry /usr/local/bin/git-pull • /usr/local/bin/git-cherry-pick /usr/local/bin/git-push • /usr/local/bin/git-citool /usr/local/bin/git-quiltimport • /usr/local/bin/git-clean /usr/local/bin/git-read-tree • /usr/local/bin/git-clone /usr/local/bin/git-rebase • /usr/local/bin/git-commit /usr/local/bin/git-rebase--interactive • /usr/local/bin/git-commit-tree /usr/local/bin/git-receive-pack • /usr/local/bin/git-config /usr/local/bin/git-reflog • /usr/local/bin/git-convert-objects /usr/local/bin/git-relink • /usr/local/bin/git-count-objects /usr/local/bin/git-remote • /usr/local/bin/git-cvsexportcommit /usr/local/bin/git-repack • /usr/local/bin/git-cvsimport /usr/local/bin/git-repo-config • /usr/local/bin/git-cvsserver /usr/local/bin/git-request-pull • /usr/local/bin/git-daemon /usr/local/bin/git-rerere • /usr/local/bin/git-describe /usr/local/bin/git-reset • /usr/local/bin/git-diff /usr/local/bin/git-rev-list • /usr/local/bin/git-diff-files /usr/local/bin/git-rev-parse • /usr/local/bin/git-diff-index /usr/local/bin/git-revert • /usr/local/bin/git-diff-tree /usr/local/bin/git-rm • /usr/local/bin/git-fast-import /usr/local/bin/git-runstatus • /usr/local/bin/git-fetch /usr/local/bin/git-send-email • /usr/local/bin/git-fetch--tool /usr/local/bin/git-send-pack • /usr/local/bin/git-fetch-pack /usr/local/bin/git-sh-setup • /usr/local/bin/git-filter-branch /usr/local/bin/git-shell • /usr/local/bin/git-fmt-merge-msg /usr/local/bin/git-shortlog • /usr/local/bin/git-for-each-ref /usr/local/bin/git-show • /usr/local/bin/git-format-patch /usr/local/bin/git-show-branch • /usr/local/bin/git-fsck /usr/local/bin/git-show-index • /usr/local/bin/git-fsck-objects /usr/local/bin/git-show-ref • /usr/local/bin/git-gc /usr/local/bin/git-ssh-fetch • /usr/local/bin/git-get-tar-commit-id /usr/local/bin/git-ssh-pull • /usr/local/bin/git-grep /usr/local/bin/git-ssh-push • /usr/local/bin/git-gui /usr/local/bin/git-ssh-upload • /usr/local/bin/git-hash-object /usr/local/bin/git-stash • /usr/local/bin/git-http-fetch /usr/local/bin/git-status • /usr/local/bin/git-imap-send /usr/local/bin/git-stripspace • /usr/local/bin/git-index-pack /usr/local/bin/git-submodule • /usr/local/bin/git-init /usr/local/bin/git-svn • /usr/local/bin/git-init-db /usr/local/bin/git-svnimport • /usr/local/bin/git-instaweb /usr/local/bin/git-symbolic-ref • /usr/local/bin/git-local-fetch /usr/local/bin/git-tag • /usr/local/bin/git-log /usr/local/bin/git-tar-tree • /usr/local/bin/git-lost-found /usr/local/bin/git-unpack-file • /usr/local/bin/git-ls-files /usr/local/bin/git-unpack-objects • /usr/local/bin/git-ls-remote /usr/local/bin/git-update-index • /usr/local/bin/git-ls-tree /usr/local/bin/git-update-ref • /usr/local/bin/git-mailinfo /usr/local/bin/git-update-server-info • /usr/local/bin/git-mailsplit /usr/local/bin/git-upload-archive • /usr/local/bin/git-merge /usr/local/bin/git-upload-pack • /usr/local/bin/git-merge-base /usr/local/bin/git-var • /usr/local/bin/git-merge-file /usr/local/bin/git-verify-pack • /usr/local/bin/git-merge-index /usr/local/bin/git-verify-tag • /usr/local/bin/git-merge-octopus /usr/local/bin/git-whatchanged • /usr/local/bin/git-merge-one-file /usr/local/bin/git-write-tree • /usr/local/bin/git-merge-ours /usr/local/bin/gitk • /usr/local/bin/git-merge-recursive

  13. easy_install Paver

  14. paver paverdocs

  15. pavement.py

  16. Why Python build files? • You already know Python • The language rules are well-defined • The language rules are well-documented • Python is powerful, so you’ll never be left hanging or need an escape hatch

  17. Configuration • options( • setup = setup_meta, • minilib=Bunch( • extra_files=['doctools', 'virtual'] • ), • sphinx=Bunch( • builddir="build", • sourcedir="source" • ), • virtualenv=Bunch( • packages_to_install=["nose", "sphinx", "docutils", "virtualenv"], • install_paver=False, • script_name='bootstrap.py', • paver_command_line=None • ) • )

  18. Dynamic config values • >>> from paver.defaults import * • >>> import time • >>> options(current=lambda: time.time()) • >>> options.current • 1216726815.0027969

  19. Namespace searching • >>> options( • ... setup=Bunch(version="1.0"), • ... sphinx=Bunch(builddir="docbuild") • ... ) • >>> options.version • '1.0'

  20. Namespace searching (continued) • >>> options( • ... setup=Bunch(version="1.0"), • ... sphinx=Bunch(builddir="docbuild") • ... ) • >>> options.order('sphinx') • >>> options.version • Traceback (most recent call last): • File "<stdin>", line 1, in <module> • File "/Users/admin/projects/paver/paver/runtime.py", line 31, in __getattr__ • raise AttributeError(name) • AttributeError: version

  21. Configuration is still standard Python • You can treat options like a normal, nested dictionary • The only unusual thing would be that callables are called.

  22. Tasks • @task • def clean(): • """Cleans up this paver directory. Removes the virtualenv traces and • the build directory.""" • pass

  23. paver help • paver help • ---> paver.tasks.help • Usage: paver [global options] taskname [task options] [taskname [taskoptions]] • Options: • --version show program's version number and exit • -n, --dry-run don't actually do anything • -v, --verbose display all logging output • -q, --quiet display only errors • -i, --interactive enable prompting • -f FILE, --file=FILE read tasks from FILE [pavement.py] • -h, --help display this help information • Tasks from paver.misctasks: • generate_setup - Generates a setup

  24. paver help <taskname> • Usage: paver paver.misctasks.minilib [options] • Options: • -h, --help display this help information • Create a Paver mini library that contains enough for a simple • pavement.py to be installed using a generated setup.py. This • is a good temporary measure until more people have deployed paver. • The output file is 'paver-minilib.zip' in the current directory. • Options: • extra_files • list of other paver modules to include (don't include the .py • extension). By default, the following modules are included: • defaults, path, release, setuputils, misctasks, options, • tasks, easy

  25. @needs • @task • @needs("uncog") • def commit(): • """Removes the generated code from the docs and then commits to bzr.""" • pass

  26. @cmdopts • @task • @cmdopts([("username=", "u", "Username for remote server"), • ("server=", "s", "Server to deploy to")]) • def deploy(): • """Copy the Paver website up.""" • pass

  27. paver <taskname> • $ paver generate_setup minilib • ---> generate_setup • Write setup.py • ---> minilib • Generate paver-minilib.zip

  28. Paver and Distutils/Setuptools

  29. python setup.py install

  30. Paver embraces and extends Distutils (don’t worry, it’s not evil)

  31. paver install

  32. setup.py example • from distutils.core import setup • setup(name='foo', version='1.0', py_modules=['foo'], )

  33. Upgrading to Paver • from paver.setuputils import setupsetup(name='foo', version='1.0', py_modules=['foo'], )

  34. Keeping it simple for users • $ paver generate_setup minilib • ---> generate_setup • Write setup.py • ---> minilib • Generate paver-minilib.zip

  35. The Paver Standard Library (is actually newer and less musty)

  36. The Paver Standard Library • Easy scripting (paver.easy) • Distutils integration (paver.setuputils) • File handling (paver.path) • Documentation tools (paver.doctools) • Subversion (paver.svn) • SSH (paver.ssh) • Virtualenv (paver.virtual) • Miscellaneous Tasks (paver.misctasks)

  37. paver.easy • from paver.easy import * • # display text if verbose is set • debug(“Hi there. Feeling chatty today?”) • # display text if quiet is not set • info(“Glad we don’t have to keep quiet”) • # display text regardless of setting • error(“HA! I’M SHOUTING AND YOU CAN’T STOP ME!”)

  38. paver.easy (continued) • # run a command, as long as dry-run is off • # capture the output into myval • myval = sh(“cat /tmp/foo”, capture=True) • # run a function (delete_all(‘/’) to be exact). • # if dry-run is set, then • # just print the message instead • dry(“Delete everything”, delete_all, ‘/’)

  39. paver.path • Jason Orendorff’s path.py module (also available separately) • It’s a subclass of string! • Fun use of operator overloading • Lots of great methods • Makes working with files/directories fun and easy

  40. paver.path examples • p = path("docs")tmpdir = p /"tmp"tmpdir.mkdir()fn = tmpdir /"myfile.txt"fn.write_text("Hi there!")

  41. paver.doctools • # add this to use • import paver.doctools

  42. paver.doctools – Sphinx • paver.doctools.html() • ¶ • Build HTML documentation using Sphinx. This uses the following options in a “sphinx” section of the options. • docroot • the root under which Sphinx will be working. Default: docs • builddir • directory under the docroot where the resulting files are put. default: build • sourcedir • directory under the docroot for the source files default: (empty string) • paver.doctools.doc_clean()¶ • Clean (delete) the built docs. Specifically, this deletes the build directory under the docroot. See the html task for the options list.

  43. paver.doctools – Cog & SectionedFile • Solutions to common problems of creating high-quality docs • Ideally, your code samples will be in convenient runnable code files and have unit tests. • But you also want nice, minimal code samples in your text as you’re writing. • Ned Batchelder’s Cog (included with Paver) and paver.doctools.SectionedFile make these easy. • Not Sphinx-specific at all

  44. paver.doctools sample code • # mysample.py# [[[section mysample]]]defsample_func():print "To sample, or not to sample?"# [[[endsection]]]

  45. paver.doctools in docs • And then when you want to print the sample string, you just call:: • # [[[cog include(“code/mysample.py”, “mysample”)]]] • # [[[end]]]

  46. paver.doctools in docs (2) • And then when you want to print the sample string, you just call:: • # [[[cog include(“code/mysample.py”, “mysample”)]]] • def sample_func(): • print "To sample, or not to sample?" • # [[[end]]]

  47. paver.doctools uncog before commit • @task • @needs("uncog") • def commit(): • """Removes the generated code from the docs and then commits to bzr.""" • sh("bzr commit")

More Related