Repair ReST link format
[ryppl:doc.git] / source / dependency-management.rst
1 Dependency Management
2 =====================
3
4 The Graph
5 ---------
6
7 This configuration of dependencies should be enough to uncover many of the edge cases.
8
9 .. digraph:: lib_dependencies
10
11    "libA" -> "libC"
12    "libA" -> "libX"
13    "libB" -> "libX"
14    "proj" -> "libA"
15    "proj" -> "libB"
16
17    
18 *proj* is a project that might not be hosted at ryppl. *libA*, *libB*,
19 *libC*, and *libX* are ryppl library projects.
20
21 .. Admonition:: Question
22
23    Can we simplify the diagram without losing important cases by
24    adding an arc from *proj* to *libX* and dropping *libB* altogether?
25
26 Specifics of Setup
27 ------------------
28
29 The developer of *libA* has a .ryppl file to his project at the top level::
30
31   depends libX:1.0-2.2,3.1
32   depends libC
33
34 This specifies a dependency on a version of libX numbered 1.0 through
35 2.2 or numbered 3.1.  
36
37 .. Note:: We will need a rule for decoding and comparing version
38    names/numbers.  Likely it will need to cover more complicated
39    versions like 1.1b2, etc.
40
41 *libB* has a similar .ryppl file::
42
43   depends libX:2.0-2.5,3.0
44
45 The person developing *proj* does:
46
47 ::
48
49   ~/proj% ryppl get libA libB
50
51 This will pull down the latest release of *libA*, *libB*, and *libC* and version 2.2 of *libX*, since it's the latest version
52 compatible with both the latest *libA* and *libB*.
53
54 Alternatively, the developer of *proj* can have his own .ryppl file::
55
56   depends libA libB
57
58 and simply execute::
59
60   ~/proj% ryppl
61
62 In case of conflicts,where the latest *libA* and *libB* are not
63 compatible with any common version of *libX*, the user should be offered options
64
65 * Abort
66 * Look for earlier versions of *libA* and *libB* that are compatible
67 * Fall back to a guess about a compatible *libX*
68
69 The default assumption should be that later versions don't break
70 backward-compatibility, so a project that depends on v2.0 of *libX*
71 will also work with v3.0.
72
73 Events
74 ------
75
76 Now we'll look at a number of things that might happen.  A set of
77 changes to be applied will be referred to here as a “patch,” even if
78 not expressed or completely expressible as a patch file.
79
80 Developer Update
81 ::::::::::::::::
82
83 Library developer propagates a patch “downstream” (from library
84 dependency to dependent project).  Propagation can either be 
85
86 * a **release**, where a patch becomes part of one or more named
87   categories of updates (e.g. “critical update,” “beta,” “version
88   upgrade,” etc.) known as a *release branch* that can be subscribed
89   to by users and automatically applied.
90
91 * a **downstream test request**, where specific users are asked to try
92   a patch, but it is not “released” for general consumption.  The
93   patch gets its own name and is not (yet) part of a release branch.
94
95 Downstream patch propagation will cause some automatic source merging
96 when downstream subscribers.  Some of the (likely) working tree states being
97 employed by users may be known to the upstream developer, e.g. the
98 HEADs of any release branches are likely candidates.  
99
100 *Ideally* we'd like to (optionally) automatically test compatibility
101 of any patch with these known downstream states at two levels—a test
102 for a clean merge or a full regression test—but these don't seem like
103 “priority 1” features.  
104
105 Regardless, downstream merges will sometimes fail, or fail to work.
106 In these cases, it is crucial that downstream users' working tree
107 states are restored.  Such failures should be automatically reported
108 upstream in a way that allows the upstream developer to correct them.
109
110 User Update
111 :::::::::::
112
113 The developer of *proj* patches one of the libraries on which *proj*
114 depends.  
115
116 The change will be checked into the user's repository, and persists
117 there until integrated upstream.  Upstream integration works as
118 follows:
119
120 1. Ryppl locates the nearest ancestor of user's working state that
121    exists in developer's repo and creates a patch branch there.
122
123 2. Ryppl applies patch to patch branch
124
125 3. Ryppl switches user to patch branch and rebases any other user
126    changes.
127
128 This should all happen without modification of user's patch.  
129
130 If developer wants to make modifications before merging back into a
131 release branch, she is free to do so, but this should be done as
132 follow-up checkins on the patch branch, and requests for a
133 pull+update+test should be sent automatically to user.
134
135 Merge to release branch should similarly automatically notify user,
136 with the option for automatic or manual switching of user's working
137 tree state to the release branch.