1479 lines
176 KiB
HTML
1479 lines
176 KiB
HTML
|
|
|
|
<!DOCTYPE html>
|
|
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
|
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
|
<head>
|
|
<meta charset="utf-8">
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
<title>pylorax.api.recipes — Lorax 32.2 documentation</title>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript" src="../../../_static/js/modernizr.min.js"></script>
|
|
|
|
|
|
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></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>
|
|
<script type="text/javascript" src="../../../_static/language_data.js"></script>
|
|
|
|
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
|
|
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
|
|
<link rel="index" title="Index" href="../../../genindex.html" />
|
|
<link rel="search" title="Search" href="../../../search.html" />
|
|
</head>
|
|
|
|
<body class="wy-body-for-nav">
|
|
|
|
|
|
<div class="wy-grid-for-nav">
|
|
|
|
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
|
<div class="wy-side-scroll">
|
|
<div class="wy-side-nav-search" >
|
|
|
|
|
|
|
|
<a href="../../../index.html" class="icon icon-home"> Lorax
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
<div class="version">
|
|
32.2
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div role="search">
|
|
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
|
|
<input type="text" name="q" placeholder="Search docs" />
|
|
<input type="hidden" name="check_keywords" value="yes" />
|
|
<input type="hidden" name="area" value="default" />
|
|
</form>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../mkksiso.html">mkksiso</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">src</a></li>
|
|
</ul>
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
|
|
|
|
|
<nav class="wy-nav-top" aria-label="top navigation">
|
|
|
|
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
|
<a href="../../../index.html">Lorax</a>
|
|
|
|
</nav>
|
|
|
|
|
|
<div class="wy-nav-content">
|
|
|
|
<div class="rst-content">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div role="navigation" aria-label="breadcrumbs navigation">
|
|
|
|
<ul class="wy-breadcrumbs">
|
|
|
|
<li><a href="../../../index.html">Docs</a> »</li>
|
|
|
|
<li><a href="../../index.html">Module code</a> »</li>
|
|
|
|
<li><a href="../../pylorax.html">pylorax</a> »</li>
|
|
|
|
<li>pylorax.api.recipes</li>
|
|
|
|
|
|
<li class="wy-breadcrumbs-aside">
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
|
|
<hr/>
|
|
</div>
|
|
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
<div itemprop="articleBody">
|
|
|
|
<h1>Source code for pylorax.api.recipes</h1><div class="highlight"><pre>
|
|
<span></span><span class="c1">#</span>
|
|
<span class="c1"># Copyright (C) 2017-2019 Red Hat, Inc.</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
|
|
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
|
|
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
|
|
<span class="c1"># (at your option) any later version.</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
|
|
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
|
|
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
|
|
<span class="c1"># GNU General Public License for more details.</span>
|
|
<span class="c1">#</span>
|
|
<span class="c1"># You should have received a copy of the GNU General Public License</span>
|
|
<span class="c1"># along with this program. If not, see <http://www.gnu.org/licenses/>.</span>
|
|
<span class="c1">#</span>
|
|
|
|
<span class="kn">import</span> <span class="nn">gi</span>
|
|
<span class="n">gi</span><span class="o">.</span><span class="n">require_version</span><span class="p">(</span><span class="s2">"Ggit"</span><span class="p">,</span> <span class="s2">"1.0"</span><span class="p">)</span>
|
|
<span class="kn">from</span> <span class="nn">gi.repository</span> <span class="k">import</span> <span class="n">Ggit</span> <span class="k">as</span> <span class="n">Git</span>
|
|
<span class="kn">from</span> <span class="nn">gi.repository</span> <span class="k">import</span> <span class="n">Gio</span>
|
|
<span class="kn">from</span> <span class="nn">gi.repository</span> <span class="k">import</span> <span class="n">GLib</span>
|
|
|
|
<span class="kn">import</span> <span class="nn">os</span>
|
|
<span class="kn">import</span> <span class="nn">semantic_version</span> <span class="k">as</span> <span class="nn">semver</span>
|
|
|
|
<span class="kn">from</span> <span class="nn">pylorax.api.projects</span> <span class="k">import</span> <span class="n">dep_evra</span>
|
|
<span class="kn">from</span> <span class="nn">pylorax.base</span> <span class="k">import</span> <span class="n">DataHolder</span>
|
|
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="k">import</span> <span class="n">joinpaths</span>
|
|
<span class="kn">import</span> <span class="nn">pylorax.api.toml</span> <span class="k">as</span> <span class="nn">toml</span>
|
|
|
|
|
|
<div class="viewcode-block" id="CommitTimeValError"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.CommitTimeValError">[docs]</a><span class="k">class</span> <span class="nc">CommitTimeValError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
<div class="viewcode-block" id="RecipeFileError"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipeFileError">[docs]</a><span class="k">class</span> <span class="nc">RecipeFileError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
<div class="viewcode-block" id="RecipeError"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipeError">[docs]</a><span class="k">class</span> <span class="nc">RecipeError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
|
|
<div class="viewcode-block" id="Recipe"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe">[docs]</a><span class="k">class</span> <span class="nc">Recipe</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
|
|
<span class="sd">"""A Recipe of package and modules</span>
|
|
|
|
<span class="sd"> This is a subclass of dict that enforces the constructor arguments</span>
|
|
<span class="sd"> and adds a .filename property to return the recipe's filename,</span>
|
|
<span class="sd"> and a .toml() function to return the recipe as a TOML string.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">description</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">modules</span><span class="p">,</span> <span class="n">packages</span><span class="p">,</span> <span class="n">groups</span><span class="p">,</span> <span class="n">customizations</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">gitrepos</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="c1"># Check that version is empty or semver compatible</span>
|
|
<span class="k">if</span> <span class="n">version</span><span class="p">:</span>
|
|
<span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="n">version</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Make sure modules, packages, and groups are listed by their case-insensitive names</span>
|
|
<span class="k">if</span> <span class="n">modules</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">modules</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">modules</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">m</span><span class="p">:</span> <span class="n">m</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
|
<span class="k">if</span> <span class="n">packages</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">packages</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">packages</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
|
<span class="k">if</span> <span class="n">groups</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">groups</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">groups</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">g</span><span class="p">:</span> <span class="n">g</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
|
|
|
<span class="c1"># Only support [[repos.git]] for now</span>
|
|
<span class="k">if</span> <span class="n">gitrepos</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">repos</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"git"</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">gitrepos</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">g</span><span class="p">:</span> <span class="n">g</span><span class="p">[</span><span class="s2">"repo"</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())}</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">repos</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="nb">dict</span><span class="o">.</span><span class="fm">__init__</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="n">name</span><span class="p">,</span>
|
|
<span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">,</span>
|
|
<span class="n">version</span><span class="o">=</span><span class="n">version</span><span class="p">,</span>
|
|
<span class="n">modules</span><span class="o">=</span><span class="n">modules</span><span class="p">,</span>
|
|
<span class="n">packages</span><span class="o">=</span><span class="n">packages</span><span class="p">,</span>
|
|
<span class="n">groups</span><span class="o">=</span><span class="n">groups</span><span class="p">,</span>
|
|
<span class="n">customizations</span><span class="o">=</span><span class="n">customizations</span><span class="p">,</span>
|
|
<span class="n">repos</span><span class="o">=</span><span class="n">repos</span><span class="p">)</span>
|
|
|
|
<span class="c1"># We don't want customizations=None to show up in the TOML so remove it</span>
|
|
<span class="k">if</span> <span class="n">customizations</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">del</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">]</span>
|
|
|
|
<span class="c1"># Don't include empty repos or repos.git</span>
|
|
<span class="k">if</span> <span class="n">repos</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">repos</span><span class="p">[</span><span class="s2">"git"</span><span class="p">]:</span>
|
|
<span class="k">del</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"repos"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">package_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Return the names of the packages"""</span>
|
|
<span class="k">return</span> <span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"packages"</span><span class="p">]</span> <span class="ow">or</span> <span class="p">[]]</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">package_nver</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Return the names and version globs of the packages"""</span>
|
|
<span class="k">return</span> <span class="p">[(</span><span class="n">p</span><span class="p">[</span><span class="s2">"name"</span><span class="p">],</span> <span class="n">p</span><span class="p">[</span><span class="s2">"version"</span><span class="p">])</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"packages"</span><span class="p">]</span> <span class="ow">or</span> <span class="p">[]]</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">module_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Return the names of the modules"""</span>
|
|
<span class="k">return</span> <span class="p">[</span><span class="n">m</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"modules"</span><span class="p">]</span> <span class="ow">or</span> <span class="p">[]]</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">module_nver</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Return the names and version globs of the modules"""</span>
|
|
<span class="k">return</span> <span class="p">[(</span><span class="n">m</span><span class="p">[</span><span class="s2">"name"</span><span class="p">],</span> <span class="n">m</span><span class="p">[</span><span class="s2">"version"</span><span class="p">])</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"modules"</span><span class="p">]</span> <span class="ow">or</span> <span class="p">[]]</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">group_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Return the names of the groups. Groups do not have versions."""</span>
|
|
<span class="k">return</span> <span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">g</span><span class="p">:</span> <span class="n">g</span><span class="p">[</span><span class="s2">"name"</span><span class="p">],</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"groups"</span><span class="p">]</span> <span class="ow">or</span> <span class="p">[])</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">filename</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Return the Recipe's filename</span>
|
|
|
|
<span class="sd"> Replaces spaces in the name with '-' and appends .toml</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"name"</span><span class="p">))</span>
|
|
|
|
<div class="viewcode-block" id="Recipe.toml"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe.toml">[docs]</a> <span class="k">def</span> <span class="nf">toml</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Return the Recipe in TOML format"""</span>
|
|
<span class="k">return</span> <span class="n">toml</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="Recipe.bump_version"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe.bump_version">[docs]</a> <span class="k">def</span> <span class="nf">bump_version</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">old_version</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""semver recipe version number bump</span>
|
|
|
|
<span class="sd"> :param old_version: An optional old version number</span>
|
|
<span class="sd"> :type old_version: str</span>
|
|
<span class="sd"> :returns: The new version number or None</span>
|
|
<span class="sd"> :rtype: str</span>
|
|
<span class="sd"> :raises: ValueError</span>
|
|
|
|
<span class="sd"> If neither have a version, 0.0.1 is returned</span>
|
|
<span class="sd"> If there is no old version the new version is checked and returned</span>
|
|
<span class="sd"> If there is no new version, but there is a old one, bump its patch level</span>
|
|
<span class="sd"> If the old and new versions are the same, bump the patch level</span>
|
|
<span class="sd"> If they are different, check and return the new version</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">new_version</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">new_version</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">old_version</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="p">[</span><span class="s2">"version"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"0.0.1"</span>
|
|
|
|
<span class="k">elif</span> <span class="n">new_version</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">old_version</span><span class="p">:</span>
|
|
<span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="n">new_version</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="p">[</span><span class="s2">"version"</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_version</span>
|
|
|
|
<span class="k">elif</span> <span class="ow">not</span> <span class="n">new_version</span> <span class="ow">or</span> <span class="n">new_version</span> <span class="o">==</span> <span class="n">old_version</span><span class="p">:</span>
|
|
<span class="n">new_version</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="n">old_version</span><span class="p">)</span><span class="o">.</span><span class="n">next_patch</span><span class="p">())</span>
|
|
<span class="bp">self</span><span class="p">[</span><span class="s2">"version"</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_version</span>
|
|
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="n">new_version</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="p">[</span><span class="s2">"version"</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_version</span>
|
|
|
|
<span class="c1"># Return the new version</span>
|
|
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="bp">self</span><span class="p">[</span><span class="s2">"version"</span><span class="p">]))</span></div>
|
|
|
|
<div class="viewcode-block" id="Recipe.freeze"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.Recipe.freeze">[docs]</a> <span class="k">def</span> <span class="nf">freeze</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">deps</span><span class="p">):</span>
|
|
<span class="sd">""" Return a new Recipe with full module and package NEVRA</span>
|
|
|
|
<span class="sd"> :param deps: A list of dependency NEVRA to use to fill in the modules and packages</span>
|
|
<span class="sd"> :type deps: list(</span>
|
|
<span class="sd"> :returns: A new Recipe object</span>
|
|
<span class="sd"> :rtype: Recipe</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">module_names</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">module_names</span>
|
|
<span class="n">package_names</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">package_names</span>
|
|
<span class="n">group_names</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">group_names</span>
|
|
|
|
<span class="n">new_modules</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">new_packages</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">new_groups</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">dep</span> <span class="ow">in</span> <span class="n">deps</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">dep</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="ow">in</span> <span class="n">package_names</span><span class="p">:</span>
|
|
<span class="n">new_packages</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">RecipePackage</span><span class="p">(</span><span class="n">dep</span><span class="p">[</span><span class="s2">"name"</span><span class="p">],</span> <span class="n">dep_evra</span><span class="p">(</span><span class="n">dep</span><span class="p">)))</span>
|
|
<span class="k">elif</span> <span class="n">dep</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="ow">in</span> <span class="n">module_names</span><span class="p">:</span>
|
|
<span class="n">new_modules</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">RecipeModule</span><span class="p">(</span><span class="n">dep</span><span class="p">[</span><span class="s2">"name"</span><span class="p">],</span> <span class="n">dep_evra</span><span class="p">(</span><span class="n">dep</span><span class="p">)))</span>
|
|
<span class="k">elif</span> <span class="n">dep</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="ow">in</span> <span class="n">group_names</span><span class="p">:</span>
|
|
<span class="n">new_groups</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">RecipeGroup</span><span class="p">(</span><span class="n">dep</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]))</span>
|
|
<span class="k">if</span> <span class="s2">"customizations"</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span>
|
|
<span class="n">customizations</span> <span class="o">=</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">customizations</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="s2">"repos"</span> <span class="ow">in</span> <span class="bp">self</span> <span class="ow">and</span> <span class="s2">"git"</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"repos"</span><span class="p">]:</span>
|
|
<span class="n">gitrepos</span> <span class="o">=</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"repos"</span><span class="p">][</span><span class="s2">"git"</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">gitrepos</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">return</span> <span class="n">Recipe</span><span class="p">(</span><span class="bp">self</span><span class="p">[</span><span class="s2">"name"</span><span class="p">],</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"description"</span><span class="p">],</span> <span class="bp">self</span><span class="p">[</span><span class="s2">"version"</span><span class="p">],</span>
|
|
<span class="n">new_modules</span><span class="p">,</span> <span class="n">new_packages</span><span class="p">,</span> <span class="n">new_groups</span><span class="p">,</span> <span class="n">customizations</span><span class="p">,</span> <span class="n">gitrepos</span><span class="p">)</span></div></div>
|
|
|
|
<div class="viewcode-block" id="RecipeModule"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipeModule">[docs]</a><span class="k">class</span> <span class="nc">RecipeModule</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
|
|
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">version</span><span class="p">):</span>
|
|
<span class="nb">dict</span><span class="o">.</span><span class="fm">__init__</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="n">name</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="n">version</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="RecipePackage"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipePackage">[docs]</a><span class="k">class</span> <span class="nc">RecipePackage</span><span class="p">(</span><span class="n">RecipeModule</span><span class="p">):</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
<div class="viewcode-block" id="RecipeGroup"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipeGroup">[docs]</a><span class="k">class</span> <span class="nc">RecipeGroup</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
|
|
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
|
|
<span class="nb">dict</span><span class="o">.</span><span class="fm">__init__</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="n">name</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="NewRecipeGit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.NewRecipeGit">[docs]</a><span class="k">def</span> <span class="nf">NewRecipeGit</span><span class="p">(</span><span class="n">toml_dict</span><span class="p">):</span>
|
|
<span class="sd">"""Create a RecipeGit object from fields in a TOML dict</span>
|
|
|
|
<span class="sd"> :param rpmname: Name of the rpm to create, also used as the prefix name in the tar archive</span>
|
|
<span class="sd"> :type rpmname: str</span>
|
|
<span class="sd"> :param rpmversion: Version of the rpm, eg. "1.0.0"</span>
|
|
<span class="sd"> :type rpmversion: str</span>
|
|
<span class="sd"> :param rpmrelease: Release of the rpm, eg. "1"</span>
|
|
<span class="sd"> :type rpmrelease: str</span>
|
|
<span class="sd"> :param summary: Summary string for the rpm</span>
|
|
<span class="sd"> :type summary: str</span>
|
|
<span class="sd"> :param repo: URL of the get repo to clone and create the archive from</span>
|
|
<span class="sd"> :type repo: str</span>
|
|
<span class="sd"> :param ref: Git reference to check out. eg. origin/branch-name, git tag, or git commit hash</span>
|
|
<span class="sd"> :type ref: str</span>
|
|
<span class="sd"> :param destination: Path to install the / of the git repo at when installing the rpm</span>
|
|
<span class="sd"> :type destination: str</span>
|
|
<span class="sd"> :returns: A populated RecipeGit object</span>
|
|
<span class="sd"> :rtype: RecipeGit</span>
|
|
|
|
<span class="sd"> The TOML should look like this::</span>
|
|
|
|
<span class="sd"> [[repos.git]]</span>
|
|
<span class="sd"> rpmname="server-config"</span>
|
|
<span class="sd"> rpmversion="1.0"</span>
|
|
<span class="sd"> rpmrelease="1"</span>
|
|
<span class="sd"> summary="Setup files for server deployment"</span>
|
|
<span class="sd"> repo="PATH OF GIT REPO TO CLONE"</span>
|
|
<span class="sd"> ref="v1.0"</span>
|
|
<span class="sd"> destination="/opt/server/"</span>
|
|
|
|
<span class="sd"> Note that the repo path supports anything that git supports, file://, https://, http://</span>
|
|
|
|
<span class="sd"> Currently there is no support for authentication</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">RecipeGit</span><span class="p">(</span><span class="n">toml_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"rpmname"</span><span class="p">),</span>
|
|
<span class="n">toml_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"rpmversion"</span><span class="p">),</span>
|
|
<span class="n">toml_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"rpmrelease"</span><span class="p">),</span>
|
|
<span class="n">toml_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"summary"</span><span class="p">,</span> <span class="s2">""</span><span class="p">),</span>
|
|
<span class="n">toml_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"repo"</span><span class="p">),</span>
|
|
<span class="n">toml_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"ref"</span><span class="p">),</span>
|
|
<span class="n">toml_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"destination"</span><span class="p">))</span></div>
|
|
|
|
<div class="viewcode-block" id="RecipeGit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.RecipeGit">[docs]</a><span class="k">class</span> <span class="nc">RecipeGit</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
|
|
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rpmname</span><span class="p">,</span> <span class="n">rpmversion</span><span class="p">,</span> <span class="n">rpmrelease</span><span class="p">,</span> <span class="n">summary</span><span class="p">,</span> <span class="n">repo</span><span class="p">,</span> <span class="n">ref</span><span class="p">,</span> <span class="n">destination</span><span class="p">):</span>
|
|
<span class="nb">dict</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rpmname</span><span class="o">=</span><span class="n">rpmname</span><span class="p">,</span> <span class="n">rpmversion</span><span class="o">=</span><span class="n">rpmversion</span><span class="p">,</span> <span class="n">rpmrelease</span><span class="o">=</span><span class="n">rpmrelease</span><span class="p">,</span>
|
|
<span class="n">summary</span><span class="o">=</span><span class="n">summary</span><span class="p">,</span> <span class="n">repo</span><span class="o">=</span><span class="n">repo</span><span class="p">,</span> <span class="n">ref</span><span class="o">=</span><span class="n">ref</span><span class="p">,</span> <span class="n">destination</span><span class="o">=</span><span class="n">destination</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="recipe_from_file"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_from_file">[docs]</a><span class="k">def</span> <span class="nf">recipe_from_file</span><span class="p">(</span><span class="n">recipe_path</span><span class="p">):</span>
|
|
<span class="sd">"""Return a recipe file as a Recipe object</span>
|
|
|
|
<span class="sd"> :param recipe_path: Path to the recipe fila</span>
|
|
<span class="sd"> :type recipe_path: str</span>
|
|
<span class="sd"> :returns: A Recipe object</span>
|
|
<span class="sd"> :rtype: Recipe</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">recipe_path</span><span class="p">,</span> <span class="s1">'rb'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">recipe_from_toml</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">())</span></div>
|
|
|
|
<div class="viewcode-block" id="recipe_from_toml"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_from_toml">[docs]</a><span class="k">def</span> <span class="nf">recipe_from_toml</span><span class="p">(</span><span class="n">recipe_str</span><span class="p">):</span>
|
|
<span class="sd">"""Create a Recipe object from a toml string.</span>
|
|
|
|
<span class="sd"> :param recipe_str: The Recipe TOML string</span>
|
|
<span class="sd"> :type recipe_str: str</span>
|
|
<span class="sd"> :returns: A Recipe object</span>
|
|
<span class="sd"> :rtype: Recipe</span>
|
|
<span class="sd"> :raises: TomlError</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">recipe_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">recipe_str</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">recipe_from_dict</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="check_required_list"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.check_required_list">[docs]</a><span class="k">def</span> <span class="nf">check_required_list</span><span class="p">(</span><span class="n">lst</span><span class="p">,</span> <span class="n">fields</span><span class="p">):</span>
|
|
<span class="sd">"""Check a list of dicts for required fields</span>
|
|
|
|
<span class="sd"> :param lst: A list of dicts with fields</span>
|
|
<span class="sd"> :type lst: list of dict</span>
|
|
<span class="sd"> :param fields: A list of field name strings</span>
|
|
<span class="sd"> :type fields: list of str</span>
|
|
<span class="sd"> :returns: A list of error strings</span>
|
|
<span class="sd"> :rtype: list of str</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">m</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">lst</span><span class="p">):</span>
|
|
<span class="n">m_errs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">check_list_case</span><span class="p">(</span><span class="n">fields</span><span class="p">,</span> <span class="n">m</span><span class="o">.</span><span class="n">keys</span><span class="p">(),</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">"</span><span class="si">%d</span><span class="s2"> "</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)))</span>
|
|
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">fields</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">f</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">m</span><span class="p">:</span>
|
|
<span class="n">m_errs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'</span><span class="si">%s</span><span class="s2">'"</span> <span class="o">%</span> <span class="n">f</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">m_errs</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"</span><span class="si">%d</span><span class="s2"> is missing </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">m_errs</span><span class="p">)))</span>
|
|
<span class="k">return</span> <span class="n">errors</span></div>
|
|
|
|
<div class="viewcode-block" id="check_list_case"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.check_list_case">[docs]</a><span class="k">def</span> <span class="nf">check_list_case</span><span class="p">(</span><span class="n">expected_keys</span><span class="p">,</span> <span class="n">recipe_keys</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">):</span>
|
|
<span class="sd">"""Check the case of the recipe keys</span>
|
|
|
|
<span class="sd"> :param expected_keys: A list of expected key strings</span>
|
|
<span class="sd"> :type expected_keys: list of str</span>
|
|
<span class="sd"> :param recipe_keys: A list of the recipe's key strings</span>
|
|
<span class="sd"> :type recipe_keys: list of str</span>
|
|
<span class="sd"> :returns: list of errors</span>
|
|
<span class="sd"> :rtype: list of str</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">recipe_keys</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">expected_keys</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="k">if</span> <span class="n">k</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="n">expected_keys</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">prefix</span> <span class="o">+</span> <span class="s2">"</span><span class="si">%s</span><span class="s2"> should be </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">k</span><span class="o">.</span><span class="n">lower</span><span class="p">()))</span>
|
|
<span class="k">return</span> <span class="n">errors</span></div>
|
|
|
|
<div class="viewcode-block" id="check_recipe_dict"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.check_recipe_dict">[docs]</a><span class="k">def</span> <span class="nf">check_recipe_dict</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">):</span>
|
|
<span class="sd">"""Check a dict before using it to create a new Recipe</span>
|
|
|
|
<span class="sd"> :param recipe_dict: A plain dict of the recipe</span>
|
|
<span class="sd"> :type recipe_dict: dict</span>
|
|
<span class="sd"> :returns: True if dict is ok</span>
|
|
<span class="sd"> :rtype: bool</span>
|
|
<span class="sd"> :raises: RecipeError</span>
|
|
|
|
<span class="sd"> This checks a dict to make sure required fields are present,</span>
|
|
<span class="sd"> that optional fields are correct, and that other optional fields</span>
|
|
<span class="sd"> are of the correct format, when included.</span>
|
|
|
|
<span class="sd"> This collects all of the errors and returns a single RecipeError with</span>
|
|
<span class="sd"> a string that can be presented to users.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="c1"># Check for wrong case of top level keys</span>
|
|
<span class="n">top_keys</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"name"</span><span class="p">,</span> <span class="s2">"description"</span><span class="p">,</span> <span class="s2">"version"</span><span class="p">,</span> <span class="s2">"modules"</span><span class="p">,</span> <span class="s2">"packages"</span><span class="p">,</span> <span class="s2">"groups"</span><span class="p">,</span> <span class="s2">"repos"</span><span class="p">,</span> <span class="s2">"customizations"</span><span class="p">]</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">check_list_case</span><span class="p">(</span><span class="n">recipe_dict</span><span class="o">.</span><span class="n">keys</span><span class="p">(),</span> <span class="n">top_keys</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="s2">"name"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">recipe_dict</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"Missing 'name'"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="s2">"description"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">recipe_dict</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"Missing 'description'"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="s2">"version"</span> <span class="ow">in</span> <span class="n">recipe_dict</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">semver</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"version"</span><span class="p">])</span>
|
|
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"Invalid 'version', must use Semantic Versioning"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Examine all the modules</span>
|
|
<span class="k">if</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"modules"</span><span class="p">):</span>
|
|
<span class="n">module_errors</span> <span class="o">=</span> <span class="n">check_required_list</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"modules"</span><span class="p">],</span> <span class="p">[</span><span class="s2">"name"</span><span class="p">,</span> <span class="s2">"version"</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="n">module_errors</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'modules' errors:</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">module_errors</span><span class="p">))</span>
|
|
|
|
<span class="c1"># Examine all the packages</span>
|
|
<span class="k">if</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"packages"</span><span class="p">):</span>
|
|
<span class="n">package_errors</span> <span class="o">=</span> <span class="n">check_required_list</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"packages"</span><span class="p">],</span> <span class="p">[</span><span class="s2">"name"</span><span class="p">,</span> <span class="s2">"version"</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="n">package_errors</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'packages' errors:</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">package_errors</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"groups"</span><span class="p">):</span>
|
|
<span class="n">groups_errors</span> <span class="o">=</span> <span class="n">check_required_list</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"groups"</span><span class="p">],</span> <span class="p">[</span><span class="s2">"name"</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="n">groups_errors</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'groups' errors:</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">groups_errors</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"repos"</span><span class="p">)</span> <span class="ow">and</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"repos"</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"git"</span><span class="p">):</span>
|
|
<span class="n">repos_errors</span> <span class="o">=</span> <span class="n">check_required_list</span><span class="p">(</span><span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"repos"</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"git"</span><span class="p">),</span>
|
|
<span class="p">[</span><span class="s2">"rpmname"</span><span class="p">,</span> <span class="s2">"rpmversion"</span><span class="p">,</span> <span class="s2">"rpmrelease"</span><span class="p">,</span> <span class="s2">"summary"</span><span class="p">,</span> <span class="s2">"repo"</span><span class="p">,</span> <span class="s2">"ref"</span><span class="p">,</span> <span class="s2">"destination"</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="n">repos_errors</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'repos.git' errors:</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">repos_errors</span><span class="p">))</span>
|
|
|
|
<span class="c1"># No customizations to check, exit now</span>
|
|
<span class="n">c</span> <span class="o">=</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"customizations"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">errors</span>
|
|
|
|
<span class="c1"># Make sure to catch empty sections by testing for keywords, not just looking at .get() result.</span>
|
|
<span class="k">if</span> <span class="s2">"kernel"</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">check_list_case</span><span class="p">([</span><span class="s2">"append"</span><span class="p">],</span> <span class="n">c</span><span class="p">[</span><span class="s2">"kernel"</span><span class="p">]</span><span class="o">.</span><span class="n">keys</span><span class="p">(),</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">"kernel "</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="s2">"append"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"kernel"</span><span class="p">,</span> <span class="p">[]):</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'customizations.kernel': missing append field."</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="s2">"sshkey"</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">sshkey_errors</span> <span class="o">=</span> <span class="n">check_required_list</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"sshkey"</span><span class="p">),</span> <span class="p">[</span><span class="s2">"user"</span><span class="p">,</span> <span class="s2">"key"</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="n">sshkey_errors</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'customizations.sshkey' errors:</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sshkey_errors</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="s2">"user"</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">user_errors</span> <span class="o">=</span> <span class="n">check_required_list</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"user"</span><span class="p">),</span> <span class="p">[</span><span class="s2">"name"</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="n">user_errors</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'customizations.user' errors:</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">user_errors</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="s2">"group"</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">group_errors</span> <span class="o">=</span> <span class="n">check_required_list</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"group"</span><span class="p">),</span> <span class="p">[</span><span class="s2">"name"</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="n">group_errors</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'customizations.group' errors:</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">group_errors</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="s2">"timezone"</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">check_list_case</span><span class="p">([</span><span class="s2">"timezone"</span><span class="p">,</span> <span class="s2">"ntpservers"</span><span class="p">],</span> <span class="n">c</span><span class="p">[</span><span class="s2">"timezone"</span><span class="p">]</span><span class="o">.</span><span class="n">keys</span><span class="p">(),</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">"timezone "</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"timezone"</span><span class="p">):</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'customizations.timezone': missing timezone or ntpservers fields."</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="s2">"locale"</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">check_list_case</span><span class="p">([</span><span class="s2">"languages"</span><span class="p">,</span> <span class="s2">"keyboard"</span><span class="p">],</span> <span class="n">c</span><span class="p">[</span><span class="s2">"locale"</span><span class="p">]</span><span class="o">.</span><span class="n">keys</span><span class="p">(),</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">"locale "</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"locale"</span><span class="p">):</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'customizations.locale': missing languages or keyboard fields."</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="s2">"firewall"</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">check_list_case</span><span class="p">([</span><span class="s2">"ports"</span><span class="p">],</span> <span class="n">c</span><span class="p">[</span><span class="s2">"firewall"</span><span class="p">]</span><span class="o">.</span><span class="n">keys</span><span class="p">(),</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">"firewall "</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"firewall"</span><span class="p">):</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'customizations.firewall': missing ports field or services section."</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="s2">"services"</span> <span class="ow">in</span> <span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"firewall"</span><span class="p">,</span> <span class="p">[]):</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">check_list_case</span><span class="p">([</span><span class="s2">"enabled"</span><span class="p">,</span> <span class="s2">"disabled"</span><span class="p">],</span> <span class="n">c</span><span class="p">[</span><span class="s2">"firewall"</span><span class="p">][</span><span class="s2">"services"</span><span class="p">]</span><span class="o">.</span><span class="n">keys</span><span class="p">(),</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">"firewall.services "</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"firewall"</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"services"</span><span class="p">):</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'customizations.firewall.services': missing enabled or disabled fields."</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="s2">"services"</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">check_list_case</span><span class="p">([</span><span class="s2">"enabled"</span><span class="p">,</span> <span class="s2">"disabled"</span><span class="p">],</span> <span class="n">c</span><span class="p">[</span><span class="s2">"services"</span><span class="p">]</span><span class="o">.</span><span class="n">keys</span><span class="p">(),</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">"services "</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"services"</span><span class="p">):</span>
|
|
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"'customizations.services': missing enabled or disabled fields."</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">errors</span></div>
|
|
|
|
<div class="viewcode-block" id="recipe_from_dict"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_from_dict">[docs]</a><span class="k">def</span> <span class="nf">recipe_from_dict</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">):</span>
|
|
<span class="sd">"""Create a Recipe object from a plain dict.</span>
|
|
|
|
<span class="sd"> :param recipe_dict: A plain dict of the recipe</span>
|
|
<span class="sd"> :type recipe_dict: dict</span>
|
|
<span class="sd"> :returns: A Recipe object</span>
|
|
<span class="sd"> :rtype: Recipe</span>
|
|
<span class="sd"> :raises: RecipeError</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">errors</span> <span class="o">=</span> <span class="n">check_recipe_dict</span><span class="p">(</span><span class="n">recipe_dict</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">errors</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">errors</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="n">RecipeError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Make RecipeModule objects from the toml</span>
|
|
<span class="c1"># The TOML may not have modules or packages in it. Set them to None in this case</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"modules"</span><span class="p">):</span>
|
|
<span class="n">modules</span> <span class="o">=</span> <span class="p">[</span><span class="n">RecipeModule</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"name"</span><span class="p">),</span> <span class="n">m</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">))</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"modules"</span><span class="p">]]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">modules</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"packages"</span><span class="p">):</span>
|
|
<span class="n">packages</span> <span class="o">=</span> <span class="p">[</span><span class="n">RecipePackage</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"name"</span><span class="p">),</span> <span class="n">p</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">))</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"packages"</span><span class="p">]]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">packages</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"groups"</span><span class="p">):</span>
|
|
<span class="n">groups</span> <span class="o">=</span> <span class="p">[</span><span class="n">RecipeGroup</span><span class="p">(</span><span class="n">g</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"name"</span><span class="p">))</span> <span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"groups"</span><span class="p">]]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">groups</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"repos"</span><span class="p">)</span> <span class="ow">and</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"repos"</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"git"</span><span class="p">):</span>
|
|
<span class="n">gitrepos</span> <span class="o">=</span> <span class="p">[</span><span class="n">NewRecipeGit</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"repos"</span><span class="p">][</span><span class="s2">"git"</span><span class="p">]]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">gitrepos</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span>
|
|
<span class="n">description</span> <span class="o">=</span> <span class="n">recipe_dict</span><span class="p">[</span><span class="s2">"description"</span><span class="p">]</span>
|
|
<span class="n">version</span> <span class="o">=</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">customizations</span> <span class="o">=</span> <span class="n">recipe_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"customizations"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
|
|
<span class="c1"># [customizations] was incorrectly documented at first, so we have to support using it</span>
|
|
<span class="c1"># as [[customizations]] by grabbing the first element.</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">customizations</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
|
|
<span class="n">customizations</span> <span class="o">=</span> <span class="n">customizations</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
|
|
<span class="k">except</span> <span class="ne">KeyError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">RecipeError</span><span class="p">(</span><span class="s2">"There was a problem parsing the recipe: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
|
|
|
|
<span class="k">return</span> <span class="n">Recipe</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">description</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">modules</span><span class="p">,</span> <span class="n">packages</span><span class="p">,</span> <span class="n">groups</span><span class="p">,</span> <span class="n">customizations</span><span class="p">,</span> <span class="n">gitrepos</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="gfile"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.gfile">[docs]</a><span class="k">def</span> <span class="nf">gfile</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
|
|
<span class="sd">"""Convert a string path to GFile for use with Git"""</span>
|
|
<span class="k">return</span> <span class="n">Gio</span><span class="o">.</span><span class="n">file_new_for_path</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="recipe_filename"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_filename">[docs]</a><span class="k">def</span> <span class="nf">recipe_filename</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
|
|
<span class="sd">"""Return the toml filename for a recipe</span>
|
|
|
|
<span class="sd"> Replaces spaces with '-' and appends '.toml'</span>
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># XXX Raise and error if this is empty?</span>
|
|
<span class="k">return</span> <span class="n">name</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">" "</span><span class="p">,</span> <span class="s2">"-"</span><span class="p">)</span> <span class="o">+</span> <span class="s2">".toml"</span></div>
|
|
|
|
<div class="viewcode-block" id="head_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.head_commit">[docs]</a><span class="k">def</span> <span class="nf">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">):</span>
|
|
<span class="sd">"""Get the branch's HEAD Commit Object</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :returns: Branch's head commit</span>
|
|
<span class="sd"> :rtype: Git.Commit</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">branch_obj</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup_branch</span><span class="p">(</span><span class="n">branch</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">BranchType</span><span class="o">.</span><span class="n">LOCAL</span><span class="p">)</span>
|
|
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">branch_obj</span><span class="o">.</span><span class="n">get_target</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="prepare_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.prepare_commit">[docs]</a><span class="k">def</span> <span class="nf">prepare_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">builder</span><span class="p">):</span>
|
|
<span class="sd">"""Prepare for a commit</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param builder: instance of TreeBuilder</span>
|
|
<span class="sd"> :type builder: TreeBuilder</span>
|
|
<span class="sd"> :returns: (Tree, Sig, Ref)</span>
|
|
<span class="sd"> :rtype: tuple</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">tree_id</span> <span class="o">=</span> <span class="n">builder</span><span class="o">.</span><span class="n">write</span><span class="p">()</span>
|
|
<span class="n">tree</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">tree_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Tree</span><span class="p">)</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Signature</span><span class="o">.</span><span class="n">new_now</span><span class="p">(</span><span class="s2">"bdcs-api-server"</span><span class="p">,</span> <span class="s2">"user-email"</span><span class="p">)</span>
|
|
<span class="n">ref</span> <span class="o">=</span> <span class="s2">"refs/heads/</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">branch</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">ref</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="open_or_create_repo"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.open_or_create_repo">[docs]</a><span class="k">def</span> <span class="nf">open_or_create_repo</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
|
|
<span class="sd">"""Open an existing repo, or create a new one</span>
|
|
|
|
<span class="sd"> :param path: path to recipe directory</span>
|
|
<span class="sd"> :type path: string</span>
|
|
<span class="sd"> :returns: A repository object</span>
|
|
<span class="sd"> :rtype: Git.Repository</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
|
|
<span class="sd"> A bare git repo will be created in the git directory of the specified path.</span>
|
|
<span class="sd"> If a repo already exists it will be opened and returned instead of</span>
|
|
<span class="sd"> creating a new one.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">Git</span><span class="o">.</span><span class="n">init</span><span class="p">()</span>
|
|
<span class="n">git_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s2">"git"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">git_path</span><span class="p">,</span> <span class="s2">"HEAD"</span><span class="p">)):</span>
|
|
<span class="k">return</span> <span class="n">Git</span><span class="o">.</span><span class="n">Repository</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">gfile</span><span class="p">(</span><span class="n">git_path</span><span class="p">))</span>
|
|
|
|
<span class="n">repo</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Repository</span><span class="o">.</span><span class="n">init_repository</span><span class="p">(</span><span class="n">gfile</span><span class="p">(</span><span class="n">git_path</span><span class="p">),</span> <span class="kc">True</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Make an initial empty commit</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Signature</span><span class="o">.</span><span class="n">new_now</span><span class="p">(</span><span class="s2">"bdcs-api-server"</span><span class="p">,</span> <span class="s2">"user-email"</span><span class="p">)</span>
|
|
<span class="n">tree_id</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">get_index</span><span class="p">()</span><span class="o">.</span><span class="n">write_tree</span><span class="p">()</span>
|
|
<span class="n">tree</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">tree_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Tree</span><span class="p">)</span>
|
|
<span class="n">repo</span><span class="o">.</span><span class="n">create_commit</span><span class="p">(</span><span class="s2">"HEAD"</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="s2">"UTF-8"</span><span class="p">,</span> <span class="s2">"Initial Recipe repository commit"</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="p">[])</span>
|
|
<span class="k">return</span> <span class="n">repo</span></div>
|
|
|
|
<div class="viewcode-block" id="write_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.write_commit">[docs]</a><span class="k">def</span> <span class="nf">write_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
|
|
<span class="sd">"""Make a new commit to a repository's branch</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param filename: full path of the file to add</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :param message: The commit message</span>
|
|
<span class="sd"> :type message: str</span>
|
|
<span class="sd"> :param content: The data to write</span>
|
|
<span class="sd"> :type content: str</span>
|
|
<span class="sd"> :returns: OId of the new commit</span>
|
|
<span class="sd"> :rtype: Git.OId</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="n">GLib</span><span class="o">.</span><span class="n">GError</span><span class="p">:</span>
|
|
<span class="c1"># Branch doesn't exist, make a new one based on master</span>
|
|
<span class="n">master_head</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="s2">"master"</span><span class="p">)</span>
|
|
<span class="n">repo</span><span class="o">.</span><span class="n">create_branch</span><span class="p">(</span><span class="n">branch</span><span class="p">,</span> <span class="n">master_head</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
|
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
|
|
|
|
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
|
|
<span class="n">blob_id</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_blob_from_buffer</span><span class="p">(</span><span class="n">content</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"UTF-8"</span><span class="p">))</span>
|
|
|
|
<span class="c1"># Use treebuilder to make a new entry for this filename and blob</span>
|
|
<span class="n">parent_tree</span> <span class="o">=</span> <span class="n">parent_commit</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
|
|
<span class="n">builder</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_tree_builder_from_tree</span><span class="p">(</span><span class="n">parent_tree</span><span class="p">)</span>
|
|
<span class="n">builder</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">blob_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">FileMode</span><span class="o">.</span><span class="n">BLOB</span><span class="p">)</span>
|
|
<span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">ref</span><span class="p">)</span> <span class="o">=</span> <span class="n">prepare_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">builder</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_commit</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="s2">"UTF-8"</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="p">[</span><span class="n">parent_commit</span><span class="p">])</span></div>
|
|
|
|
<div class="viewcode-block" id="read_commit_spec"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.read_commit_spec">[docs]</a><span class="k">def</span> <span class="nf">read_commit_spec</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">spec</span><span class="p">):</span>
|
|
<span class="sd">"""Return the raw content of the blob specified by the spec</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param spec: Git revparse spec</span>
|
|
<span class="sd"> :type spec: str</span>
|
|
<span class="sd"> :returns: Contents of the commit</span>
|
|
<span class="sd"> :rtype: str</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
|
|
<span class="sd"> eg. To read the README file from master the spec is "master:README"</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">revparse</span><span class="p">(</span><span class="n">spec</span><span class="p">)</span><span class="o">.</span><span class="n">get_id</span><span class="p">()</span>
|
|
<span class="n">blob</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Blob</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">blob</span><span class="o">.</span><span class="n">get_raw_content</span><span class="p">()</span></div>
|
|
|
|
<div class="viewcode-block" id="read_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.read_commit">[docs]</a><span class="k">def</span> <span class="nf">read_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">commit</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""Return the contents of a file on a specific branch or commit.</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param filename: filename to read</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :param commit: Optional commit hash</span>
|
|
<span class="sd"> :type commit: str</span>
|
|
<span class="sd"> :returns: The commit id, and the contents of the commit</span>
|
|
<span class="sd"> :rtype: tuple(str, str)</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
|
|
<span class="sd"> If no commit is passed the master:filename is returned, otherwise it will be</span>
|
|
<span class="sd"> commit:filename</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">commit</span><span class="p">:</span>
|
|
<span class="c1"># Find the most recent commit for filename on the selected branch</span>
|
|
<span class="n">commits</span> <span class="o">=</span> <span class="n">list_commits</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">commits</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">RecipeError</span><span class="p">(</span><span class="s2">"No commits for </span><span class="si">%s</span><span class="s2"> on the </span><span class="si">%s</span><span class="s2"> branch."</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">branch</span><span class="p">))</span>
|
|
<span class="n">commit</span> <span class="o">=</span> <span class="n">commits</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">commit</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">commit</span><span class="p">,</span> <span class="n">read_commit_spec</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">commit</span><span class="p">,</span> <span class="n">filename</span><span class="p">)))</span></div>
|
|
|
|
<div class="viewcode-block" id="read_recipe_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.read_recipe_commit">[docs]</a><span class="k">def</span> <span class="nf">read_recipe_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">,</span> <span class="n">commit</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""Read a recipe commit from git and return a Recipe object</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param recipe_name: Recipe name to read</span>
|
|
<span class="sd"> :type recipe_name: str</span>
|
|
<span class="sd"> :param commit: Optional commit hash</span>
|
|
<span class="sd"> :type commit: str</span>
|
|
<span class="sd"> :returns: A Recipe object</span>
|
|
<span class="sd"> :rtype: Recipe</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
|
|
<span class="sd"> If no commit is passed the master:filename is returned, otherwise it will be</span>
|
|
<span class="sd"> commit:filename</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">repo_file_exists</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">)):</span>
|
|
<span class="k">raise</span> <span class="n">RecipeFileError</span><span class="p">(</span><span class="s2">"Unknown blueprint"</span><span class="p">)</span>
|
|
|
|
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="n">recipe_toml</span><span class="p">)</span> <span class="o">=</span> <span class="n">read_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">),</span> <span class="n">commit</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">recipe_from_toml</span><span class="p">(</span><span class="n">recipe_toml</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="read_recipe_and_id"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.read_recipe_and_id">[docs]</a><span class="k">def</span> <span class="nf">read_recipe_and_id</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">,</span> <span class="n">commit</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""Read a recipe commit and its id from git</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param recipe_name: Recipe name to read</span>
|
|
<span class="sd"> :type recipe_name: str</span>
|
|
<span class="sd"> :param commit: Optional commit hash</span>
|
|
<span class="sd"> :type commit: str</span>
|
|
<span class="sd"> :returns: The commit id, and a Recipe object</span>
|
|
<span class="sd"> :rtype: tuple(str, Recipe)</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
|
|
<span class="sd"> If no commit is passed the master:filename is returned, otherwise it will be</span>
|
|
<span class="sd"> commit:filename</span>
|
|
<span class="sd"> """</span>
|
|
<span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">recipe_toml</span><span class="p">)</span> <span class="o">=</span> <span class="n">read_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">),</span> <span class="n">commit</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">recipe_from_toml</span><span class="p">(</span><span class="n">recipe_toml</span><span class="p">))</span></div>
|
|
|
|
<div class="viewcode-block" id="list_branch_files"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.list_branch_files">[docs]</a><span class="k">def</span> <span class="nf">list_branch_files</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">):</span>
|
|
<span class="sd">"""Return a sorted list of the files on the branch HEAD</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :returns: A sorted list of the filenames</span>
|
|
<span class="sd"> :rtype: list(str)</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span><span class="o">.</span><span class="n">get_id</span><span class="p">()</span><span class="o">.</span><span class="n">to_string</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="n">list_commit_files</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">commit</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="list_commit_files"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.list_commit_files">[docs]</a><span class="k">def</span> <span class="nf">list_commit_files</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">commit</span><span class="p">):</span>
|
|
<span class="sd">"""Return a sorted list of the files on a commit</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param commit: The commit hash to list</span>
|
|
<span class="sd"> :type commit: str</span>
|
|
<span class="sd"> :returns: A sorted list of the filenames</span>
|
|
<span class="sd"> :rtype: list(str)</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">OId</span><span class="o">.</span><span class="n">new_from_string</span><span class="p">(</span><span class="n">commit</span><span class="p">)</span>
|
|
<span class="n">commit_obj</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
|
|
<span class="n">tree</span> <span class="o">=</span> <span class="n">commit_obj</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="nb">sorted</span><span class="p">([</span><span class="n">tree</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="o">.</span><span class="n">get_name</span><span class="p">()</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">tree</span><span class="o">.</span><span class="n">size</span><span class="p">())])</span></div>
|
|
|
|
<div class="viewcode-block" id="delete_recipe"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.delete_recipe">[docs]</a><span class="k">def</span> <span class="nf">delete_recipe</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">):</span>
|
|
<span class="sd">"""Delete a recipe from a branch.</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param recipe_name: Recipe name to delete</span>
|
|
<span class="sd"> :type recipe_name: str</span>
|
|
<span class="sd"> :returns: OId of the new commit</span>
|
|
<span class="sd"> :rtype: Git.OId</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">delete_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">))</span></div>
|
|
|
|
<div class="viewcode-block" id="delete_file"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.delete_file">[docs]</a><span class="k">def</span> <span class="nf">delete_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
|
|
<span class="sd">"""Delete a file from a branch.</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param filename: filename to delete</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :returns: OId of the new commit</span>
|
|
<span class="sd"> :rtype: Git.OId</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
|
|
<span class="n">parent_tree</span> <span class="o">=</span> <span class="n">parent_commit</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
|
|
<span class="n">builder</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_tree_builder_from_tree</span><span class="p">(</span><span class="n">parent_tree</span><span class="p">)</span>
|
|
<span class="n">builder</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
|
|
<span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">ref</span><span class="p">)</span> <span class="o">=</span> <span class="n">prepare_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">builder</span><span class="p">)</span>
|
|
<span class="n">message</span> <span class="o">=</span> <span class="s2">"Recipe </span><span class="si">%s</span><span class="s2"> deleted"</span> <span class="o">%</span> <span class="n">filename</span>
|
|
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_commit</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="s2">"UTF-8"</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="p">[</span><span class="n">parent_commit</span><span class="p">])</span></div>
|
|
|
|
<div class="viewcode-block" id="revert_recipe"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.revert_recipe">[docs]</a><span class="k">def</span> <span class="nf">revert_recipe</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">,</span> <span class="n">commit</span><span class="p">):</span>
|
|
<span class="sd">"""Revert the contents of a recipe to that of a previous commit</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param recipe_name: Recipe name to revert</span>
|
|
<span class="sd"> :type recipe_name: str</span>
|
|
<span class="sd"> :param commit: Commit hash</span>
|
|
<span class="sd"> :type commit: str</span>
|
|
<span class="sd"> :returns: OId of the new commit</span>
|
|
<span class="sd"> :rtype: Git.OId</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">revert_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">),</span> <span class="n">commit</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="revert_file"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.revert_file">[docs]</a><span class="k">def</span> <span class="nf">revert_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">commit</span><span class="p">):</span>
|
|
<span class="sd">"""Revert the contents of a file to that of a previous commit</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param filename: filename to revert</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :param commit: Commit hash</span>
|
|
<span class="sd"> :type commit: str</span>
|
|
<span class="sd"> :returns: OId of the new commit</span>
|
|
<span class="sd"> :rtype: Git.OId</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">OId</span><span class="o">.</span><span class="n">new_from_string</span><span class="p">(</span><span class="n">commit</span><span class="p">)</span>
|
|
<span class="n">commit_obj</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
|
|
<span class="n">revert_tree</span> <span class="o">=</span> <span class="n">commit_obj</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
|
|
<span class="n">entry</span> <span class="o">=</span> <span class="n">revert_tree</span><span class="o">.</span><span class="n">get_by_name</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
|
|
<span class="n">blob_id</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">get_id</span><span class="p">()</span>
|
|
<span class="n">parent_commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Use treebuilder to modify the tree</span>
|
|
<span class="n">parent_tree</span> <span class="o">=</span> <span class="n">parent_commit</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
|
|
<span class="n">builder</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_tree_builder_from_tree</span><span class="p">(</span><span class="n">parent_tree</span><span class="p">)</span>
|
|
<span class="n">builder</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">blob_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">FileMode</span><span class="o">.</span><span class="n">BLOB</span><span class="p">)</span>
|
|
<span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">ref</span><span class="p">)</span> <span class="o">=</span> <span class="n">prepare_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">builder</span><span class="p">)</span>
|
|
<span class="n">commit_hash</span> <span class="o">=</span> <span class="n">commit_id</span><span class="o">.</span><span class="n">to_string</span><span class="p">()</span>
|
|
<span class="n">message</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s</span><span class="s2"> reverted to commit </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">commit_hash</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_commit</span><span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="s2">"UTF-8"</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="p">[</span><span class="n">parent_commit</span><span class="p">])</span></div>
|
|
|
|
<div class="viewcode-block" id="commit_recipe"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.commit_recipe">[docs]</a><span class="k">def</span> <span class="nf">commit_recipe</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="p">):</span>
|
|
<span class="sd">"""Commit a recipe to a branch</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param recipe: Recipe to commit</span>
|
|
<span class="sd"> :type recipe: Recipe</span>
|
|
<span class="sd"> :returns: OId of the new commit</span>
|
|
<span class="sd"> :rtype: Git.OId</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">old_recipe</span> <span class="o">=</span> <span class="n">read_recipe_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="p">[</span><span class="s2">"name"</span><span class="p">])</span>
|
|
<span class="n">old_version</span> <span class="o">=</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s2">"version"</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="n">old_version</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="n">recipe</span><span class="o">.</span><span class="n">bump_version</span><span class="p">(</span><span class="n">old_version</span><span class="p">)</span>
|
|
<span class="n">recipe_toml</span> <span class="o">=</span> <span class="n">recipe</span><span class="o">.</span><span class="n">toml</span><span class="p">()</span>
|
|
<span class="n">message</span> <span class="o">=</span> <span class="s2">"Recipe </span><span class="si">%s</span><span class="s2">, version </span><span class="si">%s</span><span class="s2"> saved."</span> <span class="o">%</span> <span class="p">(</span><span class="n">recipe</span><span class="p">[</span><span class="s2">"name"</span><span class="p">],</span> <span class="n">recipe</span><span class="p">[</span><span class="s2">"version"</span><span class="p">])</span>
|
|
<span class="k">return</span> <span class="n">write_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">recipe_toml</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="commit_recipe_file"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.commit_recipe_file">[docs]</a><span class="k">def</span> <span class="nf">commit_recipe_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
|
|
<span class="sd">"""Commit a recipe file to a branch</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param filename: Path to the recipe file to commit</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :returns: OId of the new commit</span>
|
|
<span class="sd"> :rtype: Git.OId</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit or RecipeFileError</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">recipe</span> <span class="o">=</span> <span class="n">recipe_from_file</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">RecipeFileError</span>
|
|
|
|
<span class="k">return</span> <span class="n">commit_recipe</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="commit_recipe_directory"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.commit_recipe_directory">[docs]</a><span class="k">def</span> <span class="nf">commit_recipe_directory</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">directory</span><span class="p">):</span>
|
|
<span class="sa">r</span><span class="sd">"""Commit all \*.toml files from a directory, if they aren't already in git.</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param directory: The directory of \*.toml recipes to commit</span>
|
|
<span class="sd"> :type directory: str</span>
|
|
<span class="sd"> :returns: None</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit or RecipeFileError</span>
|
|
|
|
<span class="sd"> Files with Toml or RecipeFileErrors will be skipped, and the remainder will</span>
|
|
<span class="sd"> be tried.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">dir_files</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="n">e</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">directory</span><span class="p">)</span> <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">".toml"</span><span class="p">)])</span>
|
|
<span class="n">branch_files</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">list_branch_files</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">))</span>
|
|
<span class="n">new_files</span> <span class="o">=</span> <span class="n">dir_files</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">branch_files</span><span class="p">)</span>
|
|
|
|
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">new_files</span><span class="p">:</span>
|
|
<span class="c1"># Skip files with errors, but try the others</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">commit_recipe_file</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">directory</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="n">RecipeError</span><span class="p">,</span> <span class="n">RecipeFileError</span><span class="p">,</span> <span class="n">toml</span><span class="o">.</span><span class="n">TomlError</span><span class="p">):</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
<div class="viewcode-block" id="tag_recipe_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.tag_recipe_commit">[docs]</a><span class="k">def</span> <span class="nf">tag_recipe_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">):</span>
|
|
<span class="sd">"""Tag a file's most recent commit</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param recipe_name: Recipe name to tag</span>
|
|
<span class="sd"> :type recipe_name: str</span>
|
|
<span class="sd"> :returns: Tag id or None if it failed.</span>
|
|
<span class="sd"> :rtype: Git.OId</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
|
|
<span class="sd"> Uses tag_file_commit()</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">repo_file_exists</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">)):</span>
|
|
<span class="k">raise</span> <span class="n">RecipeFileError</span><span class="p">(</span><span class="s2">"Unknown blueprint"</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">tag_file_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">))</span></div>
|
|
|
|
<div class="viewcode-block" id="tag_file_commit"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.tag_file_commit">[docs]</a><span class="k">def</span> <span class="nf">tag_file_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
|
|
<span class="sd">"""Tag a file's most recent commit</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param filename: Filename to tag</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :returns: Tag id or None if it failed.</span>
|
|
<span class="sd"> :rtype: Git.OId</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
|
|
<span class="sd"> This uses git tags, of the form `refs/tags/<branch>/<filename>/r<revision>`</span>
|
|
<span class="sd"> Only the most recent recipe commit can be tagged to prevent out of order tagging.</span>
|
|
<span class="sd"> Revisions start at 1 and increment for each new commit that is tagged.</span>
|
|
<span class="sd"> If the commit has already been tagged it will return false.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">file_commits</span> <span class="o">=</span> <span class="n">list_commits</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">file_commits</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># Find the most recently tagged version (may not be one) and add 1 to it.</span>
|
|
<span class="k">for</span> <span class="n">details</span> <span class="ow">in</span> <span class="n">file_commits</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">details</span><span class="o">.</span><span class="n">revision</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">new_revision</span> <span class="o">=</span> <span class="n">details</span><span class="o">.</span><span class="n">revision</span> <span class="o">+</span> <span class="mi">1</span>
|
|
<span class="k">break</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">new_revision</span> <span class="o">=</span> <span class="mi">1</span>
|
|
|
|
<span class="n">name</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">/</span><span class="si">%s</span><span class="s2">/r</span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">new_revision</span><span class="p">)</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Signature</span><span class="o">.</span><span class="n">new_now</span><span class="p">(</span><span class="s2">"bdcs-api-server"</span><span class="p">,</span> <span class="s2">"user-email"</span><span class="p">)</span>
|
|
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">OId</span><span class="o">.</span><span class="n">new_from_string</span><span class="p">(</span><span class="n">file_commits</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">commit</span><span class="p">)</span>
|
|
<span class="n">commit</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">repo</span><span class="o">.</span><span class="n">create_tag</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">commit</span><span class="p">,</span> <span class="n">sig</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">CreateFlags</span><span class="o">.</span><span class="n">NONE</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="find_commit_tag"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.find_commit_tag">[docs]</a><span class="k">def</span> <span class="nf">find_commit_tag</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">commit_id</span><span class="p">):</span>
|
|
<span class="sd">"""Find the tag that matches the commit_id</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param filename: filename to revert</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :param commit_id: The commit id to check</span>
|
|
<span class="sd"> :type commit_id: Git.OId</span>
|
|
<span class="sd"> :returns: The tag or None if there isn't one</span>
|
|
<span class="sd"> :rtype: str or None</span>
|
|
|
|
<span class="sd"> There should be only 1 tag pointing to a commit, but there may not</span>
|
|
<span class="sd"> be a tag at all.</span>
|
|
|
|
<span class="sd"> The tag will look like: 'refs/tags/<branch>/<filename>/r<revision>'</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">pattern</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">/</span><span class="si">%s</span><span class="s2">/r*"</span> <span class="o">%</span> <span class="p">(</span><span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
|
|
<span class="n">tags</span> <span class="o">=</span> <span class="p">[</span><span class="n">t</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">repo</span><span class="o">.</span><span class="n">list_tags_match</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span> <span class="k">if</span> <span class="n">is_commit_tag</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">commit_id</span><span class="p">,</span> <span class="n">t</span><span class="p">)]</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">tags</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">tags</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></div>
|
|
|
|
<div class="viewcode-block" id="is_commit_tag"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.is_commit_tag">[docs]</a><span class="k">def</span> <span class="nf">is_commit_tag</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">commit_id</span><span class="p">,</span> <span class="n">tag</span><span class="p">):</span>
|
|
<span class="sd">"""Check to see if a tag points to a specific commit.</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param commit_id: The commit id to check</span>
|
|
<span class="sd"> :type commit_id: Git.OId</span>
|
|
<span class="sd"> :param tag: The tag to check</span>
|
|
<span class="sd"> :type tag: str</span>
|
|
<span class="sd"> :returns: True if the tag points to the commit, False otherwise</span>
|
|
<span class="sd"> :rtype: bool</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">ref</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup_reference</span><span class="p">(</span><span class="s2">"refs/tags/"</span> <span class="o">+</span> <span class="n">tag</span><span class="p">)</span>
|
|
<span class="n">tag_id</span> <span class="o">=</span> <span class="n">ref</span><span class="o">.</span><span class="n">get_target</span><span class="p">()</span>
|
|
<span class="n">tag</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">tag_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Tag</span><span class="p">)</span>
|
|
<span class="n">target_id</span> <span class="o">=</span> <span class="n">tag</span><span class="o">.</span><span class="n">get_target_id</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="n">commit_id</span><span class="o">.</span><span class="n">compare</span><span class="p">(</span><span class="n">target_id</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span></div>
|
|
|
|
<div class="viewcode-block" id="get_revision_from_tag"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.get_revision_from_tag">[docs]</a><span class="k">def</span> <span class="nf">get_revision_from_tag</span><span class="p">(</span><span class="n">tag</span><span class="p">):</span>
|
|
<span class="sd">"""Return the revision number from a tag</span>
|
|
|
|
<span class="sd"> :param tag: The tag to exract the revision from</span>
|
|
<span class="sd"> :type tag: str</span>
|
|
<span class="sd"> :returns: The integer revision or None</span>
|
|
<span class="sd"> :rtype: int or None</span>
|
|
|
|
<span class="sd"> The revision is the part after the r in 'branch/filename/rXXX'</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">tag</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">tag</span><span class="o">.</span><span class="n">rsplit</span><span class="p">(</span><span class="s1">'r'</span><span class="p">,</span> <span class="mi">2</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">None</span></div>
|
|
|
|
<div class="viewcode-block" id="CommitDetails"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.CommitDetails">[docs]</a><span class="k">class</span> <span class="nc">CommitDetails</span><span class="p">(</span><span class="n">DataHolder</span><span class="p">):</span>
|
|
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">commit</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">revision</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="n">DataHolder</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
|
|
<span class="n">commit</span> <span class="o">=</span> <span class="n">commit</span><span class="p">,</span>
|
|
<span class="n">timestamp</span> <span class="o">=</span> <span class="n">timestamp</span><span class="p">,</span>
|
|
<span class="n">message</span> <span class="o">=</span> <span class="n">message</span><span class="p">,</span>
|
|
<span class="n">revision</span> <span class="o">=</span> <span class="n">revision</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="list_commits"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.list_commits">[docs]</a><span class="k">def</span> <span class="nf">list_commits</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">limit</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
|
|
<span class="sd">"""List the commit history of a file on a branch.</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param filename: filename to revert</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :param limit: Number of commits to return (0=all)</span>
|
|
<span class="sd"> :type limit: int</span>
|
|
<span class="sd"> :returns: A list of commit details</span>
|
|
<span class="sd"> :rtype: list(CommitDetails)</span>
|
|
<span class="sd"> :raises: Can raise errors from Ggit</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">revwalk</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">RevisionWalker</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">repo</span><span class="p">)</span>
|
|
<span class="n">branch_ref</span> <span class="o">=</span> <span class="s2">"refs/heads/</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">branch</span>
|
|
<span class="n">revwalk</span><span class="o">.</span><span class="n">push_ref</span><span class="p">(</span><span class="n">branch_ref</span><span class="p">)</span>
|
|
|
|
<span class="n">commits</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
|
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">revwalk</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">commit_id</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
<span class="n">commit</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
|
|
|
|
<span class="n">parents</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_parents</span><span class="p">()</span>
|
|
<span class="c1"># No parents? Must be the first commit.</span>
|
|
<span class="k">if</span> <span class="n">parents</span><span class="o">.</span><span class="n">get_size</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="n">tree</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
|
|
<span class="c1"># Is the filename in this tree? If not, move on.</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">tree</span><span class="o">.</span><span class="n">get_by_name</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="c1"># Is filename different in all of the parent commits?</span>
|
|
<span class="n">parent_commits</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">parents</span><span class="o">.</span><span class="n">get</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">parents</span><span class="o">.</span><span class="n">get_size</span><span class="p">())))</span>
|
|
<span class="n">is_diff</span> <span class="o">=</span> <span class="nb">all</span><span class="p">([</span><span class="n">is_parent_diff</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="n">pc</span><span class="p">)</span> <span class="k">for</span> <span class="n">pc</span> <span class="ow">in</span> <span class="n">parent_commits</span><span class="p">])</span>
|
|
<span class="c1"># No changes from parents, skip it.</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_diff</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="n">tag</span> <span class="o">=</span> <span class="n">find_commit_tag</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_id</span><span class="p">())</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">commits</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">get_commit_details</span><span class="p">(</span><span class="n">commit</span><span class="p">,</span> <span class="n">get_revision_from_tag</span><span class="p">(</span><span class="n">tag</span><span class="p">)))</span>
|
|
<span class="k">if</span> <span class="n">limit</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">commits</span><span class="p">)</span> <span class="o">></span> <span class="n">limit</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
<span class="k">except</span> <span class="n">CommitTimeValError</span><span class="p">:</span>
|
|
<span class="c1"># Skip any commits that have trouble converting the time</span>
|
|
<span class="c1"># TODO - log details about this failure</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="c1"># These will be in reverse time sort order thanks to revwalk</span>
|
|
<span class="k">return</span> <span class="n">commits</span></div>
|
|
|
|
<div class="viewcode-block" id="get_commit_details"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.get_commit_details">[docs]</a><span class="k">def</span> <span class="nf">get_commit_details</span><span class="p">(</span><span class="n">commit</span><span class="p">,</span> <span class="n">revision</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""Return the details about a specific commit.</span>
|
|
|
|
<span class="sd"> :param commit: The commit to get details from</span>
|
|
<span class="sd"> :type commit: Git.Commit</span>
|
|
<span class="sd"> :param revision: Optional commit revision</span>
|
|
<span class="sd"> :type revision: int</span>
|
|
<span class="sd"> :returns: Details about the commit</span>
|
|
<span class="sd"> :rtype: CommitDetails</span>
|
|
<span class="sd"> :raises: CommitTimeValError or Ggit exceptions</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">message</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_message</span><span class="p">()</span>
|
|
<span class="n">commit_str</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_id</span><span class="p">()</span><span class="o">.</span><span class="n">to_string</span><span class="p">()</span>
|
|
<span class="n">sig</span> <span class="o">=</span> <span class="n">commit</span><span class="o">.</span><span class="n">get_committer</span><span class="p">()</span>
|
|
|
|
<span class="n">datetime</span> <span class="o">=</span> <span class="n">sig</span><span class="o">.</span><span class="n">get_time</span><span class="p">()</span>
|
|
<span class="c1"># XXX What do we do with timezone?</span>
|
|
<span class="n">_timezone</span> <span class="o">=</span> <span class="n">sig</span><span class="o">.</span><span class="n">get_time_zone</span><span class="p">()</span>
|
|
<span class="n">timeval</span> <span class="o">=</span> <span class="n">GLib</span><span class="o">.</span><span class="n">TimeVal</span><span class="p">()</span>
|
|
<span class="n">ok</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">to_timeval</span><span class="p">(</span><span class="n">timeval</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">ok</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">CommitTimeValError</span>
|
|
<span class="n">time_str</span> <span class="o">=</span> <span class="n">timeval</span><span class="o">.</span><span class="n">to_iso8601</span><span class="p">()</span>
|
|
|
|
<span class="k">return</span> <span class="n">CommitDetails</span><span class="p">(</span><span class="n">commit_str</span><span class="p">,</span> <span class="n">time_str</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">revision</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="is_parent_diff"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.is_parent_diff">[docs]</a><span class="k">def</span> <span class="nf">is_parent_diff</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">tree</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
|
|
<span class="sd">"""Check to see if the commit is different from its parents</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param filename: filename to revert</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :param tree: The commit's tree</span>
|
|
<span class="sd"> :type tree: Git.Tree</span>
|
|
<span class="sd"> :param parent: The commit's parent commit</span>
|
|
<span class="sd"> :type parent: Git.Commit</span>
|
|
<span class="sd"> :retuns: True if filename in the commit is different from its parents</span>
|
|
<span class="sd"> :rtype: bool</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">diff_opts</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">DiffOptions</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
|
|
<span class="n">diff_opts</span><span class="o">.</span><span class="n">set_pathspec</span><span class="p">([</span><span class="n">filename</span><span class="p">])</span>
|
|
<span class="n">diff</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">Diff</span><span class="o">.</span><span class="n">new_tree_to_tree</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">parent</span><span class="o">.</span><span class="n">get_tree</span><span class="p">(),</span> <span class="n">tree</span><span class="p">,</span> <span class="n">diff_opts</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">diff</span><span class="o">.</span><span class="n">get_num_deltas</span><span class="p">()</span> <span class="o">></span> <span class="mi">0</span></div>
|
|
|
|
<div class="viewcode-block" id="find_field_value"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.find_field_value">[docs]</a><span class="k">def</span> <span class="nf">find_field_value</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">lst</span><span class="p">):</span>
|
|
<span class="sd">"""Find a field matching value in the list of dicts.</span>
|
|
|
|
<span class="sd"> :param field: field to search for</span>
|
|
<span class="sd"> :type field: str</span>
|
|
<span class="sd"> :param value: value to match in the field</span>
|
|
<span class="sd"> :type value: str</span>
|
|
<span class="sd"> :param lst: List of dict's with field</span>
|
|
<span class="sd"> :type lst: list of dict</span>
|
|
<span class="sd"> :returns: First dict with matching field:value, or None</span>
|
|
<span class="sd"> :rtype: dict or None</span>
|
|
|
|
<span class="sd"> Used to return a specific entry from a list that looks like this:</span>
|
|
|
|
<span class="sd"> [{"name": "one", "attr": "green"}, ...]</span>
|
|
|
|
<span class="sd"> find_field_value("name", "one", lst) will return the matching dict.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">lst</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">d</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">field</span><span class="p">)</span> <span class="ow">and</span> <span class="n">d</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="n">value</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">d</span>
|
|
<span class="k">return</span> <span class="kc">None</span></div>
|
|
|
|
<div class="viewcode-block" id="find_name"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.find_name">[docs]</a><span class="k">def</span> <span class="nf">find_name</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">lst</span><span class="p">):</span>
|
|
<span class="sd">"""Find the dict matching the name in a list and return it.</span>
|
|
|
|
<span class="sd"> :param name: Name to search for</span>
|
|
<span class="sd"> :type name: str</span>
|
|
<span class="sd"> :param lst: List of dict's with "name" field</span>
|
|
<span class="sd"> :type lst: list of dict</span>
|
|
<span class="sd"> :returns: First dict with matching name, or None</span>
|
|
<span class="sd"> :rtype: dict or None</span>
|
|
|
|
<span class="sd"> This is just a wrapper for find_field_value with field set to "name"</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">find_field_value</span><span class="p">(</span><span class="s2">"name"</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">lst</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="find_recipe_obj"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.find_recipe_obj">[docs]</a><span class="k">def</span> <span class="nf">find_recipe_obj</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">recipe</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""Find a recipe object</span>
|
|
|
|
<span class="sd"> :param path: A list of dict field names</span>
|
|
<span class="sd"> :type path: list of str</span>
|
|
<span class="sd"> :param recipe: The recipe to search</span>
|
|
<span class="sd"> :type recipe: Recipe</span>
|
|
<span class="sd"> :param default: The value to return if it is not found</span>
|
|
<span class="sd"> :type default: Any</span>
|
|
|
|
<span class="sd"> Return the object found by applying the path to the dicts in the recipe, or</span>
|
|
<span class="sd"> return the default if it doesn't exist.</span>
|
|
|
|
<span class="sd"> eg. {"customizations": {"hostname": "foo", "users": [...]}}</span>
|
|
|
|
<span class="sd"> find_recipe_obj(["customizations", "hostname"], recipe, "")</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">o</span> <span class="o">=</span> <span class="n">recipe</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">path</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">o</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">p</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">default</span>
|
|
<span class="n">o</span> <span class="o">=</span> <span class="n">o</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">default</span>
|
|
|
|
<span class="k">return</span> <span class="n">o</span></div>
|
|
|
|
<div class="viewcode-block" id="diff_lists"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.diff_lists">[docs]</a><span class="k">def</span> <span class="nf">diff_lists</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">field</span><span class="p">,</span> <span class="n">old_items</span><span class="p">,</span> <span class="n">new_items</span><span class="p">):</span>
|
|
<span class="sd">"""Return the differences between two lists of dicts.</span>
|
|
|
|
<span class="sd"> :param title: Title of the entry</span>
|
|
<span class="sd"> :type title: str</span>
|
|
<span class="sd"> :param field: Field to use as the key for comparisons</span>
|
|
<span class="sd"> :type field: str</span>
|
|
<span class="sd"> :param old_items: List of item dicts with "name" field</span>
|
|
<span class="sd"> :type old_items: list(dict)</span>
|
|
<span class="sd"> :param new_items: List of item dicts with "name" field</span>
|
|
<span class="sd"> :type new_items: list(dict)</span>
|
|
<span class="sd"> :returns: List of diff dicts with old/new entries</span>
|
|
<span class="sd"> :rtype: list(dict)</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">diffs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">old_fields</span><span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">m</span><span class="p">[</span><span class="n">field</span><span class="p">]</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">old_items</span><span class="p">)</span>
|
|
<span class="n">new_fields</span><span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">m</span><span class="p">[</span><span class="n">field</span><span class="p">]</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">new_items</span><span class="p">)</span>
|
|
|
|
<span class="n">added_items</span> <span class="o">=</span> <span class="n">new_fields</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">old_fields</span><span class="p">)</span>
|
|
<span class="n">added_items</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">added_items</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
|
|
|
<span class="n">removed_items</span> <span class="o">=</span> <span class="n">old_fields</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">new_fields</span><span class="p">)</span>
|
|
<span class="n">removed_items</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">removed_items</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
|
|
|
<span class="n">same_items</span> <span class="o">=</span> <span class="n">old_fields</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">new_fields</span><span class="p">)</span>
|
|
<span class="n">same_items</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">same_items</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
|
|
|
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">added_items</span><span class="p">:</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">"old"</span><span class="p">:</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="s2">"new"</span><span class="p">:{</span><span class="n">title</span><span class="p">:</span><span class="n">find_field_value</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">new_items</span><span class="p">)}})</span>
|
|
|
|
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">removed_items</span><span class="p">:</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">"old"</span><span class="p">:{</span><span class="n">title</span><span class="p">:</span><span class="n">find_field_value</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">old_items</span><span class="p">)},</span>
|
|
<span class="s2">"new"</span><span class="p">:</span><span class="kc">None</span><span class="p">})</span>
|
|
|
|
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">same_items</span><span class="p">:</span>
|
|
<span class="n">old_item</span> <span class="o">=</span> <span class="n">find_field_value</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">old_items</span><span class="p">)</span>
|
|
<span class="n">new_item</span> <span class="o">=</span> <span class="n">find_field_value</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">new_items</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">old_item</span> <span class="o">!=</span> <span class="n">new_item</span><span class="p">:</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">"old"</span><span class="p">:{</span><span class="n">title</span><span class="p">:</span><span class="n">old_item</span><span class="p">},</span>
|
|
<span class="s2">"new"</span><span class="p">:{</span><span class="n">title</span><span class="p">:</span><span class="n">new_item</span><span class="p">}})</span>
|
|
|
|
<span class="k">return</span> <span class="n">diffs</span></div>
|
|
|
|
<div class="viewcode-block" id="customizations_diff"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.customizations_diff">[docs]</a><span class="k">def</span> <span class="nf">customizations_diff</span><span class="p">(</span><span class="n">old_recipe</span><span class="p">,</span> <span class="n">new_recipe</span><span class="p">):</span>
|
|
<span class="sd">"""Diff the customizations sections from two versions of a recipe</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">diffs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">old_keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">old_recipe</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"customizations"</span><span class="p">,</span> <span class="p">{})</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
<span class="n">new_keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">new_recipe</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"customizations"</span><span class="p">,</span> <span class="p">{})</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
|
|
<span class="n">added_keys</span> <span class="o">=</span> <span class="n">new_keys</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">old_keys</span><span class="p">)</span>
|
|
<span class="n">added_keys</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">added_keys</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
|
|
|
<span class="n">removed_keys</span> <span class="o">=</span> <span class="n">old_keys</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">new_keys</span><span class="p">)</span>
|
|
<span class="n">removed_keys</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">removed_keys</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
|
|
|
<span class="n">same_keys</span> <span class="o">=</span> <span class="n">old_keys</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">new_keys</span><span class="p">)</span>
|
|
<span class="n">same_keys</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">same_keys</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
|
|
|
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">added_keys</span><span class="p">:</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">"old"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="s2">"new"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"Customizations."</span><span class="o">+</span><span class="n">v</span><span class="p">:</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">]}})</span>
|
|
|
|
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">removed_keys</span><span class="p">:</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">"old"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"Customizations."</span><span class="o">+</span><span class="n">v</span><span class="p">:</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">]},</span>
|
|
<span class="s2">"new"</span><span class="p">:</span> <span class="kc">None</span><span class="p">})</span>
|
|
|
|
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">same_keys</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">]</span> <span class="o">==</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">]:</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">new_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">])</span> <span class="o">==</span> <span class="nb">type</span><span class="p">([]):</span>
|
|
<span class="c1"># Lists of dicts need to use diff_lists</span>
|
|
<span class="c1"># sshkey uses 'user', user and group use 'name'</span>
|
|
<span class="k">if</span> <span class="s2">"user"</span> <span class="ow">in</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">][</span><span class="mi">0</span><span class="p">]:</span>
|
|
<span class="n">field_name</span> <span class="o">=</span> <span class="s2">"user"</span>
|
|
<span class="k">elif</span> <span class="s2">"name"</span> <span class="ow">in</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">][</span><span class="mi">0</span><span class="p">]:</span>
|
|
<span class="n">field_name</span> <span class="o">=</span> <span class="s2">"name"</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2"> list has unrecognized key, not 'name' or 'user'"</span> <span class="o">%</span> <span class="s2">"customizations."</span><span class="o">+</span><span class="n">v</span><span class="p">)</span>
|
|
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">diff_lists</span><span class="p">(</span><span class="s2">"Customizations."</span><span class="o">+</span><span class="n">v</span><span class="p">,</span> <span class="n">field_name</span><span class="p">,</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">],</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">]))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">"old"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"Customizations."</span><span class="o">+</span><span class="n">v</span><span class="p">:</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">]},</span>
|
|
<span class="s2">"new"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"Customizations."</span><span class="o">+</span><span class="n">v</span><span class="p">:</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s2">"customizations"</span><span class="p">][</span><span class="n">v</span><span class="p">]}})</span>
|
|
|
|
<span class="k">return</span> <span class="n">diffs</span></div>
|
|
|
|
|
|
<div class="viewcode-block" id="recipe_diff"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.recipe_diff">[docs]</a><span class="k">def</span> <span class="nf">recipe_diff</span><span class="p">(</span><span class="n">old_recipe</span><span class="p">,</span> <span class="n">new_recipe</span><span class="p">):</span>
|
|
<span class="sd">"""Diff two versions of a recipe</span>
|
|
|
|
<span class="sd"> :param old_recipe: The old version of the recipe</span>
|
|
<span class="sd"> :type old_recipe: Recipe</span>
|
|
<span class="sd"> :param new_recipe: The new version of the recipe</span>
|
|
<span class="sd"> :type new_recipe: Recipe</span>
|
|
<span class="sd"> :returns: A list of diff dict entries with old/new</span>
|
|
<span class="sd"> :rtype: list(dict)</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">diffs</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="c1"># These cannot be added or removed, just different</span>
|
|
<span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"name"</span><span class="p">,</span> <span class="s2">"description"</span><span class="p">,</span> <span class="s2">"version"</span><span class="p">]:</span>
|
|
<span class="k">if</span> <span class="n">old_recipe</span><span class="p">[</span><span class="n">element</span><span class="p">]</span> <span class="o">!=</span> <span class="n">new_recipe</span><span class="p">[</span><span class="n">element</span><span class="p">]:</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">"old"</span><span class="p">:{</span><span class="n">element</span><span class="o">.</span><span class="n">title</span><span class="p">():</span><span class="n">old_recipe</span><span class="p">[</span><span class="n">element</span><span class="p">]},</span>
|
|
<span class="s2">"new"</span><span class="p">:{</span><span class="n">element</span><span class="o">.</span><span class="n">title</span><span class="p">():</span><span class="n">new_recipe</span><span class="p">[</span><span class="n">element</span><span class="p">]}})</span>
|
|
|
|
<span class="c1"># These lists always exist</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">diff_lists</span><span class="p">(</span><span class="s2">"Module"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">,</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s2">"modules"</span><span class="p">],</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s2">"modules"</span><span class="p">]))</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">diff_lists</span><span class="p">(</span><span class="s2">"Package"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">,</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s2">"packages"</span><span class="p">],</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s2">"packages"</span><span class="p">]))</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">diff_lists</span><span class="p">(</span><span class="s2">"Group"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">,</span> <span class="n">old_recipe</span><span class="p">[</span><span class="s2">"groups"</span><span class="p">],</span> <span class="n">new_recipe</span><span class="p">[</span><span class="s2">"groups"</span><span class="p">]))</span>
|
|
|
|
<span class="c1"># The customizations section can contain a number of different types</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">customizations_diff</span><span class="p">(</span><span class="n">old_recipe</span><span class="p">,</span> <span class="n">new_recipe</span><span class="p">))</span>
|
|
|
|
<span class="c1"># repos contains keys that are lists (eg. [[repos.git]])</span>
|
|
<span class="n">diffs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">diff_lists</span><span class="p">(</span><span class="s2">"Repos.git"</span><span class="p">,</span> <span class="s2">"rpmname"</span><span class="p">,</span>
|
|
<span class="n">find_recipe_obj</span><span class="p">([</span><span class="s2">"repos"</span><span class="p">,</span> <span class="s2">"git"</span><span class="p">],</span> <span class="n">old_recipe</span><span class="p">,</span> <span class="p">[]),</span>
|
|
<span class="n">find_recipe_obj</span><span class="p">([</span><span class="s2">"repos"</span><span class="p">,</span> <span class="s2">"git"</span><span class="p">],</span> <span class="n">new_recipe</span><span class="p">,</span> <span class="p">[])))</span>
|
|
|
|
<span class="k">return</span> <span class="n">diffs</span></div>
|
|
|
|
<div class="viewcode-block" id="repo_file_exists"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.recipes.repo_file_exists">[docs]</a><span class="k">def</span> <span class="nf">repo_file_exists</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
|
|
<span class="sd">"""Return True if the filename exists on the branch</span>
|
|
|
|
<span class="sd"> :param repo: Open repository</span>
|
|
<span class="sd"> :type repo: Git.Repository</span>
|
|
<span class="sd"> :param branch: Branch name</span>
|
|
<span class="sd"> :type branch: str</span>
|
|
<span class="sd"> :param filename: Filename to check</span>
|
|
<span class="sd"> :type filename: str</span>
|
|
<span class="sd"> :returns: True if the filename exists on the HEAD of the branch, False otherwise.</span>
|
|
<span class="sd"> :rtype: bool</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">commit</span> <span class="o">=</span> <span class="n">head_commit</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span><span class="o">.</span><span class="n">get_id</span><span class="p">()</span><span class="o">.</span><span class="n">to_string</span><span class="p">()</span>
|
|
<span class="n">commit_id</span> <span class="o">=</span> <span class="n">Git</span><span class="o">.</span><span class="n">OId</span><span class="o">.</span><span class="n">new_from_string</span><span class="p">(</span><span class="n">commit</span><span class="p">)</span>
|
|
<span class="n">commit_obj</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">Git</span><span class="o">.</span><span class="n">Commit</span><span class="p">)</span>
|
|
<span class="n">tree</span> <span class="o">=</span> <span class="n">commit_obj</span><span class="o">.</span><span class="n">get_tree</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="n">tree</span><span class="o">.</span><span class="n">get_by_name</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span></div>
|
|
</pre></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
<footer>
|
|
|
|
|
|
<hr/>
|
|
|
|
<div role="contentinfo">
|
|
<p>
|
|
© Copyright 2018, Red Hat, Inc.
|
|
|
|
</p>
|
|
</div>
|
|
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
|
|
|
</footer>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</section>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
jQuery(function () {
|
|
SphinxRtdTheme.Navigation.enable(true);
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</body>
|
|
</html> |