aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJauhien Piatlicki (jauhien) <piatlicki@gmail.com>2013-08-06 22:09:28 +0200
committerJauhien Piatlicki (jauhien) <piatlicki@gmail.com>2013-08-06 22:09:28 +0200
commit4d158c383f10ccc177b93ffeecaff3fce33b1691 (patch)
tree36704efe2cafb0e166697924a9e7fddcb0201bf6
parentREADME.md: github code highlighting (diff)
downloadg-sorcery-4d158c383f10ccc177b93ffeecaff3fce33b1691.tar.gz
g-sorcery-4d158c383f10ccc177b93ffeecaff3fce33b1691.tar.bz2
g-sorcery-4d158c383f10ccc177b93ffeecaff3fce33b1691.zip
Developer instructions
-rw-r--r--README.md4
-rw-r--r--docs/Makefile13
-rw-r--r--docs/developer_instructions.html946
-rw-r--r--docs/developer_instructions.rst640
4 files changed, 1599 insertions, 4 deletions
diff --git a/README.md b/README.md
index caa3a7e..dcd8553 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ Installation and using
======================
At the moment upstream layman does not support g-sorcery overlay type.
-You should patch it with `https://raw.github.com/jauhien/g-sorcery/master/layman-git-g-sorcery.patch`.
+You should [patch it](https://raw.github.com/jauhien/g-sorcery/master/layman-git-g-sorcery.patch).
To do it download above mentioned patch, place it in
**/etc/portage/patches/app-portage/layman-9999/** directory and
@@ -120,3 +120,5 @@ all in one overlay. Note, that if you call **generate-tree** command your overla
will be wiped and overlay tree for a given repository will be generated. Be careful!
See man pages of **gs-elpa** and **gs-ctan** for further information.
+
+If you want to develop a new backend see [developer's instructions](./docs/developer_instructions.html).
diff --git a/docs/Makefile b/docs/Makefile
index c42c78d..19b6458 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,9 +1,16 @@
-SOURCES=g-sorcery gs-elpa gs-ctan
-MANS=$(SOURCES:=.8)
+HTML_SOURCES=developer_instructions
+HTML_DOCS=$(HTML_SOURCES:=.html)
+MAN_SOURCES=g-sorcery gs-elpa gs-ctan
+MANS=$(MAN_SOURCES:=.8)
+
+RST2HTML=rst2html.py
RST2MAN=rst2man.py
-all: ${MANS}
+all: ${MANS} ${HTML_DOCS}
%.8: %.8.rst
$(RST2MAN) $< $@
+
+%.html: %.rst
+ $(RST2HTML) $< $@
diff --git a/docs/developer_instructions.html b/docs/developer_instructions.html
new file mode 100644
index 0000000..db574e6
--- /dev/null
+++ b/docs/developer_instructions.html
@@ -0,0 +1,946 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.10: http://docutils.sourceforge.net/" />
+<title>Developer Instructions</title>
+<style type="text/css">
+
+/*
+:Author: David Goodger (goodger@python.org)
+:Id: $Id: html4css1.css 7514 2012-09-14 14:27:12Z milde $
+:Copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+*/
+
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+ border: 0 }
+
+table.borderless td, table.borderless th {
+ /* Override padding for "table.docutils td" with "! important".
+ The right padding separates the table cells. */
+ padding: 0 0.5em 0 0 ! important }
+
+.first {
+ /* Override more specific margin styles with "! important". */
+ margin-top: 0 ! important }
+
+.last, .with-subtitle {
+ margin-bottom: 0 ! important }
+
+.hidden {
+ display: none }
+
+a.toc-backref {
+ text-decoration: none ;
+ color: black }
+
+blockquote.epigraph {
+ margin: 2em 5em ; }
+
+dl.docutils dd {
+ margin-bottom: 0.5em }
+
+object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
+ overflow: hidden;
+}
+
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
+ font-weight: bold }
+*/
+
+div.abstract {
+ margin: 2em 5em }
+
+div.abstract p.topic-title {
+ font-weight: bold ;
+ text-align: center }
+
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
+ margin: 2em ;
+ border: medium outset ;
+ padding: 1em }
+
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+ font-weight: bold ;
+ font-family: sans-serif }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title, .code .error {
+ color: red ;
+ font-weight: bold ;
+ font-family: sans-serif }
+
+/* Uncomment (and remove this text!) to get reduced vertical space in
+ compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+ margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+ margin-top: 0.5em }
+*/
+
+div.dedication {
+ margin: 2em 5em ;
+ text-align: center ;
+ font-style: italic }
+
+div.dedication p.topic-title {
+ font-weight: bold ;
+ font-style: normal }
+
+div.figure {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+div.footer, div.header {
+ clear: both;
+ font-size: smaller }
+
+div.line-block {
+ display: block ;
+ margin-top: 1em ;
+ margin-bottom: 1em }
+
+div.line-block div.line-block {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ margin-left: 1.5em }
+
+div.sidebar {
+ margin: 0 0 0.5em 1em ;
+ border: medium outset ;
+ padding: 1em ;
+ background-color: #ffffee ;
+ width: 40% ;
+ float: right ;
+ clear: right }
+
+div.sidebar p.rubric {
+ font-family: sans-serif ;
+ font-size: medium }
+
+div.system-messages {
+ margin: 5em }
+
+div.system-messages h1 {
+ color: red }
+
+div.system-message {
+ border: medium outset ;
+ padding: 1em }
+
+div.system-message p.system-message-title {
+ color: red ;
+ font-weight: bold }
+
+div.topic {
+ margin: 2em }
+
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+ margin-top: 0.4em }
+
+h1.title {
+ text-align: center }
+
+h2.subtitle {
+ text-align: center }
+
+hr.docutils {
+ width: 75% }
+
+img.align-left, .figure.align-left, object.align-left {
+ clear: left ;
+ float: left ;
+ margin-right: 1em }
+
+img.align-right, .figure.align-right, object.align-right {
+ clear: right ;
+ float: right ;
+ margin-left: 1em }
+
+img.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left }
+
+.align-center {
+ clear: both ;
+ text-align: center }
+
+.align-right {
+ text-align: right }
+
+/* reset inner alignment in figures */
+div.align-right {
+ text-align: inherit }
+
+/* div.align-center * { */
+/* text-align: left } */
+
+ol.simple, ul.simple {
+ margin-bottom: 1em }
+
+ol.arabic {
+ list-style: decimal }
+
+ol.loweralpha {
+ list-style: lower-alpha }
+
+ol.upperalpha {
+ list-style: upper-alpha }
+
+ol.lowerroman {
+ list-style: lower-roman }
+
+ol.upperroman {
+ list-style: upper-roman }
+
+p.attribution {
+ text-align: right ;
+ margin-left: 50% }
+
+p.caption {
+ font-style: italic }
+
+p.credits {
+ font-style: italic ;
+ font-size: smaller }
+
+p.label {
+ white-space: nowrap }
+
+p.rubric {
+ font-weight: bold ;
+ font-size: larger ;
+ color: maroon ;
+ text-align: center }
+
+p.sidebar-title {
+ font-family: sans-serif ;
+ font-weight: bold ;
+ font-size: larger }
+
+p.sidebar-subtitle {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+p.topic-title {
+ font-weight: bold }
+
+pre.address {
+ margin-bottom: 0 ;
+ margin-top: 0 ;
+ font: inherit }
+
+pre.literal-block, pre.doctest-block, pre.math, pre.code {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+pre.code .ln { color: grey; } /* line numbers */
+pre.code, code { background-color: #eeeeee }
+pre.code .comment, code .comment { color: #5C6576 }
+pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
+pre.code .literal.string, code .literal.string { color: #0C5404 }
+pre.code .name.builtin, code .name.builtin { color: #352B84 }
+pre.code .deleted, code .deleted { background-color: #DEB0A1}
+pre.code .inserted, code .inserted { background-color: #A3D289}
+
+span.classifier {
+ font-family: sans-serif ;
+ font-style: oblique }
+
+span.classifier-delimiter {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+span.interpreted {
+ font-family: sans-serif }
+
+span.option {
+ white-space: nowrap }
+
+span.pre {
+ white-space: pre }
+
+span.problematic {
+ color: red }
+
+span.section-subtitle {
+ /* font-size relative to parent (h1..h6 element) */
+ font-size: 80% }
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px }
+
+table.docinfo {
+ margin: 2em 4em }
+
+table.docutils {
+ margin-top: 0.5em ;
+ margin-bottom: 0.5em }
+
+table.footnote {
+ border-left: solid 1px black;
+ margin-left: 1px }
+
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
+ padding-left: 0.5em ;
+ padding-right: 0.5em ;
+ vertical-align: top }
+
+table.docutils th.field-name, table.docinfo th.docinfo-name {
+ font-weight: bold ;
+ text-align: left ;
+ white-space: nowrap ;
+ padding-left: 0 }
+
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+ font-size: 100% }
+
+ul.auto-toc {
+ list-style-type: none }
+
+</style>
+</head>
+<body>
+<div class="document" id="developer-instructions">
+<h1 class="title">Developer Instructions</h1>
+
+<div class="section" id="g-sorcery-overview">
+<h1>g-sorcery overview</h1>
+<p><strong>g-sorcery</strong> is a framework aimed to easy development of ebuild
+generators.</p>
+<p>Some terms used in this guide:</p>
+<ul>
+<li><dl class="first docutils">
+<dt><strong>3rd party software provider</strong> or <strong>repository</strong></dt>
+<dd><p class="first last">A system of software distribution like CTAN or CPAN that
+provides packages for some domain (e.g. TeX packages or elisp
+packages for emacs).</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>backend</strong></dt>
+<dd><p class="first last">A tool developed using <strong>g-sorcery</strong> framework that provides
+support for repositories of a given type.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>overlay</strong></dt>
+<dd><p class="first last">Usual Gentoo overlay.</p>
+</dd>
+</dl>
+</li>
+</ul>
+<p><strong>g-sorcery</strong> consists of different parts:</p>
+<ul>
+<li><dl class="first docutils">
+<dt><strong>package_db.PackageDB</strong></dt>
+<dd><p class="first last">A package database. It holds information about all available
+packages in a given repository.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>package_db.DBGenerator</strong></dt>
+<dd><p class="first last">A fabric that creates PackageDB object and fills it with information.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>backend.Backend</strong></dt>
+<dd><p class="first last">Backend that processes user commands.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>ebuild</strong></dt>
+<dd><p class="first last">Module with different ebuild generators.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>eclass</strong></dt>
+<dd><p class="first last">Module with eclass generators.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>metadata.MetadataGenerator</strong></dt>
+<dd><p class="first last">Metadata generator.</p>
+</dd>
+</dl>
+</li>
+</ul>
+<p>Also there are other modules and classes that will be described later.</p>
+<p>Usually repositories of a given type provide some kind of database. It can
+be just a plain ASCII file, xmlrpc interface or just a joint set of web-pages.
+This database describes what packages are available and how to install them.</p>
+<p>Also usually there is an upstream tool for repositories of a given type that
+allows installation of available packages. The main problem when using
+such tools is that package mangler you use is not aware of them and they are
+not aware of your package manager.</p>
+<p>The idea of <strong>g-sorcery</strong> is to convert a database provided by a repository
+into well defined format and then generate an overlay with ebuilds.
+Then available packages can be installed as usual <strong>Gentoo</strong> packages.</p>
+<p>So there are two phases of backend operation:</p>
+<ul class="simple">
+<li>synchronize with repository database</li>
+<li>populate overlay using obtained information</li>
+</ul>
+<p>There are two ways of using backend:</p>
+<ul class="simple">
+<li>run it as a CLI tool manually</li>
+<li>use its integration with layman</li>
+</ul>
+</div>
+<div class="section" id="backend-structure">
+<h1>Backend structure</h1>
+<p>The only mandatory module in a backend is called <strong>backend</strong>. It should contain
+at least one variable called <strong>instance</strong> that has a <strong>__call__</strong> method that
+takes 4 arguments. These arguments are:</p>
+<ul class="simple">
+<li>self</li>
+<li>command line arguments</li>
+<li>backend config</li>
+<li>g-sorcery config</li>
+</ul>
+<p>Usually <strong>instance</strong> variable should be an instance of a class g_sorcery.backend.Backend
+or derived class.</p>
+<p>g_sorcery.backend.Backend constructor takes 8 arguments. They are:</p>
+<ul class="simple">
+<li>self</li>
+<li>Package database generator class</li>
+<li>Two ebuild generator classes</li>
+<li>Eclass generator class</li>
+<li>Metadata generator class</li>
+<li>Package database class</li>
+<li>Boolean variable that defines method of database generation</li>
+</ul>
+<p>There are two ebuild generator classes as there are two scenarios of using backend on user
+side: generate the entire overlay tree (possibly by layman) or generate a given ebuild
+and its dependencies. In a first case it would be very bad idea to have sources in ebuild's
+SRC_URI as during manifest generation for an overlay all the sources would be downloaded
+to the user's comuter that inevitably would made user really happy. So one ebuild generator
+generates ebuild with empty SRC_URI. Note that a mechanism for downloading of sources during
+ebuild merging should be provided. For an example see <strong>git-2</strong> eclass from the main tree or
+any eclass from backends provided with g-sorcery.</p>
+<p>Usually downloading and parsing of a database from a repository is an easy operation. But sometimes
+there could exist some problems. Hence exists the last parameter in Backend constructor that
+allows syncing with already generated database available somewhere in Internet.</p>
+<p>To do something usefull backend should customize any classes from g-sorcery it needs
+and define backend.instance variable using those classes. Other two things backend should do are:</p>
+<ul class="simple">
+<li>install a binary that calls g-sorcery with appropriate backend name (see man g-sorcery)</li>
+<li>install a config that allows g-sorcery find appropriate backend module</li>
+</ul>
+<p>A binary should just pass arguments to g-sorcery. For a backend named gs-elpa it could look like</p>
+<pre class="code literal-block">
+#!/bin/bash
+
+g-sorcery g-elpa $&#64;
+</pre>
+<div class="section" id="backend-config">
+<h2>Backend config</h2>
+<p>Backend config is just a JSON file with a dictionary. There are two mandatory entries:</p>
+<ul>
+<li><dl class="first docutils">
+<dt>package</dt>
+<dd><p class="first last">Its value should be a string with a package containing backend.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt>repositories</dt>
+<dd><p class="first last">A dictionary describing available repositories. Should have at least one entry.</p>
+</dd>
+</dl>
+</li>
+</ul>
+<p>Backend config should have a name BACKEND.js and should be installed under <strong>/etc/g-sorcery</strong>
+directory. BACKEND here is a backend name which was used in a g-sorcery call.</p>
+<p>An entry in repositories dictionary as key should have a repository name and should be a dictionary
+with repository properties. The only mandatory property is <strong>repo_uri</strong> in case database is
+generated using info downloaded from the repository or <strong>db_uri</strong> in case database is
+just synced with another already generated database. Also there can be a <strong>masters</strong> entry that
+contains a list of overlays this repository depends on. If present it should contain at least
+<strong>gentoo</strong> entry.</p>
+<p>A simple backend config:</p>
+<pre class="code literal-block">
+ {
+ &quot;package&quot;: &quot;gs_elpa&quot;,
+ &quot;repositories&quot;: {
+ &quot;gnu-elpa&quot;: {
+ &quot;repo_uri&quot;: &quot;http://elpa.gnu.org/packages/&quot;
+ },
+ &quot;marmalade&quot;: {
+ &quot;repo_uri&quot;: &quot;http://marmalade-repo.org/packages/&quot;,
+ &quot;masters&quot;: [&quot;gentoo&quot;, &quot;gnu-elpa&quot;]
+ },
+ &quot;melpa&quot;: {
+ &quot;repo_uri&quot;: &quot;http://melpa.milkbox.net/packages/&quot;,
+ &quot;masters&quot;: [&quot;gentoo&quot;, &quot;gnu-elpa&quot;]
+ }
+ }
+}
+</pre>
+</div>
+</div>
+<div class="section" id="package-database">
+<h1>Package database</h1>
+<div class="section" id="directory-layout">
+<h2>Directory layout</h2>
+<p>Package database is a directory tree with JSON files. The layout of this tree looks like:</p>
+<pre class="code literal-block">
+db dir
+ manifest.json: database manifest
+ categories.json: information about categories
+ category1
+ packages.json: list of packages
+ package1
+ versions.json: list of versions
+ version1.json: description of a package
+ version2.json: description of a package
+ ...
+ package2
+ ...
+ category2
+ ...
+</pre>
+<p>Files named version.json contain ebuild data which is just a dictionary with information
+relevant for ebuild, eclass and metadata generation for a given package.</p>
+</div>
+<div class="section" id="packagedb-class">
+<h2>PackageDB class</h2>
+<p>PackageDB class is aimed for interaction with package database. It has methods that allow
+to add categories and packages and to do queries on them. Usually you do not want to customize this
+class. But in case you want there is number of methods that can be redifend.</p>
+<p>First of all if you have a database that should be synced with another already generate database
+you can redifine URI to be used for syncing using <strong>get_real_db_uri</strong> method.</p>
+<p>There is a number of hooks that are called after package, category or the whole database is
+written/read:</p>
+<ul class="simple">
+<li>additional_write_version</li>
+<li>additional_write_package</li>
+<li>additional_write_category</li>
+<li>additional_write</li>
+<li>additional_read_version</li>
+<li>additional_read_package</li>
+<li>additional_read_category</li>
+<li>additional_read</li>
+</ul>
+<p>Note that before add any package you should add a category for it using <strong>add_category</strong>.
+Then packages can be added using <strong>add_package</strong>. PackageDB currently does not write changes
+automatically, so you should call <strong>write</strong> after changes are done. This is not relevant
+for database changing in <strong>process_data</strong> method of database generator as there all changes
+are written by other methods it calls internally after <strong>process_data</strong>.</p>
+</div>
+<div class="section" id="json-serializable-objects">
+<h2>JSON serializable objects</h2>
+<p>If you need to store an object in a database it should be JSON serializable in terms of
+g_sorcery.serialization module. It means it should define two methods:</p>
+<ul class="simple">
+<li>usual method <strong>serialize</strong> that returns a JSON serializable object in terms of standard Python
+json module</li>
+<li>class method <strong>deserialize</strong> that takes a value returned by <strong>serialize</strong> and constructs new instance
+of your class using it</li>
+</ul>
+</div>
+<div class="section" id="dependency-handling">
+<h2>Dependency handling</h2>
+<p>There is a special class g_sorcery.g_collections.Dependency aimed to handle dependencies.
+Its constructor takes two mandatory parameters:</p>
+<ul class="simple">
+<li>category</li>
+<li>package</li>
+</ul>
+<p>and two additional parameters:</p>
+<ul class="simple">
+<li>version</li>
+<li>operator</li>
+</ul>
+<p>These two are the same as version and operator used in the usual package atom.</p>
+<p>For storing dependency lists in a database you should use a collection
+g_sorcery.g_collections.serializable_elist. Its constructor takes an iterable and a
+separator that will be used to separate items when this collection is printed. In case of
+storing dependencies for using them in ebuild's DEPEND variable a separator should be &quot;nt&quot;.</p>
+<p>Ebuild data for every package version must have a &quot;dependencies&quot; entry. This entry is used
+by backend during deciding which ebuilds should be generated. So make sure it does not have
+any external dependencies.</p>
+</div>
+</div>
+<div class="section" id="package-database-generator">
+<h1>Package database generator</h1>
+<div class="section" id="customizing-dbgenerator">
+<h2>Customizing DBGenerator</h2>
+<p>To do something usefull you should customize package_db.DBGenerator class.
+With this aim you should subclass it and define some methods. Here they are:</p>
+<ul>
+<li><dl class="first docutils">
+<dt>get_download_uries</dt>
+<dd><p class="first">Get a list with download URI entries.
+Each entry has one of the following formats:</p>
+<ol class="arabic">
+<li><p class="first">String with URI.</p>
+</li>
+<li><dl class="first docutils">
+<dt>A dictionary with entries:</dt>
+<dd><ul class="first simple">
+<li>uri: URI.</li>
+<li>parser: Parser to be applied to downloaded data.</li>
+<li>open_file: Whether parser accepts file objects.</li>
+<li>open_mode: Open mode for a downloaded file.</li>
+</ul>
+<p class="last">The only mandatory entry is uri.</p>
+</dd>
+</dl>
+</li>
+</ol>
+<p class="last">The default implementation returns [backend_config[&quot;repositories&quot;][REPOSITORY][&quot;repo_uri&quot;]].</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt>parse_data</dt>
+<dd><p class="first last">This method parses a file downloaded from a repository
+and returns its content in any form you think useful.
+There is no useful default implementation of this method.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt>process_data</dt>
+<dd><p class="first last">This method should fill a package database with entries using
+already downloaded and parsed data.</p>
+</dd>
+</dl>
+</li>
+</ul>
+<p>Generally speaking these are all the method you should implement.</p>
+</div>
+<div class="section" id="value-convertion">
+<h2>Value convertion</h2>
+<p>During database generation you may need to convert some values provided by repository
+(e.g license names that can not coincide with those used in Gentoo). With this aim
+you can use <strong>convert</strong> function. To understand how it works see its sources in
+g_sorcery.package_db.DBGenerator and as an example CTAN backend.</p>
+<p>Here is a very short example. If you want to convert licenses in the same way for all
+repositories of this type you just add <strong>common_config</strong> entry to backend config which
+looks like:</p>
+<pre class="code literal-block">
+&quot;common_config&quot;: {
+ &quot;licenses&quot;: {
+ &quot;apache2&quot;: &quot;Apache-2.0&quot;,
+ &quot;artistic&quot;: &quot;Artistic&quot;,
+ &quot;Artistic2&quot;: &quot;Artistic-2&quot;,
+ &quot;gpl&quot;: &quot;GPL-1&quot;,
+ &quot;gpl2&quot;: &quot;GPL-2&quot;,
+ &quot;gpl3&quot;: &quot;GPL-3&quot;,
+ &quot;knuth&quot;: &quot;TeX&quot;,
+ &quot;lgpl&quot;: &quot;LGPL-2&quot;,
+ &quot;lgpl2.1&quot;: &quot;LGPL-2.1&quot;,
+ &quot;lppl&quot;: &quot;LPPL-1.2&quot;,
+ &quot;lppl1&quot;: &quot;LPPL-1.2&quot;,
+ &quot;lppl1.2&quot;: &quot;LPPL-1.2&quot;,
+ &quot;lppl1.3&quot;: &quot;LPPL-1.3c&quot;
+ }
+}
+</pre>
+<p>And then call in your <strong>process_data</strong> method</p>
+<pre class="code literal-block">
+license = self.convert([common_config, config], &quot;licenses&quot;, repo_license)
+</pre>
+<p>Where <strong>common_config</strong>, <strong>config</strong> are config provided as arguments to your <strong>process_data</strong> method
+and <strong>repo_license</strong> is a license name used by the repository.</p>
+<p>There is a special conversion function used for dependencies: <strong>convert_dependency</strong>. To use it you should
+usually redefine <strong>convert_internal_dependency</strong> and <strong>convert_external_dependency</strong>. To decide whether
+a dependency is external database generator uses <strong>external</strong> entry in config.</p>
+<p>You may want to test whether there is a given value in given entry in config. To do it use
+<strong>in_config</strong> function.</p>
+</div>
+</div>
+<div class="section" id="eclass-generator">
+<h1>Eclass generator</h1>
+<p>Usualy you do not want to modify eclass generator. Currently it is very simple: it just returns eclasses
+from a given directory. So all you should do is populating a directory with eclasses and then
+inheriting g_sorcery.eclass.EclassGenerator and defining a directory in constructor. It should look
+like</p>
+<pre class="code literal-block">
+class ElpaEclassGenerator(EclassGenerator):
+ &quot;&quot;&quot;
+ Implementation of eclass generator. Only specifies a data directory.
+ &quot;&quot;&quot;
+ def __init__(self):
+ super(ElpaEclassGenerator, self).__init__(os.path.join(get_pkgpath(__file__), 'data'))
+</pre>
+<p>There is no common eclass currently. I plan to change it in the future, so your eclass code can
+inherit any common functionality.</p>
+</div>
+<div class="section" id="ebuild-generator">
+<h1>Ebuild generator</h1>
+<p>There is a number of ebuild generators in g_sorcery.ebuild module. The DefaultEbuildGenerator
+is a recommended one. To use it you should inherit it and define an ebuild layout in constructor.</p>
+<p>Layout has entries for vars and inherited eclasses. Each entry is a list.
+Entries are processed in the following order:</p>
+<ul class="simple">
+<li>vars_before_inherit</li>
+<li>inherit</li>
+<li>vars_after_inherit</li>
+<li>vars_after_description</li>
+<li>vars_after_keywords</li>
+</ul>
+<p><strong>inherit</strong> entry is just a list of eclass names.</p>
+<p><strong>vars*</strong> entries are lists of variables in two possible formats:</p>
+<ol class="arabic simple">
+<li>A string with variable name</li>
+<li>A tuple (varname, value)</li>
+</ol>
+<p>Variable names are automatically transformed to the upper-case during ebuild generation.</p>
+<p>An example of ebuild generator:</p>
+<pre class="code literal-block">
+Layout = collections.namedtuple(&quot;Layout&quot;,
+ [&quot;vars_before_inherit&quot;, &quot;inherit&quot;,
+ &quot;vars_after_description&quot;, &quot;vars_after_keywords&quot;])
+
+class ElpaEbuildWithoutDigestGenerator(DefaultEbuildGenerator):
+ &quot;&quot;&quot;
+ Implementation of ebuild generator without sources digesting.
+ &quot;&quot;&quot;
+ def __init__(self, package_db):
+
+ vars_before_inherit = \
+ [&quot;repo_uri&quot;, &quot;source_type&quot;, &quot;realname&quot;]
+
+ inherit = [&quot;g-elpa&quot;]
+
+ vars_after_description = \
+ [&quot;homepage&quot;]
+
+ vars_after_keywords = \
+ [&quot;depend&quot;, &quot;rdepend&quot;]
+
+ layout = Layout(vars_before_inherit, inherit,
+ vars_after_description, vars_after_keywords)
+
+ super(ElpaEbuildWithoutDigestGenerator, self).__init__(package_db, layout)
+</pre>
+</div>
+<div class="section" id="metadata-generator">
+<h1>Metadata generator</h1>
+<p>To use metadata generator you should just define some variables in ebuild data.</p>
+<div class="section" id="xml-schema-format">
+<h2>XML schema format</h2>
+<p>Metadata generator uses a XML schema in format defined in g_sorcery.metadata module.
+Schema is a list of entries. Each entry describes one XML tag.
+Entry is a dictionary. Dictionary keys are:</p>
+<ul>
+<li><dl class="first docutils">
+<dt><strong>name</strong></dt>
+<dd><p class="first last">Name of a tag</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>multiple</strong></dt>
+<dd><p class="first last">Defines if a given tag can be used more then one time. It is a tuple. First element
+of a tuple is boolean. If it is set a tag can be repeated. Second element is a string.
+If it is not empty, it defines a name for an attribute
+that will distinguish different entries of a tag.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>required</strong></dt>
+<dd><p class="first last">Boolean that defines if a given tag is required.</p>
+</dd>
+</dl>
+</li>
+<li><dl class="first docutils">
+<dt><strong>subtags</strong></dt>
+<dd><p class="first last">List of subtags.</p>
+</dd>
+</dl>
+</li>
+</ul>
+</div>
+<div class="section" id="data-dictinonary-format">
+<h2>Data dictinonary format</h2>
+<p>The part of ebuild data used for metadata generation should have data dictionary format
+also defined in g_sorcery.metadata.</p>
+<p>Keys correspond to tags from a schema with the same name.
+If a tag is not multiple without subkeys value is just a
+string with text for the tag.
+If tag is multiple value is a list with entries
+corresponding to a single tag.
+If tag has subtags value is a dictionary with entries
+corresponding to subkeys and <strong>text</strong> entry corresponding
+to text for the tag.
+If tag should have attributes value is a tuple or list with
+0 element containing an attribute and 1 element containing
+a value for the tag as described previously.</p>
+</div>
+<div class="section" id="metadata-xml-schema">
+<h2>Metadata XML schema</h2>
+<p>Metadata XML schema looks like</p>
+<pre class="code literal-block">
+default_schema = [{'name' : 'herd',
+ 'multiple' : (True, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : []},
+
+ {'name' : 'maintainer',
+ 'multiple' : (True, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : [{'name' : 'email',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : True,
+ 'subtags' : []},
+ {'name' : 'name',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : []},
+ {'name' : 'description',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : []},
+ ]
+ },
+
+ {'name' : 'longdescription',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : []},
+
+ {'name' : 'use',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : [{'name' : 'flag',
+ 'multiple' : (True, &quot;name&quot;),
+ 'required' : True,
+ 'subtags' : []}]
+ },
+
+ {'name' : 'upstream',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : [{'name' : 'maintainer',
+ 'multiple' : (True, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : [{'name' : 'name',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : True,
+ 'subtags' : []},
+ {'name' : 'email',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : []}]},
+ {'name' : 'changelog',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : []},
+ {'name' : 'doc',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : []},
+ {'name' : 'bugs-to',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : []},
+ {'name' : 'remote-id',
+ 'multiple' : (False, &quot;&quot;),
+ 'required' : False,
+ 'subtags' : []},
+ ]
+ },
+ ]
+</pre>
+<p>So to have metadata.xml filled with e.g. maintainer info you should add to ebuild data
+something like</p>
+<pre class="code literal-block">
+{'maintainer' : [{'email' : 'piatlicki&#64;gmail.com',
+ 'name' : 'Jauhien Piatlicki'}]}
+</pre>
+</div>
+</div>
+<div class="section" id="layman-integration">
+<h1>Layman integration</h1>
+<p>There is a <strong>layman</strong> integration for <strong>g-sorcery</strong> (thanks to Brian Dolbec and Auke Booij here).
+To use it you just need to install and xml file describing your repositories in
+<strong>/etc/layman/overlays</strong> directory. For our example of backend config we could write an xml file
+that looks like</p>
+<pre class="code literal-block">
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;!DOCTYPE repositories SYSTEM &quot;/dtd/repositories.dtd&quot;&gt;
+&lt;repositories xmlns=&quot;&quot; version=&quot;1.0&quot;&gt;
+&lt;repo quality=&quot;experimental&quot; status=&quot;unofficial&quot;&gt;
+ &lt;name&gt;gnu-elpa&lt;/name&gt;
+ &lt;description&gt;packages for emacs&lt;/description&gt;
+ &lt;homepage&gt;http://elpa.gnu.org/&lt;/homepage&gt;
+ &lt;owner&gt;
+ &lt;email&gt;piatlicki&#64;gmail.com&lt;/email&gt;
+ &lt;name&gt;Jauhien Piatlicki&lt;/name&gt;
+ &lt;/owner&gt;
+ &lt;source type=&quot;g-sorcery&quot;&gt;gs-elpa gnu-elpa&lt;/source&gt;
+&lt;/repo&gt;
+&lt;repo quality=&quot;experimental&quot; status=&quot;unofficial&quot;&gt;
+ &lt;name&gt;marmalade&lt;/name&gt;
+ &lt;description&gt;packages for emacs&lt;/description&gt;
+ &lt;homepage&gt;http://marmalade-repo.org/&lt;/homepage&gt;
+ &lt;owner&gt;
+ &lt;email&gt;piatlicki&#64;gmail.com&lt;/email&gt;
+ &lt;name&gt;Jauhien Piatlicki&lt;/name&gt;
+ &lt;/owner&gt;
+ &lt;source type=&quot;g-sorcery&quot;&gt;gs-elpa marmalade&lt;/source&gt;
+&lt;/repo&gt;
+&lt;repo quality=&quot;experimental&quot; status=&quot;unofficial&quot;&gt;
+ &lt;name&gt;melpa&lt;/name&gt;
+ &lt;description&gt;packages for emacs&lt;/description&gt;
+ &lt;homepage&gt;http://melpa.milkbox.net&lt;/homepage&gt;
+ &lt;owner&gt;
+ &lt;email&gt;piatlicki&#64;gmail.com&lt;/email&gt;
+ &lt;name&gt;Jauhien Piatlicki&lt;/name&gt;
+ &lt;/owner&gt;
+ &lt;source type=&quot;g-sorcery&quot;&gt;gs-elpa melpa&lt;/source&gt;
+&lt;/repo&gt;
+&lt;/repositories&gt;
+</pre>
+<p>In entries <strong>&lt;source type=&quot;g-sorcery&quot;&gt;gs-elpa melpa&lt;/source&gt;</strong> the source type
+should always be <strong>g-sorcery</strong>, <strong>gs-elpa</strong> is backend name and <strong>melpa</strong> is repository name.</p>
+<p>For full description of format of this file see <strong>layman</strong> documentation.</p>
+<p>Note: at the moment layman-9999 does not support <strong>g-sorcery</strong> overlay type and you should
+patch it with <a class="reference external" href="https://raw.github.com/jauhien/g-sorcery/master/layman-git-g-sorcery.patch">https://raw.github.com/jauhien/g-sorcery/master/layman-git-g-sorcery.patch</a></p>
+</div>
+<div class="section" id="summary">
+<h1>Summary</h1>
+<p>So to create your own backend you should write a module named <strong>backend</strong> and define there
+a variable named <strong>instance</strong> that is an instance of g_sorcery.backend.Backend class. Or something
+that quacks like this class.</p>
+<p>Before doing it you should have defined classes you pass to it as parameters. They should be database
+generator, two ebuild generators, eclass and metadata generators.</p>
+<p>Also you should write an executable that calls g-sorcery and some configs.</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/docs/developer_instructions.rst b/docs/developer_instructions.rst
new file mode 100644
index 0000000..cd95a2f
--- /dev/null
+++ b/docs/developer_instructions.rst
@@ -0,0 +1,640 @@
+======================
+Developer Instructions
+======================
+
+g-sorcery overview
+==================
+
+**g-sorcery** is a framework aimed to easy development of ebuild
+generators.
+
+Some terms used in this guide:
+
+* **3rd party software provider** or **repository**
+ A system of software distribution like CTAN or CPAN that
+ provides packages for some domain (e.g. TeX packages or elisp
+ packages for emacs).
+
+* **backend**
+ A tool developed using **g-sorcery** framework that provides
+ support for repositories of a given type.
+
+* **overlay**
+ Usual Gentoo overlay.
+
+**g-sorcery** consists of different parts:
+
+* **package_db.PackageDB**
+ A package database. It holds information about all available
+ packages in a given repository.
+
+* **package_db.DBGenerator**
+ A fabric that creates PackageDB object and fills it with information.
+
+* **backend.Backend**
+ Backend that processes user commands.
+
+* **ebuild**
+ Module with different ebuild generators.
+
+* **eclass**
+ Module with eclass generators.
+
+* **metadata.MetadataGenerator**
+ Metadata generator.
+
+Also there are other modules and classes that will be described later.
+
+Usually repositories of a given type provide some kind of database. It can
+be just a plain ASCII file, xmlrpc interface or just a joint set of web-pages.
+This database describes what packages are available and how to install them.
+
+Also usually there is an upstream tool for repositories of a given type that
+allows installation of available packages. The main problem when using
+such tools is that package mangler you use is not aware of them and they are
+not aware of your package manager.
+
+The idea of **g-sorcery** is to convert a database provided by a repository
+into well defined format and then generate an overlay with ebuilds.
+Then available packages can be installed as usual **Gentoo** packages.
+
+So there are two phases of backend operation:
+
+- synchronize with repository database
+
+- populate overlay using obtained information
+
+There are two ways of using backend:
+
+- run it as a CLI tool manually
+
+- use its integration with layman
+
+
+Backend structure
+=================
+
+The only mandatory module in a backend is called **backend**. It should contain
+at least one variable called **instance** that has a **__call__** method that
+takes 4 arguments. These arguments are:
+
+* self
+
+* command line arguments
+
+* backend config
+
+* g-sorcery config
+
+Usually **instance** variable should be an instance of a class g_sorcery.backend.Backend
+or derived class.
+
+g_sorcery.backend.Backend constructor takes 8 arguments. They are:
+
+* self
+
+* Package database generator class
+
+* Two ebuild generator classes
+
+* Eclass generator class
+
+* Metadata generator class
+
+* Package database class
+
+* Boolean variable that defines method of database generation
+
+There are two ebuild generator classes as there are two scenarios of using backend on user
+side: generate the entire overlay tree (possibly by layman) or generate a given ebuild
+and its dependencies. In a first case it would be very bad idea to have sources in ebuild's
+SRC_URI as during manifest generation for an overlay all the sources would be downloaded
+to the user's comuter that inevitably would made user really happy. So one ebuild generator
+generates ebuild with empty SRC_URI. Note that a mechanism for downloading of sources during
+ebuild merging should be provided. For an example see **git-2** eclass from the main tree or
+any eclass from backends provided with g-sorcery.
+
+Usually downloading and parsing of a database from a repository is an easy operation. But sometimes
+there could exist some problems. Hence exists the last parameter in Backend constructor that
+allows syncing with already generated database available somewhere in Internet.
+
+To do something usefull backend should customize any classes from g-sorcery it needs
+and define backend.instance variable using those classes. Other two things backend should do are:
+
+* install a binary that calls g-sorcery with appropriate backend name (see man g-sorcery)
+
+* install a config that allows g-sorcery find appropriate backend module
+
+A binary should just pass arguments to g-sorcery. For a backend named gs-elpa it could look like
+
+.. code-block::
+
+ #!/bin/bash
+
+ g-sorcery g-elpa $@
+
+Backend config
+~~~~~~~~~~~~~~
+
+Backend config is just a JSON file with a dictionary. There are two mandatory entries:
+
+* package
+ Its value should be a string with a package containing backend.
+
+* repositories
+ A dictionary describing available repositories. Should have at least one entry.
+
+Backend config should have a name BACKEND.js and should be installed under **/etc/g-sorcery**
+directory. BACKEND here is a backend name which was used in a g-sorcery call.
+
+An entry in repositories dictionary as key should have a repository name and should be a dictionary
+with repository properties. The only mandatory property is **repo_uri** in case database is
+generated using info downloaded from the repository or **db_uri** in case database is
+just synced with another already generated database. Also there can be a **masters** entry that
+contains a list of overlays this repository depends on. If present it should contain at least
+**gentoo** entry.
+
+A simple backend config:
+
+.. code-block::
+
+ {
+ "package": "gs_elpa",
+ "repositories": {
+ "gnu-elpa": {
+ "repo_uri": "http://elpa.gnu.org/packages/"
+ },
+ "marmalade": {
+ "repo_uri": "http://marmalade-repo.org/packages/",
+ "masters": ["gentoo", "gnu-elpa"]
+ },
+ "melpa": {
+ "repo_uri": "http://melpa.milkbox.net/packages/",
+ "masters": ["gentoo", "gnu-elpa"]
+ }
+ }
+ }
+
+Package database
+================
+
+Directory layout
+~~~~~~~~~~~~~~~~
+
+Package database is a directory tree with JSON files. The layout of this tree looks like:
+
+.. code-block::
+
+ db dir
+ manifest.json: database manifest
+ categories.json: information about categories
+ category1
+ packages.json: list of packages
+ package1
+ versions.json: list of versions
+ version1.json: description of a package
+ version2.json: description of a package
+ ...
+ package2
+ ...
+ category2
+ ...
+
+Files named version.json contain ebuild data which is just a dictionary with information
+relevant for ebuild, eclass and metadata generation for a given package.
+
+PackageDB class
+~~~~~~~~~~~~~~~
+
+PackageDB class is aimed for interaction with package database. It has methods that allow
+to add categories and packages and to do queries on them. Usually you do not want to customize this
+class. But in case you want there is number of methods that can be redifend.
+
+First of all if you have a database that should be synced with another already generate database
+you can redifine URI to be used for syncing using **get_real_db_uri** method.
+
+There is a number of hooks that are called after package, category or the whole database is
+written/read:
+
+* additional_write_version
+
+* additional_write_package
+
+* additional_write_category
+
+* additional_write
+
+* additional_read_version
+
+* additional_read_package
+
+* additional_read_category
+
+* additional_read
+
+Note that before add any package you should add a category for it using **add_category**.
+Then packages can be added using **add_package**. PackageDB currently does not write changes
+automatically, so you should call **write** after changes are done. This is not relevant
+for database changing in **process_data** method of database generator as there all changes
+are written by other methods it calls internally after **process_data**.
+
+JSON serializable objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you need to store an object in a database it should be JSON serializable in terms of
+g_sorcery.serialization module. It means it should define two methods:
+
+* usual method **serialize** that returns a JSON serializable object in terms of standard Python
+ json module
+
+* class method **deserialize** that takes a value returned by **serialize** and constructs new instance
+ of your class using it
+
+Dependency handling
+~~~~~~~~~~~~~~~~~~~
+
+There is a special class g_sorcery.g_collections.Dependency aimed to handle dependencies.
+Its constructor takes two mandatory parameters:
+
+* category
+
+* package
+
+and two additional parameters:
+
+* version
+
+* operator
+
+These two are the same as version and operator used in the usual package atom.
+
+For storing dependency lists in a database you should use a collection
+g_sorcery.g_collections.serializable_elist. Its constructor takes an iterable and a
+separator that will be used to separate items when this collection is printed. In case of
+storing dependencies for using them in ebuild's DEPEND variable a separator should be "\n\t".
+
+Ebuild data for every package version must have a "dependencies" entry. This entry is used
+by backend during deciding which ebuilds should be generated. So make sure it does not have
+any external dependencies.
+
+
+Package database generator
+==========================
+
+Customizing DBGenerator
+~~~~~~~~~~~~~~~~~~~~~~~
+
+To do something usefull you should customize package_db.DBGenerator class.
+With this aim you should subclass it and define some methods. Here they are:
+
+* get_download_uries
+ Get a list with download URI entries.
+ Each entry has one of the following formats:
+
+ 1. String with URI.
+
+ 2. A dictionary with entries:
+ - uri: URI.
+
+ - parser: Parser to be applied to downloaded data.
+
+ - open_file: Whether parser accepts file objects.
+
+ - open_mode: Open mode for a downloaded file.
+
+ The only mandatory entry is uri.
+
+ The default implementation returns [backend_config["repositories"][REPOSITORY]["repo_uri"]].
+
+* parse_data
+ This method parses a file downloaded from a repository
+ and returns its content in any form you think useful.
+ There is no useful default implementation of this method.
+
+* process_data
+ This method should fill a package database with entries using
+ already downloaded and parsed data.
+
+Generally speaking these are all the method you should implement.
+
+Value convertion
+~~~~~~~~~~~~~~~~
+
+During database generation you may need to convert some values provided by repository
+(e.g license names that can not coincide with those used in Gentoo). With this aim
+you can use **convert** function. To understand how it works see its sources in
+g_sorcery.package_db.DBGenerator and as an example CTAN backend.
+
+Here is a very short example. If you want to convert licenses in the same way for all
+repositories of this type you just add **common_config** entry to backend config which
+looks like:
+
+.. code-block::
+
+ "common_config": {
+ "licenses": {
+ "apache2": "Apache-2.0",
+ "artistic": "Artistic",
+ "Artistic2": "Artistic-2",
+ "gpl": "GPL-1",
+ "gpl2": "GPL-2",
+ "gpl3": "GPL-3",
+ "knuth": "TeX",
+ "lgpl": "LGPL-2",
+ "lgpl2.1": "LGPL-2.1",
+ "lppl": "LPPL-1.2",
+ "lppl1": "LPPL-1.2",
+ "lppl1.2": "LPPL-1.2",
+ "lppl1.3": "LPPL-1.3c"
+ }
+ }
+
+And then call in your **process_data** method
+
+.. code-block::
+
+ license = self.convert([common_config, config], "licenses", repo_license)
+
+Where **common_config**, **config** are config provided as arguments to your **process_data** method
+and **repo_license** is a license name used by the repository.
+
+There is a special conversion function used for dependencies: **convert_dependency**. To use it you should
+usually redefine **convert_internal_dependency** and **convert_external_dependency**. To decide whether
+a dependency is external database generator uses **external** entry in config.
+
+You may want to test whether there is a given value in given entry in config. To do it use
+**in_config** function.
+
+Eclass generator
+================
+
+Usualy you do not want to modify eclass generator. Currently it is very simple: it just returns eclasses
+from a given directory. So all you should do is populating a directory with eclasses and then
+inheriting g_sorcery.eclass.EclassGenerator and defining a directory in constructor. It should look
+like
+
+.. code-block::
+
+ class ElpaEclassGenerator(EclassGenerator):
+ """
+ Implementation of eclass generator. Only specifies a data directory.
+ """
+ def __init__(self):
+ super(ElpaEclassGenerator, self).__init__(os.path.join(get_pkgpath(__file__), 'data'))
+
+There is no common eclass currently. I plan to change it in the future, so your eclass code can
+inherit any common functionality.
+
+Ebuild generator
+================
+
+There is a number of ebuild generators in g_sorcery.ebuild module. The DefaultEbuildGenerator
+is a recommended one. To use it you should inherit it and define an ebuild layout in constructor.
+
+Layout has entries for vars and inherited eclasses. Each entry is a list.
+Entries are processed in the following order:
+
+* vars_before_inherit
+
+* inherit
+
+* vars_after_inherit
+
+* vars_after_description
+
+* vars_after_keywords
+
+**inherit** entry is just a list of eclass names.
+
+**vars*** entries are lists of variables in two possible formats:
+
+1. A string with variable name
+2. A tuple (varname, value)
+
+Variable names are automatically transformed to the upper-case during ebuild generation.
+
+An example of ebuild generator:
+
+.. code-block::
+
+ Layout = collections.namedtuple("Layout",
+ ["vars_before_inherit", "inherit",
+ "vars_after_description", "vars_after_keywords"])
+
+ class ElpaEbuildWithoutDigestGenerator(DefaultEbuildGenerator):
+ """
+ Implementation of ebuild generator without sources digesting.
+ """
+ def __init__(self, package_db):
+
+ vars_before_inherit = \
+ ["repo_uri", "source_type", "realname"]
+
+ inherit = ["g-elpa"]
+
+ vars_after_description = \
+ ["homepage"]
+
+ vars_after_keywords = \
+ ["depend", "rdepend"]
+
+ layout = Layout(vars_before_inherit, inherit,
+ vars_after_description, vars_after_keywords)
+
+ super(ElpaEbuildWithoutDigestGenerator, self).__init__(package_db, layout)
+
+Metadata generator
+==================
+
+To use metadata generator you should just define some variables in ebuild data.
+
+XML schema format
+~~~~~~~~~~~~~~~~~
+
+Metadata generator uses a XML schema in format defined in g_sorcery.metadata module.
+Schema is a list of entries. Each entry describes one XML tag.
+Entry is a dictionary. Dictionary keys are:
+
+* **name**
+ Name of a tag
+
+* **multiple**
+ Defines if a given tag can be used more then one time. It is a tuple. First element
+ of a tuple is boolean. If it is set a tag can be repeated. Second element is a string.
+ If it is not empty, it defines a name for an attribute
+ that will distinguish different entries of a tag.
+
+* **required**
+ Boolean that defines if a given tag is required.
+
+* **subtags**
+ List of subtags.
+
+Data dictinonary format
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The part of ebuild data used for metadata generation should have data dictionary format
+also defined in g_sorcery.metadata.
+
+Keys correspond to tags from a schema with the same name.
+If a tag is not multiple without subkeys value is just a
+string with text for the tag.
+If tag is multiple value is a list with entries
+corresponding to a single tag.
+If tag has subtags value is a dictionary with entries
+corresponding to subkeys and **text** entry corresponding
+to text for the tag.
+If tag should have attributes value is a tuple or list with
+0 element containing an attribute and 1 element containing
+a value for the tag as described previously.
+
+Metadata XML schema
+~~~~~~~~~~~~~~~~~~~
+
+Metadata XML schema looks like
+
+.. code-block::
+
+ default_schema = [{'name' : 'herd',
+ 'multiple' : (True, ""),
+ 'required' : False,
+ 'subtags' : []},
+
+ {'name' : 'maintainer',
+ 'multiple' : (True, ""),
+ 'required' : False,
+ 'subtags' : [{'name' : 'email',
+ 'multiple' : (False, ""),
+ 'required' : True,
+ 'subtags' : []},
+ {'name' : 'name',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : []},
+ {'name' : 'description',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : []},
+ ]
+ },
+
+ {'name' : 'longdescription',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : []},
+
+ {'name' : 'use',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : [{'name' : 'flag',
+ 'multiple' : (True, "name"),
+ 'required' : True,
+ 'subtags' : []}]
+ },
+
+ {'name' : 'upstream',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : [{'name' : 'maintainer',
+ 'multiple' : (True, ""),
+ 'required' : False,
+ 'subtags' : [{'name' : 'name',
+ 'multiple' : (False, ""),
+ 'required' : True,
+ 'subtags' : []},
+ {'name' : 'email',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : []}]},
+ {'name' : 'changelog',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : []},
+ {'name' : 'doc',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : []},
+ {'name' : 'bugs-to',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : []},
+ {'name' : 'remote-id',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : []},
+ ]
+ },
+ ]
+
+So to have metadata.xml filled with e.g. maintainer info you should add to ebuild data
+something like
+
+.. code-block::
+
+ {'maintainer' : [{'email' : 'piatlicki@gmail.com',
+ 'name' : 'Jauhien Piatlicki'}]}
+
+Layman integration
+==================
+
+There is a **layman** integration for **g-sorcery** (thanks to Brian Dolbec and Auke Booij here).
+To use it you just need to install and xml file describing your repositories in
+**/etc/layman/overlays** directory. For our example of backend config we could write an xml file
+that looks like
+
+.. code-block::
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE repositories SYSTEM "/dtd/repositories.dtd">
+ <repositories xmlns="" version="1.0">
+ <repo quality="experimental" status="unofficial">
+ <name>gnu-elpa</name>
+ <description>packages for emacs</description>
+ <homepage>http://elpa.gnu.org/</homepage>
+ <owner>
+ <email>piatlicki@gmail.com</email>
+ <name>Jauhien Piatlicki</name>
+ </owner>
+ <source type="g-sorcery">gs-elpa gnu-elpa</source>
+ </repo>
+ <repo quality="experimental" status="unofficial">
+ <name>marmalade</name>
+ <description>packages for emacs</description>
+ <homepage>http://marmalade-repo.org/</homepage>
+ <owner>
+ <email>piatlicki@gmail.com</email>
+ <name>Jauhien Piatlicki</name>
+ </owner>
+ <source type="g-sorcery">gs-elpa marmalade</source>
+ </repo>
+ <repo quality="experimental" status="unofficial">
+ <name>melpa</name>
+ <description>packages for emacs</description>
+ <homepage>http://melpa.milkbox.net</homepage>
+ <owner>
+ <email>piatlicki@gmail.com</email>
+ <name>Jauhien Piatlicki</name>
+ </owner>
+ <source type="g-sorcery">gs-elpa melpa</source>
+ </repo>
+ </repositories>
+
+In entries **<source type="g-sorcery">gs-elpa melpa</source>** the source type
+should always be **g-sorcery**, **gs-elpa** is backend name and **melpa** is repository name.
+
+For full description of format of this file see **layman** documentation.
+
+Note: at the moment layman-9999 does not support **g-sorcery** overlay type and you should
+patch it with https://raw.github.com/jauhien/g-sorcery/master/layman-git-g-sorcery.patch
+
+Summary
+=======
+
+So to create your own backend you should write a module named **backend** and define there
+a variable named **instance** that is an instance of g_sorcery.backend.Backend class. Or something
+that quacks like this class.
+
+Before doing it you should have defined classes you pass to it as parameters. They should be database
+generator, two ebuild generators, eclass and metadata generators.
+
+Also you should write an executable that calls g-sorcery and some configs.