aboutsummaryrefslogtreecommitdiff
path: root/bpkg/fetch.hxx
blob: 6578f0de6b2c5720721ddd6a0730fd02b823a7ce (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
// file      : bpkg/fetch.hxx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

#ifndef BPKG_FETCH_HXX
#define BPKG_FETCH_HXX

#include <ctime> // time_t

#include <libbpkg/manifest.hxx>

#include <bpkg/types.hxx>
#include <bpkg/utility.hxx>

#include <bpkg/common-options.hxx>

namespace bpkg
{
  // Repository type pkg (fetch-pkg.cxx).
  //

  // If HTTP proxy is specified via the --pkg-proxy option, then use it for
  // fetching manifests and archives from the remote pkg repository.
  //
  pkg_repository_manifests
  pkg_fetch_repositories (const dir_path&, bool ignore_unknown);

  pair<pkg_repository_manifests, string /* checksum */>
  pkg_fetch_repositories (const common_options&,
                          const repository_location&,
                          bool ignore_unknown);

  pkg_package_manifests
  pkg_fetch_packages (const dir_path&, bool ignore_unknown);

  pair<pkg_package_manifests, string /* checksum */>
  pkg_fetch_packages (const common_options&,
                      const repository_location&,
                      bool ignore_unknown);

  signature_manifest
  pkg_fetch_signature (const common_options&,
                       const repository_location&,
                       bool ignore_unknown);

  void
  pkg_fetch_archive (const common_options&,
                     const repository_location&,
                     const path& archive,
                     const path& dest);

  // Repository type git (fetch-git.cxx).
  //

  // Create a git repository in the specified directory and prepare it for
  // fetching from the specified repository location. Note that the repository
  // URL fragment is neither used nor validated.
  //
  void
  git_init (const common_options&,
            const repository_location&,
            const dir_path&);

  // Fetch a git repository in the specifid directory (previously created by
  // git_init() for the references obtained with the repository URL fragment
  // filters, returning commit ids these references resolve to in the earliest
  // to latest order. Update the remote repository URL, if changed. After
  // fetching the repository working tree state is unspecified (see
  // git_checkout()).
  //
  // Note that submodules are not fetched.
  //
  struct git_fragment
  {
    // User-friendly fragment name is either a ref (tags/v1.2.3, heads/master,
    // HEAD) or an abbreviated commit id (0123456789ab).
    //
    string      commit;
    std::time_t timestamp;
    string      friendly_name;
  };

  vector<git_fragment>
  git_fetch (const common_options&,
             const repository_location&,
             const dir_path&);

  // Checkout the specified commit previously fetched by git_fetch().
  //
  // Note that submodules may not be checked out.
  //
  void
  git_checkout (const common_options&,
                const dir_path&,
                const string& commit);

  // Fetch (if necessary) and checkout submodules, recursively, in a working
  // tree previously checked out by git_checkout(). Update the remote
  // repository URL, if changed.
  //
  void
  git_checkout_submodules (const common_options&,
                           const repository_location&,
                           const dir_path&);


  // Verify that the symlinks target paths in the working tree are valid,
  // relative, and none of them refer outside the repository directory.
  //
  void
  git_verify_symlinks (const common_options&, const dir_path&);

  // Fix up or revert the fixes (including in submodules, recursively) in a
  // working tree previously checked out by git_checkout() or
  // git_checkout_submodules(). Return true if any changes have been made to
  // the filesystem. On error issue diagnostics and return nullopt in the
  // ignore errors mode and throw failed otherwise.
  //
  // Noop on POSIX. On Windows it may replace git's filesystem-agnostic
  // symlinks with hardlinks for the file targets and junctions for the
  // directory targets. Note that it still makes sure the working tree is
  // being treated by git as "clean" despite the changes.
  //
  optional<bool>
  git_fixup_worktree (const common_options&,
                      const dir_path&,
                      bool revert,
                      bool ignore_errors = false);

  // Low-level fetch API (fetch.cxx).
  //

  // Start the process of fetching the specified URL. If out is empty, then
  // fetch to stdout. In this case also don't show any progress unless we are
  // running verbose. If user_agent is empty, then send the default (fetch
  // program specific) User-Agent header value. If the HTTP proxy URL is not
  // empty and the URL to fetch is HTTP(S), then fetch it via the specified
  // proxy server converting the https URL scheme to http (see the --pkg-proxy
  // option for details).
  //
  process
  start_fetch (const common_options&,
               const string& url,
               const path& out = {},
               const string& user_agent = {},
               const butl::url& proxy = {});

  // Similar to the above but can only be used for HTTP(S) URLs. Additionally
  // return the HTTP status code, if the underlying fetch program provides an
  // easy way to retrieve it, and 0 otherwise.
  //
  // In the former case redirect the fetch process stderr to a pipe, so that
  // depending on the returned status code the caller can either drop or dump
  // the fetch process diagnostics. May also redirect stderr in the latter
  // case for some implementation-specific reasons (to prevent the underlying
  // fetch program from interacting with the user, etc). The caller can detect
  // whether stderr is redirected by checking process::in_efd.
  //
  // In contrast to start_fetch() always fetch to stdout, which can be read by
  // the caller from the specified stream. On HTTP errors (e.g., 404) this
  // stream may contain the error description returned by the server and the
  // process may exit with 0 code.
  //
  // If the quiet argument is true, then, if stderr is redirected, minimize
  // the amount of diagnostics printed by the fetch program by only printing
  // errors. That allows the caller to read stdout and stderr streams
  // sequentially in the blocking mode by assuming that the diagnostics always
  // fits into the pipe buffer. If stderr is not redirected, then the quiet
  // argument is ignored in favor of the more informative diagnostics.
  //
  pair<process, uint16_t>
  start_fetch_http (const common_options&,
                    const string& url,
                    ifdstream& out,
                    fdstream_mode out_mode,
                    bool quiet,
                    const string& user_agent = {},
                    const butl::url& proxy = {});
}

#endif // BPKG_FETCH_HXX