/usr/share/doc/python-pastescript/docs/developer.html is in python-pastescript 1.7.5-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Paste Script: Development — Paste Script v1.7.5 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.7.5',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Paste Script v1.7.5 documentation" href="index.html" />
<link rel="next" title="<no title>" href="license.html" />
<link rel="prev" title="News: Paste Script" href="news.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="license.html" title="<no title>"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="news.html" title="News: Paste Script"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Paste Script v1.7.5 documentation</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="paste-script-development">
<h1><a class="toc-backref" href="#id1">Paste Script: Development</a><a class="headerlink" href="#paste-script-development" title="Permalink to this headline">¶</a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">author:</th><td class="field-body">Ian Bicking <<a class="reference external" href="mailto:ianb%40colorstudy.com">ianb<span>@</span>colorstudy<span>.</span>com</a>></td>
</tr>
<tr class="field"><th class="field-name">revision:</th><td class="field-body">$Rev$</td>
</tr>
<tr class="field"><th class="field-name">date:</th><td class="field-body">$LastChangedDate$</td>
</tr>
</tbody>
</table>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#paste-script-development" id="id1">Paste Script: Development</a><ul>
<li><a class="reference internal" href="#introduction" id="id2">Introduction</a></li>
<li><a class="reference internal" href="#what-paste-script-can-do" id="id3">What Paste Script Can Do</a></li>
<li><a class="reference internal" href="#how-s-the-local-thing-work" id="id4">How’s the Local Thing Work?</a></li>
<li><a class="reference internal" href="#what-do-commands-look-like" id="id5">What Do Commands Look Like?</a></li>
<li><a class="reference internal" href="#templates" id="id6">Templates</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="introduction">
<h2><a class="toc-backref" href="#id2">Introduction</a><a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
<p>This document is an introduction to how you can extend <tt class="docutils literal"><span class="pre">paster</span></tt> and
Paste Script for your system – be it a framework, server setup, or
whatever else you want to do.</p>
</div>
<div class="section" id="what-paste-script-can-do">
<h2><a class="toc-backref" href="#id3">What Paste Script Can Do</a><a class="headerlink" href="#what-paste-script-can-do" title="Permalink to this headline">¶</a></h2>
<p><tt class="docutils literal"><span class="pre">paster</span></tt> is a two-level command, where the second level (e.g.,
<tt class="docutils literal"><span class="pre">paster</span> <span class="pre">help</span></tt>, <tt class="docutils literal"><span class="pre">paster</span> <span class="pre">create</span></tt>, etc) is pluggable.</p>
<p>Commands are attached to <a class="reference external" href="http://peak.telecommunity.com/DevCenter/PythonEggs">Python Eggs</a>, i.e., to the
package you distribute and someone installs. The commands are
identified using <a class="reference external" href="http://peak.telecommunity.com/DevCenter/setuptools#dynamic-discovery-of-services-and-plugins">entry points</a>.</p>
<p>To make your command available do something like this in your
<tt class="docutils literal"><span class="pre">setup.py</span></tt> file:</p>
<div class="highlight-python"><pre>from setuptools import setup
setup(...
entry_points="""
[paste.paster_command]
mycommand = mypackage.mycommand:MyCommand
[paste.global_paster_command]
myglobal = mypackage.myglobal:MyGlobalCommand
""")</pre>
</div>
<p>This means that <tt class="docutils literal"><span class="pre">paster</span> <span class="pre">mycommand</span></tt> will run the <tt class="docutils literal"><span class="pre">MyCommand</span></tt>
command located in the <tt class="docutils literal"><span class="pre">mypackage.mycommand</span></tt> module. Similarly with
<tt class="docutils literal"><span class="pre">paster</span> <span class="pre">myglobal</span></tt>. The distinction between these two entry points
is that the first will only be usable when <tt class="docutils literal"><span class="pre">paster</span></tt> is run inside a
project that is identified as using your project, while the second
will be globally available as a command as soon as your package is
installed.</p>
</div>
<div class="section" id="how-s-the-local-thing-work">
<h2><a class="toc-backref" href="#id4">How’s the Local Thing Work?</a><a class="headerlink" href="#how-s-the-local-thing-work" title="Permalink to this headline">¶</a></h2>
<p>So if you have a local command, how does it get enabled? If the
person is running <tt class="docutils literal"><span class="pre">paster</span></tt> inside their project directory,
<tt class="docutils literal"><span class="pre">paster</span></tt> will look in <tt class="docutils literal"><span class="pre">Project_Name.egg-info/paster_plugins.txt</span></tt>
which is a list of project names (the name of your package) whose
commands should be made available.</p>
<p>This is for frameworks, so frameworks can add commands to <tt class="docutils literal"><span class="pre">paster</span></tt>
that only apply to projects that use that framework.</p>
</div>
<div class="section" id="what-do-commands-look-like">
<h2><a class="toc-backref" href="#id5">What Do Commands Look Like?</a><a class="headerlink" href="#what-do-commands-look-like" title="Permalink to this headline">¶</a></h2>
<p>The command objects (like <tt class="docutils literal"><span class="pre">MyCommand</span></tt>) are subclasses of
<tt class="docutils literal"><span class="pre">paste.script.command.Command</span></tt>. You can look at that class to get
an idea, but a basic outline looks like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">paste.script</span> <span class="kn">import</span> <span class="n">command</span>
<span class="k">class</span> <span class="nc">MyCommand</span><span class="p">(</span><span class="n">command</span><span class="o">.</span><span class="n">Command</span><span class="p">):</span>
<span class="n">max_args</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">min_args</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">usage</span> <span class="o">=</span> <span class="s">"NAME"</span>
<span class="n">summary</span> <span class="o">=</span> <span class="s">"Say hello!"</span>
<span class="n">group_name</span> <span class="o">=</span> <span class="s">"My Package Name"</span>
<span class="n">parser</span> <span class="o">=</span> <span class="n">command</span><span class="o">.</span><span class="n">Command</span><span class="o">.</span><span class="n">standard_parser</span><span class="p">(</span><span class="n">verbose</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_option</span><span class="p">(</span><span class="s">'--goodbye'</span><span class="p">,</span>
<span class="n">action</span><span class="o">=</span><span class="s">'store_true'</span><span class="p">,</span>
<span class="n">dest</span><span class="o">=</span><span class="s">'goodbye'</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s">"Say 'Goodbye' instead"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">command</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbose</span><span class="p">:</span>
<span class="k">print</span> <span class="s">"Got name: </span><span class="si">%r</span><span class="s">"</span> <span class="o">%</span> <span class="n">name</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">goodbye</span><span class="p">:</span>
<span class="k">print</span> <span class="s">"Goodbye"</span><span class="p">,</span> <span class="n">name</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">print</span> <span class="s">"Hello"</span><span class="p">,</span> <span class="n">name</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">max_args</span></tt> and <tt class="docutils literal"><span class="pre">min_args</span></tt> are used to give error messages. You
can also raise <tt class="docutils literal"><span class="pre">command.BadCommand(msg)</span></tt> if the arguments are
incorrect in some way. (Use <tt class="xref docutils literal"><span class="pre">None</span></tt> here to give no restriction)</p>
<p>The <tt class="docutils literal"><span class="pre">usage</span></tt> variable means <tt class="docutils literal"><span class="pre">paster</span> <span class="pre">mycommand</span> <span class="pre">-h</span></tt> will give a usage
of <tt class="docutils literal"><span class="pre">paster</span> <span class="pre">mycommand</span> <span class="pre">[options]</span> <span class="pre">NAME</span></tt>. <tt class="docutils literal"><span class="pre">summary</span></tt> is used with
<tt class="docutils literal"><span class="pre">paster</span> <span class="pre">help</span></tt> (describing your command in a short form).
<tt class="docutils literal"><span class="pre">group_name</span></tt> is used to group commands together for <tt class="docutils literal"><span class="pre">paste</span> <span class="pre">help</span></tt>
under that title.</p>
<p>The <tt class="docutils literal"><span class="pre">parser</span></tt> object is an <cite>optparse
<http://python.org/doc/current/lib/module-optparse.html></cite>
<tt class="docutils literal"><span class="pre">OptionParser</span></tt> object. <tt class="docutils literal"><span class="pre">Command.standard_parser</span></tt> is a class
method that creates normal options, and enables options based on these
keyword (boolean) arguments: <tt class="docutils literal"><span class="pre">verbose</span></tt>, <tt class="docutils literal"><span class="pre">interactive</span></tt>,
<tt class="docutils literal"><span class="pre">no_interactive</span></tt> (if interactive is the default), <tt class="docutils literal"><span class="pre">simulate</span></tt>,
<tt class="docutils literal"><span class="pre">quiet</span></tt> (undoes verbose), and <tt class="docutils literal"><span class="pre">overwrite</span></tt>. You can create the
parser however you want, but using <tt class="docutils literal"><span class="pre">standard_parser()</span></tt> encourages a
consistent set of shared options across commands.</p>
<p>When your command is run, <tt class="docutils literal"><span class="pre">.command()</span></tt> is called. As you can see,
the options are in <tt class="docutils literal"><span class="pre">self.options</span></tt> and the positional arguments are
in <tt class="docutils literal"><span class="pre">self.args</span></tt>. Some options are turned into instance variables –
especially <tt class="docutils literal"><span class="pre">self.verbose</span></tt> and <tt class="docutils literal"><span class="pre">self.simulate</span></tt> (even if you haven’t
chosen to use those options, many methods expect to find some value
there, which is why they are turned into instance variables).</p>
<p>There are quite a few useful methods you can use in your command. See
the <a class="reference external" href="class-paste.script.command.Command.html">Command class</a> for a
complete list. Some particulars:</p>
<p><tt class="docutils literal"><span class="pre">run_command(cmd,</span> <span class="pre">arg1,</span> <span class="pre">arg2,</span> <span class="pre">...,</span> <span class="pre">cwd=os.getcwd(),</span> <span class="pre">capture_stderr=False)</span></tt>:</p>
<blockquote>
<div>Runs the command, respecting verbosity and simulation. Will raise
an error if the command doesn’t exit with a 0 code.</div></blockquote>
<p><tt class="docutils literal"><span class="pre">insert_into_file(filename,</span> <span class="pre">marker_name,</span> <span class="pre">text,</span> <span class="pre">indent=False)</span></tt>:</p>
<blockquote>
<div>Inserts a line of text into the file, looking for a marker like
<tt class="docutils literal"><span class="pre">-*-</span> <span class="pre">marker_name</span> <span class="pre">-*-</span></tt> (and inserting just after it). If
<tt class="docutils literal"><span class="pre">indent=True</span></tt>, then the line will be indented at the same level
as the marker line.</div></blockquote>
<p><tt class="docutils literal"><span class="pre">ensure_dir(dir,</span> <span class="pre">svn_add=True)</span></tt>:</p>
<blockquote>
<div>Ensures that the directory exists. If <tt class="docutils literal"><span class="pre">svn_add</span></tt> is true and the
parent directory has an <tt class="docutils literal"><span class="pre">.svn</span></tt> directory, add the new directory
to Subversion.</div></blockquote>
<p><tt class="docutils literal"><span class="pre">ensure_file(filename,</span> <span class="pre">content,</span> <span class="pre">svn_add=True)</span></tt>:</p>
<blockquote>
<div>Ensure the file exists with the given content. Will ask the user
before overwriting a file if <tt class="docutils literal"><span class="pre">--interactive</span></tt> has been given.</div></blockquote>
</div>
<div class="section" id="templates">
<h2><a class="toc-backref" href="#id6">Templates</a><a class="headerlink" href="#templates" title="Permalink to this headline">¶</a></h2>
<p>The other pluggable part is “templates”. These are used to create new
projects. Paste Script includes one template itself:
<tt class="docutils literal"><span class="pre">basic_package</span></tt> which creates a new setuptools package.</p>
<p>To enable, add to <tt class="docutils literal"><span class="pre">setup.py</span></tt>:</p>
<div class="highlight-python"><pre>setup(...
entry_points="""
[paste.paster_create_template]
framework = framework.templates:FrameworkTemplate
""")</pre>
</div>
<p><tt class="docutils literal"><span class="pre">FrameworkTemplate</span></tt> should be a subclass of
<tt class="docutils literal"><span class="pre">paste.script.templates.Template</span></tt>. An easy way to do this is simply
with:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">paste.script</span> <span class="kn">import</span> <span class="n">templates</span>
<span class="k">class</span> <span class="nc">FrameworkTemplate</span><span class="p">(</span><span class="n">templates</span><span class="o">.</span><span class="n">Template</span><span class="p">):</span>
<span class="n">egg_plugins</span> <span class="o">=</span> <span class="p">[</span><span class="s">'Framework'</span><span class="p">]</span>
<span class="n">summary</span> <span class="o">=</span> <span class="s">'Template for creating a basic Framework package'</span>
<span class="n">required_templates</span> <span class="o">=</span> <span class="p">[</span><span class="s">'basic_package'</span><span class="p">]</span>
<span class="n">_template_dir</span> <span class="o">=</span> <span class="s">'template'</span>
<span class="n">use_cheetah</span> <span class="o">=</span> <span class="bp">True</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">egg_plugins</span></tt> will add <tt class="docutils literal"><span class="pre">Framework</span></tt> to <tt class="docutils literal"><span class="pre">paste_plugins.txt</span></tt> in the
package. <tt class="docutils literal"><span class="pre">required_template</span></tt> means those template will be run
before this one (so in this case you’ll have a complete package ready,
and you can just write your framework files to it). <tt class="docutils literal"><span class="pre">_template_dir</span></tt>
is a module-relative directory to find your source files.</p>
<p>The source files are just a directory of files that will be copied
into place, potentially with variable substitutions. Three variables
are expected: <tt class="docutils literal"><span class="pre">project</span></tt> is the project name (e.g., <tt class="docutils literal"><span class="pre">Project-Name</span></tt>),
<tt class="docutils literal"><span class="pre">package</span></tt> is the Python package in that project (e.g.,
<tt class="docutils literal"><span class="pre">projectname</span></tt>) and <tt class="docutils literal"><span class="pre">egg</span></tt> is the project’s egg name as generated by
setuptools (e.g., <tt class="docutils literal"><span class="pre">Project_Name</span></tt>). Users can add other variables by
adding <tt class="docutils literal"><span class="pre">foo=bar</span></tt> arguments to <tt class="docutils literal"><span class="pre">paster</span> <span class="pre">create</span></tt>.</p>
<p>Filenames are substituted with <tt class="docutils literal"><span class="pre">+var_name+</span></tt>, e.g., <tt class="docutils literal"><span class="pre">+package+</span></tt> is
the package directory.</p>
<p>If a file in the template directory ends in <tt class="docutils literal"><span class="pre">_tmpl</span></tt> then it will be
substituted. If <tt class="docutils literal"><span class="pre">use_cheetah</span></tt> is true, then it’s treated as a
<a class="reference external" href="http://www.cheetahtemplate.org/">Cheetah</a> template. Otherwise
<a class="reference external" href="http://docs.python.org/library/string.html#template-strings">string.Template</a> is
used, though full expressions are allowed in <tt class="docutils literal"><span class="pre">${expr}</span></tt> instead of
just variables.</p>
<p>See the <a class="reference external" href="module-paste.script.templates.html">templates module</a> for
more.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Paste Script: Development</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#what-paste-script-can-do">What Paste Script Can Do</a></li>
<li><a class="reference internal" href="#how-s-the-local-thing-work">How’s the Local Thing Work?</a></li>
<li><a class="reference internal" href="#what-do-commands-look-like">What Do Commands Look Like?</a></li>
<li><a class="reference internal" href="#templates">Templates</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="news.html"
title="previous chapter">News: Paste Script</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="license.html"
title="next chapter"><no title></a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/developer.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="license.html" title="<no title>"
>next</a> |</li>
<li class="right" >
<a href="news.html" title="News: Paste Script"
>previous</a> |</li>
<li><a href="index.html">Paste Script v1.7.5 documentation</a> »</li>
</ul>
</div>
<div class="footer">
© Copyright 2011, Ian Bicking.
Last updated on Nov 09, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.8.
</div>
</body>
</html>
|