aboutsummaryrefslogtreecommitdiff
path: root/bpkg/repository-types.cxx
blob: 90efcdd813c0b39dcd346c0f20503ce173939e9a (plain)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// -*- C++ -*-
//
// This file was generated by CLI, a command line interface
// compiler for C++.
//

// Begin prologue.
//
#include <bpkg/types-parsers.hxx>
//
// End prologue.

#include <bpkg/repository-types.hxx>

#include <map>

namespace bpkg
{
  ::bpkg::cli::usage_para
  print_bpkg_repository_types_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
  {
    CLI_POTENTIALLY_UNUSED (os);

    if (p != ::bpkg::cli::usage_para::none)
      os << ::std::endl;

    os << "\033[1mDESCRIPTION\033[0m" << ::std::endl
       << ::std::endl
       << "This help topic describes the repository types recognized by \033[1mbpkg\033[0m, their" << ::std::endl
       << "structure, and the format of their URLs. Currently three types of repositories" << ::std::endl
       << "are supported: archive-based \033[1mpkg\033[0m, directory-based \033[1mdir\033[0m, and version" << ::std::endl
       << "control-based \033[1mgit\033[0m." << ::std::endl
       << ::std::endl
       << "The repository location may specify the repository type as part of the URL" << ::std::endl
       << "scheme component in the \033[4mtype\033[0m\033[1m+\033[0m\033[4mprotocol\033[0m\033[0m form. For example:" << ::std::endl
       << ::std::endl
       << "git+https://example.com/foo" << ::std::endl
       << "dir+file:///tmp/repo" << ::std::endl
       << ::std::endl
       << "Note that the explicit specification is only needed when the correct type" << ::std::endl
       << "cannot be guessed from the URL. See \033[1mbpkg-rep-add(1)\033[0m for details." << ::std::endl
       << ::std::endl
       << "\033[1mPKG REPOSITORIES\033[0m" << ::std::endl
       << ::std::endl
       << "A \033[1mpkg\033[0m repository is \033[4marchive\033[0m-based. That is, it contains a collection of various" << ::std::endl
       << "packages/versions as archive files. For more information on the structure of" << ::std::endl
       << "\033[1mpkg\033[0m repositories refer to The \033[1mbuild2\033[0m Package Manager Manual (bpkg). The \033[1mpkg\033[0m" << ::std::endl
       << "repository location can be a local directory path or an \033[1mhttp(s)://\033[0m URL." << ::std::endl
       << ::std::endl
       << "\033[1mDIR REPOSITORIES\033[0m" << ::std::endl
       << ::std::endl
       << "A \033[1mdir\033[0m repository is \033[4mdirectory\033[0m-based. That is, it contains a collection of" << ::std::endl
       << "various packages as directories but only a single version per package can be" << ::std::endl
       << "present in such a repository. The \033[1mdir\033[0m repository location can be a local" << ::std::endl
       << "directory path or a \033[1mfile://\033[0m URL." << ::std::endl
       << ::std::endl
       << "A \033[1mdir\033[0m repository is expected to contain either the \033[1mmanifest\033[0m or" << ::std::endl
       << "\033[1mpackages.manifest\033[0m file in the root directory of the repository. If it only" << ::std::endl
       << "contains \033[1mmanifest\033[0m, then it is assumed to be a simple, single-package repository" << ::std::endl
       << "with the \033[1mmanifest\033[0m file being its package manifest. Otherwise, the" << ::std::endl
       << "\033[1mpackages.manifest\033[0m file should list the locations of available packages as" << ::std::endl
       << "described in Package List Manifest for \033[1mdir\033[0m Repositories" << ::std::endl
       << "(bpkg#manifest-package-list-dir)." << ::std::endl
       << ::std::endl
       << "A \033[1mdir\033[0m repository may also contain the \033[1mrepositories.manifest\033[0m file in the root" << ::std::endl
       << "directory of the repository. This file can be used to describe the repository" << ::std::endl
       << "itself as well as specify its prerequisite and complement repositories. See" << ::std::endl
       << "Repository List Manifest (bpkg#manifest-repository-list) for details on the" << ::std::endl
       << "format and semantics of this file." << ::std::endl
       << ::std::endl
       << "\033[1mGIT REPOSITORIES\033[0m" << ::std::endl
       << ::std::endl
       << "A \033[1mgit\033[0m repository is \033[4mversion control\033[0m-based. That is, it normally contains" << ::std::endl
       << "multiple versions of the same package (but can also contain several, usually" << ::std::endl
       << "related, packages in the same repository)." << ::std::endl
       << ::std::endl
       << "A \033[1mgit\033[0m repository has the same structure and manifest files as the \033[1mdir\033[0m" << ::std::endl
       << "repository. See Package List Manifest for \033[1mdir\033[0m Repositories" << ::std::endl
       << "(bpkg#manifest-package-list-dir) and Repository List Manifest" << ::std::endl
       << "(bpkg#manifest-repository-list) for details on their format and semantics." << ::std::endl
       << ::std::endl
       << "Theoretically, a \033[1mgit\033[0m repository may contain as many package versions as there" << ::std::endl
       << "are commits. Practically, however, we are normally only interested in a small" << ::std::endl
       << "subset of them while fetching and processing the necessary information for all" << ::std::endl
       << "of them could be prohibitively expensive.  As a result, by default, only" << ::std::endl
       << "advertised tags in the \033[1mrefs/tags/v*\033[0m form where the part after \033[1mv\033[0m is also a valid" << ::std::endl
       << "standard version (b#module-version) are considered to be sources of useful" << ::std::endl
       << "package versions. These commits normally correspond to released versions and" << ::std::endl
       << "are called the \033[4mdefault set\033[0m. Note that only the latest revision of each such" << ::std::endl
       << "version is considered." << ::std::endl
       << ::std::endl
       << "Instead of the default set, it is possible to provide a custom set of available" << ::std::endl
       << "versions by specifying one or more commit ids and/or references and/or" << ::std::endl
       << "reference patterns in the repository URL fragment (see \033[1mgit-ls-remote(1)\033[0m for" << ::std::endl
       << "details on advertised references). For example:" << ::std::endl
       << ::std::endl
       << "https://example.com/foo.git#v1.2.3" << ::std::endl
       << "https://example.com/foo.git#master" << ::std::endl
       << "https://example.com/foo.git#af234f56" << ::std::endl
       << "https://example.com/foo.git#tags/releases/*" << ::std::endl
       << "https://example.com/foo.git#HEAD,tags/v1.*.*,heads/feature-*" << ::std::endl
       << ::std::endl
       << "Furthermore, it is possible to expand (or narrow down) the default set using" << ::std::endl
       << "the special \033[1m##\033[0m fragment notation. For example:" << ::std::endl
       << ::std::endl
       << "https://example.com/foo.git##HEAD     - default set plus HEAD" << ::std::endl
       << "https://example.com/foo.git##heads/*  - default set plus branches" << ::std::endl
       << "https://example.com/foo.git##-v1.*    - default set minus v1.*" << ::std::endl
       << ::std::endl
       << "A \033[1mgit\033[0m repository URL fragment is a comma-separated list of reference filters in" << ::std::endl
       << "the following form:" << ::std::endl
       << ::std::endl
       << "[\033[4mrefname\033[0m][\033[1m@\033[0m\033[4mcommit\033[0m]\033[0m" << ::std::endl
       << ::std::endl
       << "Either \033[4mrefname\033[0m, \033[4mcommit\033[0m, or both must be specified. If both are specified then" << ::std::endl
       << "\033[4mrefname\033[0m is only used to minimize the amount of data fetched and \033[4mcommit\033[0m is" << ::std::endl
       << "expected to belong to its history. For example:" << ::std::endl
       << ::std::endl
       << ".../foo.git#master@48fba3625d65941bb85a39061bcf795d4949c778" << ::std::endl
       << ::std::endl
       << "The \033[4mrefname\033[0m part can be an abbreviated commit id or an advertised reference or" << ::std::endl
       << "reference pattern under \033[1mrefs/\033[0m. While \033[4mcommit\033[0m must be the complete, 40-characters" << ::std::endl
       << "SHA1 that need not be advertised. For convenience, a 40-characters filter that" << ::std::endl
       << "consists of only hexadecimal digits is assumed to be \033[4mcommit\033[0m even if not" << ::std::endl
       << "prefixed with \033[1m@\033[0m. In an unlikely event this produces an incorrect result, the" << ::std::endl
       << "\033[1m@\033[0m-form with omitted \033[4mcommit\033[0m can be used. For example:" << ::std::endl
       << ::std::endl
       << ".../foo.git#48fba3625d65941bb85a39061bcf795d4949c778   (commit id)" << ::std::endl
       << ".../foo.git#deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@  (reference)" << ::std::endl
       << ::std::endl
       << "The \033[4mrefname\033[0m part can use the \033[1m*\033[0m and \033[1m?\033[0m wildcard pattern characters with the" << ::std::endl
       << "standard semantics as well as the \033[1m**\033[0m character sequence which matches in" << ::std::endl
       << "subdirectories, recursively. For example:" << ::std::endl
       << ::std::endl
       << ".../foo.git#tags/v*    - tags/v1.2.3 but not tags/old/v0.1.0" << ::std::endl
       << ".../foo.git#tags/v**   - tags/v1.2.3 and tags/old/v0.1.0" << ::std::endl
       << ::std::endl
       << "A relative \033[4mrefname\033[0m is searched for in \033[1mrefs/\033[0m, \033[1mrefs/tags/\033[0m, and \033[1mrefs/heads/\033[0m as" << ::std::endl
       << "well as among symbolic references like \033[1mHEAD\033[0m. To anchor it to \033[1mrefs/\033[0m make it" << ::std::endl
       << "absolute, for example:" << ::std::endl
       << ::std::endl
       << ".../foo.git#tags/v*   - refs/tags/v1.2.3 but also refs/heads/tags/voo" << ::std::endl
       << ".../foo.git#/tags/v*  - refs/tags/v1.2.3 only" << ::std::endl
       << ::std::endl
       << "While a \033[4mrefname\033[0m pattern is allowed not match any references, a non-pattern that" << ::std::endl
       << "doesn't resolve to a reference is invalid." << ::std::endl
       << ::std::endl
       << "If a \033[4mrefname\033[0m starts with minus (\033[1m-\033[0m) then it is treated as an exclusion filter --" << ::std::endl
       << "any references that it matches are excluded from the set included by the" << ::std::endl
       << "preceding filters (or the default set). For example:" << ::std::endl
       << ::std::endl
       << ".../foo.git#v*,-v1.*  - exclude v1.* from v*" << ::std::endl
       << ".../foo.git##-v1.*    - exclude v1.* from default set" << ::std::endl
       << ::std::endl
       << "To support specifying literal leading minus, a \033[4mrefname\033[0m that starts with plus" << ::std::endl
       << "(\033[1m+\033[0m) is treated as an inclusion filter. For example:" << ::std::endl
       << ::std::endl
       << ".../foo.git#+x   - include  x" << ::std::endl
       << ".../foo.git#+-x  - include -x" << ::std::endl
       << ".../foo.git#++x  - include +x" << ::std::endl
       << ::std::endl
       << "Currently supported \033[1mgit\033[0m protocols are \033[1mgit://\033[0m, \033[1mssh://\033[0m (but not scp\033[0m pseudo-URL" << ::std::endl
       << "syntax), \033[1mhttp://\033[0m, and \033[1mhttps://\033[0m for remote repositories and \033[1mfile://\033[0m for local" << ::std::endl
       << "repositories. While \033[1mbpkg\033[0m tries to minimize the amount of information (history)" << ::std::endl
       << "fetched, it is not always possible for some protocols and/or server" << ::std::endl
       << "configurations, as discussed next." << ::std::endl
       << ::std::endl
       << "A \033[1mgit\033[0m repository accessible via \033[1mhttp(s)://\033[0m can use either \033[4mdumb\033[0m or \033[4msmart\033[0m" << ::std::endl
       << "protocol (refer to the \033[1mgit\033[0m documentation for details). The dumb protocol" << ::std::endl
       << "provides only limited support for fetch minimization and if this protocol is" << ::std::endl
       << "used, then \033[1mbpkg\033[0m has no choice but to download a substantial amount of history." << ::std::endl
       << ::std::endl
       << "The smart protocol allows fetching of minimal history for tags and branches." << ::std::endl
       << "Whether this is also possible for (all) commit ids depends on whether the" << ::std::endl
       << "server is configured to allow fetching unadvertised commits. For details, refer" << ::std::endl
       << "to the \033[1muploadpack.allowReachableSHA1InWant\033[0m and \033[1muploadpack.allowAnySHA1InWant\033[0m" << ::std::endl
       << "\033[1mgit\033[0m configuration values." << ::std::endl
       << ::std::endl
       << "The \033[1mgit://\033[0m and \033[1mssh://\033[0m protocols are similar to smart \033[1mhttp://\033[0m in that they" << ::std::endl
       << "support fetching minimal history for tags and branches and may or may not" << ::std::endl
       << "support this for commit ids depending on the server configuration. Note," << ::std::endl
       << "however, that unlike for \033[1mhttp(s)://\033[0m, for these protocols \033[1mbpkg\033[0m does not try to" << ::std::endl
       << "sense if fetching unadvertised commits is allowed and always assumes that it is" << ::std::endl
       << "not. Also note that the sensed or assumed protocol capabilities can be" << ::std::endl
       << "overridden for a \033[1mgit\033[0m repository URL prefix using the \033[1m--git-capabilities\033[0m option" << ::std::endl
       << "(\033[1mbpkg-common-options(1)\033[0m)." << ::std::endl
       << ::std::endl
       << "Based on this information, to achieve optimal results the recommended protocol" << ::std::endl
       << "for remote repositories is smart \033[1mhttps://\033[0m. Additionally, if you are planning to" << ::std::endl
       << "refer to unadvertised commit ids, then also consider configuring the server to" << ::std::endl
       << "allow fetching unadvertised commits." << ::std::endl
       << ::std::endl
       << "The \033[1mfile://\033[0m protocol has the same fetch minimization support as \033[1mgit://\033[0m and is" << ::std::endl
       << "therefore treated the same." << ::std::endl;

    p = ::bpkg::cli::usage_para::text;

    return p;
  }
}

// Begin epilogue.
//
//
// End epilogue.