1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
##############
Developer docs
##############
This page contains information useful to people wanting to contribute changes to a :term:`patchset`.
************
Installation
************
.. note::
Patchtree is developed and tested on \*NIX-like operating systems.
Windows compatibility is not tested or guaranteed.
The output .patch files can of course be used anywhere where ``git apply`` works.
Make sure you have the following dependencies installed:
* Python 3 and pip
* Coccinelle (optional, see :ref:`processors`)
Installation can be done by cloning this repository and running
.. code::
$ pip install .
This will install any missing Python dependencies automatically as well.
To check if the installation was successful, run:
.. code::
$ patchtree -h
************
Nomenclature
************
.. glossary::
target
A directory of files to be modified (e.g. SDK or library releases).
inputs
patchset
A set of files that describe how to change the target source tree(s), placed in the same structure as the original source tree.
patch
A single file (usually ``.patch`` or ``.diff``) that lists changes to make to one specific target directory.
**********************
Building clean patches
**********************
In order to generate clean patches files, patchtree needs
* the (original) :term:`target` source tree (either as a folder or .zip file)
* a set of :term:`inputs`
The basic syntax of the patchtree CLI is as follows:
.. code:: none
$ patchtree TARGET INPUT [INPUT ...]
.. note::
The inputs are interpreted as globs.
By default, the resulting patch is written to the standard output.
This behavior, along with many other default behaviors can be changed through the command-line arguments (see ``--help``) or the `configuration file <ptconfig_>`_.
************************
Writing patchset sources
************************
Each patchset source applies to exactly one target source file, and describes any changes that should be made to that file.
When possible, patchset source files should describe changes *semantically* so they can apply to multiple versions of or variations in the target.
Patchtree allows you to do using a combination of :ref:`processors <processors>` and :ref:`diff engines <diffs>`.
Every patchset source is first processed by 0 or more processors.
These are indicated using the hash symbol (``#``) in the filename, and each process the input's contents sequentially from right to left.
After processing, the resulting file content is compared to the target source's content using a diff engine.
The diff engine is selected based on the file extension.
Example:
.. code:: none
file extension (.c)
/\
sdk/middleware/adapters/src/ad_crypto.c#cocci#jinja
\_____________________________________/\__________/
target source file path processors
(jinja -> cocci)
.. _processors:
Processors
==========
Processors transform the input's content before it is compared to the target file's content.
They can be chained, and are applied in reverse order (i.e. from right to left) from how they appear in the filename.
Each processor has access to the global :any:`Context` instance, the target file's content, and the (possibly processed) input's content.
The processors included with patchtree are listed below.
.. toctree::
:maxdepth: 1
processor.rst
Custom processors can be created by inheriting from the base :any:`Process` class and registering through the `configuration file <ptconfig_>`_'s :any:`processors <Config.processors>` value.
.. _diffs:
Diff engines
============
Diff engines dictate how the diff delta is calculated from the (possibly processed) input and the target file's content.
.. TODO: Diff engines are stupid, merge strategies can just as well be handled
by processors since they have access to the appropriate state and variables
The diff engines included with patchtree are listed below.
.. toctree::
:maxdepth: 1
diff.rst
Similar to processors, custom diff engines can be created by inheriting from the base :any:`Diff` class and registering through the `configuration file <ptconfig_>`_'s :any:`diff_strategies <Config.diff_strategies>` value.
.. _ptconfig:
******************
Configuration file
******************
The configuration file is a Python file sourced from ``ptconfig.py`` relative to the current working directory when executing the ``patchtree`` command.
This file can contain arbitrary Python code.
Certain global variables influence the behavior of patchtree when defined.
These variables are the member variables of the :any:`Config` class.
|