// -*- 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 to match any references, a non-pattern" << ::std::endl
       << "that 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.

