diff options
-rw-r--r-- | bdep/git.cxx | 30 | ||||
-rw-r--r-- | bdep/git.hxx | 32 | ||||
-rw-r--r-- | bdep/git.ixx | 40 | ||||
-rw-r--r-- | bdep/git.txx | 50 | ||||
-rw-r--r-- | bdep/project-email.cxx | 2 | ||||
-rw-r--r-- | bdep/publish.cxx | 14 |
6 files changed, 115 insertions, 53 deletions
diff --git a/bdep/git.cxx b/bdep/git.cxx index c26d257..c0b48fc 100644 --- a/bdep/git.cxx +++ b/bdep/git.cxx @@ -4,7 +4,8 @@ #include <bdep/git.hxx> -#include <libbutl/filesystem.mxx> +#include <libbutl/git.mxx> +#include <libbutl/standard-version.mxx> #include <bdep/diagnostics.hxx> @@ -12,14 +13,27 @@ using namespace butl; namespace bdep { - bool - git (const dir_path& d) + static optional<standard_version> git_ver; + + void + git_check_version () { - // .git can be either a directory or a file in case of a submodule. - // - return entry_exists (d / ".git", - true /* follow_symlinks */, - true /* ignore_errors */); + if (!git_ver) + { + // Make sure that the getline() function call doesn't end up with an + // infinite recursion. + // + git_ver = standard_version (); + + optional<string> s (git_line (false /* ignore_error */, "--version")); + + if (!s || !(git_ver = git_version (*s))) + fail << "unable to obtain git version"; + + if (git_ver->version < 20120000000) + fail << "unsupported git version " << *git_ver << + info << "minimum supported version is 2.12.0" << endf; + } } optional<string> diff --git a/bdep/git.hxx b/bdep/git.hxx index 1552670..ca49622 100644 --- a/bdep/git.hxx +++ b/bdep/git.hxx @@ -5,39 +5,49 @@ #ifndef BDEP_GIT_HXX #define BDEP_GIT_HXX +#include <libbutl/git.mxx> + #include <bdep/types.hxx> #include <bdep/utility.hxx> namespace bdep { - // Return true if the specified directory is a git repository root (contains - // the .git filesystem entry). - // - bool - git (const dir_path&); + using butl::git_repository; - template <typename... A> - inline void - run_git (const dir_path& repo, A&&... args); + template <typename I, typename O, typename E, typename... A> + process + start_git (I&& in, O&& out, E&& err, A&&... args); template <typename I, typename O, typename E, typename... A> - inline process - start_git (I&& in, O&& out, E&& err, const dir_path& repo, A&&... args); + process + start_git (const dir_path& repo, I&& in, O&& out, E&& err, A&&... args); + + void + finish_git (process& pr, bool io_read = false); + + template <typename... A> + void + run_git (const dir_path& repo, A&&... args); // Return the first line of the git output. If ignore_error is true, then // suppress stderr, ignore (normal) error exit status, and return nullopt. // template <typename... A> optional<string> + git_line (bool ignore_error, A&&... args); + + template <typename... A> + optional<string> git_line (const dir_path& repo, bool ignore_error, A&&... args); // Similar to the above but takes the already started git process with a // redirected output pipe. // optional<string> - git_line (process&& pr, fdpipe&& pipe, bool ignore_error = false); + git_line (process&& pr, fdpipe&& pipe, bool ignore_error); } #include <bdep/git.ixx> +#include <bdep/git.txx> #endif // BDEP_GIT_HXX diff --git a/bdep/git.ixx b/bdep/git.ixx index e71375a..9369564 100644 --- a/bdep/git.ixx +++ b/bdep/git.ixx @@ -2,43 +2,31 @@ // copyright : Copyright (c) 2014-2018 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -using namespace butl; - namespace bdep { - template <typename... A> - inline void - run_git (const dir_path& repo, A&&... args) + template <typename I, typename O, typename E, typename... A> + inline process + start_git (const dir_path& repo, I&& in, O&& out, E&& err, A&&... args) { - return run ("git", "-C", repo, forward<A> (args)...); + return start_git (forward<I> (in), + forward<O> (out), + forward<E> (err), + "-C", repo, + forward<A> (args)...); } - template <typename I, typename O, typename E, typename... A> - inline process - start_git (I&& in, O&& out, E&& err, const dir_path& repo, A&&... args) + inline void + finish_git (process& pr, bool io_read) { - return start (forward<I> (in), - forward<O> (out), - forward<E> (err), - "git", - "-C", repo, - forward<A> (args)...); + finish ("git", pr, io_read); } template <typename... A> inline optional<string> git_line (const dir_path& repo, bool ie, A&&... args) { - fdpipe pipe (fdopen_pipe ()); - auto_fd null (ie ? fdnull () : auto_fd ()); - - process pr (start (0 /* stdin */, - pipe /* stdout */, - ie ? null.get () : 2 /* stderr */, - "git", - "-C", repo, - forward<A> (args)...)); - - return git_line (move (pr), move (pipe), ie); + return git_line (ie, + "-C", repo, + forward<A> (args)...); } } diff --git a/bdep/git.txx b/bdep/git.txx new file mode 100644 index 0000000..aef5f3d --- /dev/null +++ b/bdep/git.txx @@ -0,0 +1,50 @@ +// file : bdep/git.txx -*- C++ -*- +// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +namespace bdep +{ + template <typename... A> + void + run_git (const dir_path& repo, A&&... args) + { + process pr (start_git (repo, + 0 /* stdin */, + 1 /* stdout */, + 2 /* stderr */, + forward<A> (args)...)); + + finish_git (pr); + } + + void + git_check_version (); + + template <typename I, typename O, typename E, typename... A> + process + start_git (I&& in, O&& out, E&& err, A&&... args) + { + git_check_version (); + + return start (forward<I> (in), + forward<O> (out), + forward<E> (err), + "git", + forward<A> (args)...); + } + + template <typename... A> + optional<string> + git_line (bool ie, A&&... args) + { + fdpipe pipe (fdopen_pipe ()); + auto_fd null (ie ? fdnull () : auto_fd ()); + + process pr (start_git (0 /* stdin */, + pipe /* stdout */, + ie ? null.get () : 2 /* stderr */, + forward<A> (args)...)); + + return git_line (move (pr), move (pipe), ie); + } +} diff --git a/bdep/project-email.cxx b/bdep/project-email.cxx index 2b836f2..6216d28 100644 --- a/bdep/project-email.cxx +++ b/bdep/project-email.cxx @@ -27,7 +27,7 @@ namespace bdep // See if this is a VCS repository we recognize. // - if (git (prj)) + if (git_repository (prj)) { // In git the author email can be specified with the GIT_AUTHOR_EMAIL // environment variable after which things fall back to the committer diff --git a/bdep/publish.cxx b/bdep/publish.cxx index 3650381..40a1724 100644 --- a/bdep/publish.cxx +++ b/bdep/publish.cxx @@ -44,7 +44,7 @@ namespace bdep static url control_url (const dir_path& prj) { - if (git (prj)) + if (git_repository (prj)) { // First try remote.origin.build2ControlUrl which can be used to specify // a custom URL (e.g., if a correct one cannot be automatically derived @@ -890,7 +890,7 @@ namespace bdep // // See if this is a VCS repository we recognize. // - if (ctrl && git (prj)) + if (ctrl && git_repository (prj)) { // Checkout the build2-control branch into a separate working tree not // to interfere with the user's stuff. @@ -919,10 +919,10 @@ namespace bdep bool q (verb < 2); auto_fd null (q ? fdnull () : auto_fd ()); - process pr (start_git (0 /* stdin */, + process pr (start_git (prj, + 0 /* stdin */, q ? null.get () : 1 /* stdout */, q ? null.get () : 2 /* stderr */, - prj, "worktree", "add", wd, @@ -1003,15 +1003,15 @@ namespace bdep auto_fd null (fdnull ()); fdpipe pipe (fdopen_pipe ()); - process pr (start_git (null.get () /* stdin */, + process pr (start_git (prj, + null.get () /* stdin */, pipe /* stdout */, 2 /* stderr */, - prj, "hash-object", "-wt", "tree", "--stdin")); - optional<string> tree (git_line (move (pr), move (pipe))); + optional<string> tree (git_line (move (pr), move (pipe), false)); if (!tree) fail << "unable to create git tree object for build2-control"; |