1Pinto::Manual::TutorialU(s3e)r Contributed Perl DocumentaPtiinotno::Manual::Tutorial(3)
2
3
4
6 Pinto::Manual::Tutorial - A narrative introduction to Pinto
7
9 version 0.14
10
12 This tutorial walks you through some of the typical use cases for a
13 Pinto repository. Along the way, it demonstrates most of the pinto
14 commands. You are encouraged to try the commands as you read along.
15 If you would prefer to get a more condensed summary of features and
16 commands, please read the Pinto::Manual::QuickStart. For detailed
17 instructions on installing the software read Pinto::Manual::Installing.
18
20 Creating a repository
21 The first step in using Pinto is to create a repository, using the init
22 command like this:
23
24 pinto --root ~/repo init
25
26 This will create a new repository in the ~/repo directory. If that
27 directory does not exist, it will be created for you. If it already
28 does exist, then it must be empty.
29
30 The "--root" (or "-r") option specifies where the repository is. This
31 argument is required for every pinto command. But if you get tired of
32 typing it, you can set the "PINTO_REPOSITORY_ROOT" environment variable
33 to point to your repository instead.
34
35 The repository is created with a stack called "master" which is also
36 marked as the default stack. We'll talk more about stacks and default
37 stack later.
38
39 Inspecting the repository
40 Now that you have a repository, let's look inside it. To see the
41 contents of a repository, use the list command:
42
43 pinto --root ~/repo list
44
45 You will use the list command quite often. But at this point, the
46 listing will be empty because there is nothing in the repository. So
47 let's go ahead and add something...
48
49 Adding dependencies
50 Suppose we are working on an application called My-App that contains a
51 package called "My::App". The application also depends on the URI
52 package. Using the pull command, you can bring the URI package into
53 your repository:
54
55 pinto --root ~/repo pull URI
56
57 You will be prompted to enter a log message that describes why this
58 change is happening. The message template will include a semi-
59 informative generated message. Feel free to edit this message as you
60 see fit. Save the file and close your editor when you are done.
61
62 Now, you should have URI in your local repository. So lets look and
63 see what we really got. Once again, you use the list command to see
64 inside the repository:
65
66 pinto --root ~/repo list
67
68 This time, the listing will look something like this:
69
70 rf URI 1.60 GAAS/URI-1.60.tar.gz
71 rf URI::Escape 3.31 GAAS/URI-1.60.tar.gz
72 rf URI::Heuristic 4.20 GAAS/URI-1.60.tar.gz
73 ...
74
75 You can see that the URI package has been added to the repository, as
76 well as all the prerequisites for URI, and all of their prerequisites,
77 and so on.
78
79 Adding your own distributions
80 Now suppose that you've finished work on My-App and your ready to
81 release the first version. Using your preferred build tool
82 (ExtUtils::MakeMaker, Module::Build, Module::Install etc.) you package
83 a release as My- App-1.0.tar.gz. Now put the distribution into the
84 repository with the add command:
85
86 pinto --root ~/repo add path/to/My-App-1.0.tar.gz
87
88 When you list the repository contents now, it will include the
89 "My::App" package and show you as the author of the distribution:
90
91 rl My::App 1.0 JEFF/My-App-1.0.tar.gz
92 rf URI 1.60 GAAS/URI-1.60.tar.gz
93 rf URI::Escape 3.31 GAAS/URI-1.60.tar.gz
94 rf URI::Heuristic 4.20 GAAS/URI-1.60.tar.gz
95 ...
96
97 Installing packages
98 Now the repository contains both your application and all of its
99 prerequisites, so you can install it into your environment using the
100 install command:
101
102 pinto --root ~/repo install My::App
103
104 When "My::App" is installed, it will only use the prerequisites that
105 are in your repository. Even if a newer version of URI is released to
106 the CPAN in the future, "My::App" will always be built with the same
107 versions of the same prerequisites that you developed and tested
108 against. This ensures your application builds will be stable and
109 predictable.
110
111 On the surface, a Pinto repository looks like an ordinary CPAN, so you
112 can also install packages from it using cpanm directly. All you have
113 to do is point them at the URI of your repository (under the hood, this
114 is all the install command is really doing anyway). For example:
115
116 cpanm --mirror file:///home/jeff/repo --mirror-only My::App
117
118 The "--mirror-only" flag is important because it tells cpanm to not use
119 the "cpanmetadb" to resolve packages. Instead you only want to use the
120 index from your repository.
121
122 You can do the same thing with cpan and cpanp as well. See their
123 documentation for information on how to set the URI of the repository.
124
125 Upgrading a dependency
126 Suppose that several weeks have passed since you first released My-App
127 and now URI version 1.62 is available on the CPAN. It has some bug
128 critical fixes that you'd like to get. Again, we can bring that into
129 the repository using the pull command. But since your repository
130 already contains a version of URI, you must indicate that you want a
131 *newer* one by specifying the minimum version that you want:
132
133 pinto --root ~/repo pull URI~1.62
134
135 If you look at the listing again, this time you'll see the newer
136 version of URI (and possibly other packages as well):
137
138 rl My::App 1.0 JEFF/My-App-1.0.tar.gz
139 rf URI 1.62 GAAS/URI-1.62.tar.gz
140 rf URI::Escape 3.38 GAAS/URI-1.62.tar.gz
141 rf URI::Heuristic 4.20 GAAS/URI-1.62.tar.gz
142 ...
143
144 If the new version of URI requires any new prerequisites, those will be
145 in the repository too. Now when you install "My::App", you'll get
146 version 1.62 of URI.
147
149 So far in this tutorial, we've treated the repository as a singular
150 resource. For example, when we upgraded URI in the last section, it
151 impacted every person and every application that might have been using
152 the repository. But this kind of broad impact is undesirable. You
153 would prefer to make those kinds of changes in isolation and test them
154 before forcing everyone else to upgrade. This is what stacks are
155 designed for.
156
157 What is a stack
158 All CPAN-like repositories have an index which maps the latest version
159 of each package to the archive that contains it. Usually, there is
160 only one such index per repository. But with Pinto, there can be many
161 indexes. Each of these indexes is called a "stack". This allows you
162 to create different stacks of dependencies within a single repository.
163 So you could have a "development" stack and a "production" stack.
164 Whenever you add a distribution or upgrade a prerequisite, it only
165 affects one stack.
166
167 The default stack
168 Before getting into the gory details, you first need to know about the
169 default stack. For most operations, the name of the stack is an
170 optional parameter. So if you do not specify a stack explicitly, then
171 the operation is applied to whichever stack is marked as the default.
172
173 In any repository, there is never more than one default stack. When we
174 created this repository, the "master" stack was marked as the default.
175 You can also change the default stack or change the name of a stack,
176 but we won't go into that here. See the default command to learn more
177 about that.
178
179 Just remember that "master" is the name of the stack that was created
180 when the repository was first initialized.
181
182 Creating a stack
183 Suppose your repository contains version 1.60 of URI, but version 1.62
184 has been released to the CPAN, just like in the earlier section. You
185 want to try upgrading, but this time you're going to do it on a
186 separate stack.
187
188 Thus far, everything you've added or pulled into the repository has
189 gone onto the "master" stack. You could create an entirely new stack,
190 but the "master" stack already has the prerequisites for My-App, so
191 we're just going to make a clone using the copy command:
192
193 pinto --root ~/repo copy master uri_upgrade
194
195 This creates a new stack called "uri_upgrade". If you want to see the
196 contents of that stack, just use the list command with the "--stack"
197 option:
198
199 pinto --root ~/repo list --stack uri_upgrade
200
201 The listing should be identical to the "master" stack:
202
203 rl My::App 1.0 JEFF/My-App-1.0.tar.gz
204 rf URI 1.60 GAAS/URI-1.60.tar.gz
205 ...
206
207 Upgrading a stack
208 Now that you've got a separate stack, you can try upgrading URI. Just
209 as before, you'll use the pull command. But this time, you'll tell
210 Pinto that you want the packages to be pulled onto the "uri_upgrade"
211 stack:
212
213 pinto --root ~/repo pull --stack uri_upgrade URI~1.62
214
215 Now lets compare the "master" and "uri_upgrade" stacks using the diff
216 command:
217
218 pinto --root ~/repo diff master uri_upgrade
219
220 +rf URI 1.62 GAAS/URI-1.62.tar.gz
221 +rf URI::Escape 3.31 GAAS/URI-1.62.tar.gz
222 +rf URI::Heuristic 4.20 GAAS/URI-1.62.tar.gz
223 ...
224 -rf URI 1.60 GAAS/URI-1.60.tar.gz
225 -rf URI::Escape 3.31 GAAS/URI-1.60.tar.gz
226 -rf URI::Heuristic 4.20 GAAS/URI-1.60.tar.gz
227
228 The output is similar to the diff(1) command. Records starting with a
229 "+" were added and those starting with a "-" have been removed.
230
231 Installing from a stack
232 With URI upgraded on the "uri_upgrade" stack, you can now try building
233 and testing our application. All you have to do is run the install
234 command and point to the right stack:
235
236 pinto --root ~/repo install --stack uri_upgrade My::App
237
238 This will build My::App using only the prerequisites that are on the
239 "uri_upgrade" stack. If the tests pass, then you can confidently
240 upgrade URI on the "dev" stack as well.
241
242 As mentioned earlier, you can also use cpanm to install modules from
243 your repository. But when installing from a stack other than the
244 default, you must append "stacks/stack_name" to the URI. For example:
245
246 cpanm --mirror file:///home/jeff/repo/stacks/uri_upgrade --mirror-only My::App
247
249 In the last section, we used a stack to experiment with upgrading a
250 dependency. Fortunately, all the tests passed. But what if the tests
251 didn't pass? If the problem lies within My-App and you can quickly
252 correct it, you might just modify your code, release version 2.0 of My-
253 App, and then proceed to upgrade URI on the "master" stack.
254
255 But if the issue is a bug in URI or it will take a long time to fix My-
256 App, then you have a real problem. You don't want someone else to
257 upgrade URI, nor do you want it to be upgraded inadvertently to satisfy
258 some other prerequisite that My-App may have. Until the bug is fixed
259 (in either URI or My-App) you need to prevent URI from being upgraded.
260 This is what pins are for.
261
262 Pinning a package
263 When you pin a package, that version of the package is forced to stay
264 in a stack. Any attempt to upgrade it (either directly or via another
265 prerequisite) will fail. To pin a package, use the pin command like
266 this:
267
268 pinto --root ~/repo pin URI
269
270 If you look at the listing for the "master" stack again, you'll see
271 something like this:
272
273 ...
274 rl My::App 1.0 JEFF/My-App-1.0.tar.gz
275 rf! URI 1.60 GAAS/URI-1.60.tar.gz
276 rf! URI::Escape 3.31 GAAS/URI-1.60.tar.gz
277 ...
278
279 The "!" near the beginning of the line indicates the package has been
280 pinned. Notice every package in the URI-1.60.tar.gz distribution has
281 been pinned, so it is impossible to partially upgrade a distribution
282 (this situation could happen when a package moves into a different
283 distribution).
284
285 Unpinning a packages
286 After a while, suppose you fix the problem in My-App or a new version
287 of URI is released that fixes the bug. When that happens, you can
288 unpin URI from the stack using the unpin command:
289
290 pinto --root ~/repo unpin URI
291
292 At this point you're free to upgrade URI to the latest version whenever
293 you're ready. Just as with pinning, when you unpin a package, it
294 unpins every other package it that distribution as well.
295
297 Pins and stacks are used together to help manage change during the
298 development cycle. For example, you could create a stack called "prod"
299 that contains your known-good dependencies. Likewise, you could create
300 a stack called "dev" that contains experimental dependencies for your
301 next release. Initially, the "dev" stack is just a copy of the "prod"
302 stack.
303
304 As development proceeds, you may upgrade or add several packages on the
305 "dev" stack. If an upgraded package breaks your application, then
306 you'll place a pin in that package on the "prod" stack to signal that
307 it shouldn't be upgraded.
308
309 Pins and Patches
310 Sometimes you may find that a new version of a CPAN distribution has a
311 bug but the author is unable or unwilling to fix it (at least not
312 before your next release is due). In that situation, you may elect to
313 make a local patch of the CPAN distribution.
314
315 So suppose that you forked the code for URI and made a local version of
316 the distribution called URI-1.60_PATCHED.tar.gz. You can add it to
317 your repository using the add command:
318
319 pinto --root ~/repo add path/to/URI-1.60_PATCHED.tar.gz
320
321 In this situation, it is wise to pin the package as well, since you do
322 not want it to be updated until you are sure that the new release
323 includes your patch or the author has fixed the bug by other means.
324
325 pinto --root ~/repo pin URI
326
327 When the author of URI releases version 1.62 with your patch, you'll
328 want to try it before deciding to unpin from your locally patched
329 version. Just as before, this can be done by cloning the stack with
330 the copy command. Let's call it the "trial" stack this time:
331
332 pinto --root ~/repo copy master trial
333
334 But before you can update URI on the "trial" stack, you'll have to
335 unpin it there:
336
337 pinto --root ~/repo unpin --stack trial URI
338
339 Now you can proceed to update URI on the stack and try building
340 "My::App" like this:
341
342 pinto --root ~/repo update --stack trial URI
343 pinto --root ~/repo install --stack trial My::App
344
345 If all the tests pass, then you can merge the changes back to the
346 "master" stack:
347
348 pinto --root ~/repo merge trial master
349
350 Reviewing Past Changes
351 As you've noticed by now, each command that changes the state of a
352 stack requires a log message to describe it. You can review those
353 messages using the log command:
354
355 pinto --root ~/repo log
356
357 That should display something like this:
358
359 revision 4a62d7ce-245c-45d4-89f8-987080a90112
360 Date: Mar 15, 2013 1:58:05 PM
361 User: jeff
362
363 Pin GAAS/URI-1.59.tar.gz
364
365 Pinning URI because it is not causes our foo.t script to fail
366
367 revision 4a62d7ce-245c-45d4-89f8-987080a90112
368 Date: Mar 15, 2013 1:58:05 PM
369 User: jeff
370
371 Pull GAAS/URI-1.59.tar.gz
372
373 URI is required for HTTP support in our application
374
375 ...
376
377 The header for each message shows who made the change and when it
378 happened. It also has a unique identifier similar to Git's SHA-1
379 digests. You can use these identifiers to see the diffs between
380 different revisions or to reset the stack back to a prior revision [NB:
381 this feature is not actually implemented yet].
382
384 In this tutorial, you've seen the basic pinto commands for pulling
385 dependencies into the repository, and adding your own distributions to
386 the repository. You've also seen how to use stacks and pins to manage
387 your dependencies in the face of some common development obstacles.
388
389 Each command has several options that were not discussed in this
390 tutorial, and there are some commands that were not mentioned here at
391 all. So you are encouraged to explore the manual pages for each
392 command and learn more.
393
395 Pinto::Manual::QuickStart
396
397 Pinto::Manual::Installing
398
399 Pinto (the library)
400
401 pinto (the application)
402
404 Jeffrey Ryan Thalhammer <jeff@stratopan.com>
405
407 This software is copyright (c) 2015 by Jeffrey Ryan Thalhammer.
408
409 This is free software; you can redistribute it and/or modify it under
410 the same terms as the Perl 5 programming language system itself.
411
412
413
414perl v5.38.0 2023-07-21 Pinto::Manual::Tutorial(3)