aboutsummaryrefslogtreecommitdiff
path: root/bpkg/utility.hxx
blob: 1763af0174f514e6633412adc78af15d3e6c726a (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
207
208
// file      : bpkg/utility.hxx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

#ifndef BPKG_UTILITY_HXX
#define BPKG_UTILITY_HXX

#include <memory>   // make_shared()
#include <string>   // to_string()
#include <cstring>  // strcmp(), strchr()
#include <utility>  // move(), forward(), declval(), make_pair()
#include <cassert>  // assert()
#include <iterator> // make_move_iterator()

#include <libbutl/ft/lang.hxx>

#include <libbutl/utility.mxx>         // icasecmp(), reverse_iterate(), etc
#include <libbutl/filesystem.mxx>
#include <libbutl/default-options.mxx>

#include <bpkg/types.hxx>
#include <bpkg/version.hxx>
#include <bpkg/common-options.hxx>

namespace bpkg
{
  using std::move;
  using std::forward;
  using std::declval;

  using std::make_pair;
  using std::make_shared;
  using std::make_move_iterator;
  using std::to_string;

  using std::strcmp;
  using std::strchr;

  // <libbutl/utility.mxx>
  //
  using butl::icasecmp;
  using butl::reverse_iterate;

  using butl::make_guard;
  using butl::make_exception_guard;

  using butl::getenv;
  using butl::setenv;
  using butl::unsetenv;

  // <libbutl/filesystem.mxx>
  //
  using butl::auto_rmfile;
  using butl::auto_rmdir;

  // <libbutl/default-options.mxx>
  //
  using butl::load_default_options;
  using butl::merge_default_options;

  // Empty string and path.
  //
  extern const string empty_string;
  extern const path empty_path;
  extern const dir_path empty_dir_path;

  // Widely-used paths.
  //
  extern const dir_path bpkg_dir;    // .bpkg/
  extern const dir_path certs_dir;   // .bpkg/certs/
  extern const dir_path repos_dir;   // .bpkg/repos/
  extern const dir_path current_dir; // ./

  // Temporary directory facility.
  //
  // This is normally .bpkg/tmp/ but can also be some system-wide directory
  // (e.g., /tmp/bpkg-XXX/) if there is no bpkg configuration. This directory
  // is automatically created and cleaned up for most commands in main() so
  // you don't need to call init_tmp() explicitly except for certain special
  // commands (like cfg-create).
  //
  extern dir_path temp_dir;

  auto_rmfile
  tmp_file (const string& prefix);

  auto_rmdir
  tmp_dir (const string& prefix);

  void
  init_tmp (const dir_path& cfg);

  void
  clean_tmp (bool ignore_errors);

  // Path.
  //
  // Normalize a path. Also make the relative path absolute using the current
  // directory.
  //
  path&
  normalize (path&, const char* what);

  inline path
  normalize (const path& f, const char* what)
  {
    path r (f);
    return move (normalize (r, what));
  }

  dir_path&
  normalize (dir_path&, const char* what);

  inline dir_path
  normalize (const dir_path& d, const char* what)
  {
    dir_path r (d);
    return move (normalize (r, what));
  }

  // Progress.
  //
  extern bool stderr_term; // True if stderr is a terminal.

  // Y/N prompt. See butl::yn_prompt() for details (this is a thin wrapper).
  //
  // Issue diagnostics and throw failed if no answer could be extracted from
  // stdin (e.g., because it was closed).
  //
  bool
  yn_prompt (const string& prompt, char def = '\0');

  // Filesystem.
  //
  bool
  exists (const path&, bool ignore_error = false);

  bool
  exists (const dir_path&, bool ignore_error = false);

  bool
  empty (const dir_path&);

  void
  mk (const dir_path&);

  void
  mk_p (const dir_path&);

  void
  rm (const path&, uint16_t verbosity = 3);

  enum class rm_error_mode {ignore, warn, fail};

  void
  rm_r (const dir_path&,
        bool dir_itself = true,
        uint16_t verbosity = 3,
        rm_error_mode = rm_error_mode::fail);

  void
  mv (const dir_path& from, const dir_path& to);

  // Set (with diagnostics at verbosity level 3 or higher) the new and return
  // the previous working directory.
  //
  dir_path
  change_wd (const dir_path&);

  // File descriptor streams.
  //
  fdpipe
  open_pipe ();

  auto_fd
  open_null ();

  // Directory extracted from argv[0] (i.e., this process' recall directory)
  // or empty if there is none. Can be used as a search fallback.
  //
  extern dir_path exec_dir;

  // Run build2, mapping verbosity levels. If quiet is true, then run build2
  // quiet if our verbosity level is 1.
  //
  const char*
  name_b (const common_options&);

  // Verbosity level 1 mapping.
  //
  enum class verb_b
  {
    quiet,    // Run quiet.
    progress, // Run quiet but (potentially) with progress.
    normal    // Run normally (at verbosity 1).
  };

  template <typename O, typename E, typename... A>
  process
  start_b (const common_options&, O&& out, E&& err, verb_b, A&&... args);

  template <typename... A>
  void
  run_b (const common_options&, verb_b, A&&... args);
}

#include <bpkg/utility.txx>

#endif // BPKG_UTILITY_HXX