blob: 47519c221a6d6872a1a6cde3f810dbf8534cccba [file] [log] [blame]
[email protected]ddfb1642012-10-09 00:56:57 +00001// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
[email protected]cefd1f22012-12-20 02:04:28 +00005/// Helper functionality for invoking Git.
[email protected]05c9cc02012-10-09 01:25:43 +00006library git;
[email protected]ddfb1642012-10-09 00:56:57 +00007
[email protected]bd5f2592013-01-07 11:23:16 +00008import 'dart:async';
[email protected]05c9cc02012-10-09 01:25:43 +00009import 'io.dart';
[email protected]71976ef2012-12-08 02:57:00 +000010import 'log.dart' as log;
[email protected]05c9cc02012-10-09 01:25:43 +000011import 'utils.dart';
[email protected]ddfb1642012-10-09 00:56:57 +000012
13/// Tests whether or not the git command-line app is available for use.
14Future<bool> get isInstalled {
15 if (_isGitInstalledCache != null) {
[email protected]c6eca942013-01-24 01:13:36 +000016 return new Future.immediate(_isGitInstalledCache);
[email protected]ddfb1642012-10-09 00:56:57 +000017 }
18
[email protected]bd5f2592013-01-07 11:23:16 +000019 return _gitCommand.then((git) => git != null);
[email protected]ddfb1642012-10-09 00:56:57 +000020}
21
22/// Run a git process with [args] from [workingDir]. Returns the stdout as a
23/// list of strings if it succeeded. Completes to an exception if it failed.
[email protected]c6eca942013-01-24 01:13:36 +000024Future<List<String>> run(List<String> args,
25 {String workingDir, Map<String, String> environment}) {
[email protected]bd5f2592013-01-07 11:23:16 +000026 return _gitCommand.then((git) {
[email protected]c6eca942013-01-24 01:13:36 +000027 return runProcess(git, args, workingDir: workingDir,
28 environment: environment);
[email protected]bd5f2592013-01-07 11:23:16 +000029 }).then((result) {
[email protected]ddfb1642012-10-09 00:56:57 +000030 if (!result.success) throw new Exception(
[email protected]30a360f2012-10-09 20:54:05 +000031 'Git error. Command: git ${Strings.join(args, " ")}\n'
32 '${Strings.join(result.stderr, "\n")}');
[email protected]ddfb1642012-10-09 00:56:57 +000033
34 return result.stdout;
35 });
36}
37
38bool _isGitInstalledCache;
39
40/// The cached Git command.
41String _gitCommandCache;
42
43/// Returns the name of the git command-line app, or null if Git could not be
44/// found on the user's PATH.
45Future<String> get _gitCommand {
[email protected]ddfb1642012-10-09 00:56:57 +000046 if (_gitCommandCache != null) {
[email protected]c6eca942013-01-24 01:13:36 +000047 return new Future.immediate(_gitCommandCache);
[email protected]ddfb1642012-10-09 00:56:57 +000048 }
49
[email protected]bd5f2592013-01-07 11:23:16 +000050 return _tryGitCommand("git").then((success) {
[email protected]c6eca942013-01-24 01:13:36 +000051 if (success) return "git";
[email protected]ddfb1642012-10-09 00:56:57 +000052
53 // Git is sometimes installed on Windows as `git.cmd`
[email protected]bd5f2592013-01-07 11:23:16 +000054 return _tryGitCommand("git.cmd").then((success) {
[email protected]ddfb1642012-10-09 00:56:57 +000055 if (success) return "git.cmd";
56 return null;
57 });
[email protected]bd5f2592013-01-07 11:23:16 +000058 }).then((command) {
[email protected]71976ef2012-12-08 02:57:00 +000059 log.fine('Determined git command $command.');
[email protected]ddfb1642012-10-09 00:56:57 +000060 _gitCommandCache = command;
61 return command;
62 });
63}
64
65/// Checks whether [command] is the Git command for this computer.
66Future<bool> _tryGitCommand(String command) {
[email protected]ddfb1642012-10-09 00:56:57 +000067 // If "git --version" prints something familiar, git is working.
[email protected]fc7fe362013-01-09 21:37:40 +000068 return runProcess(command, ["--version"]).then((results) {
69 var regexp = new RegExp("^git version");
70 return results.stdout.length == 1 && regexp.hasMatch(results.stdout[0]);
71 }).catchError((err) {
72 // If the process failed, they probably don't have it.
73 return false;
74 });
[email protected]cefd1f22012-12-20 02:04:28 +000075}