dugite 1.104.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 GitHub and contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Dugite - JS bindings for Git
2
+
3
+ This project provides bindings for Node applications to interact with Git repositories, using the same command line interface that core Git offers. Development is primarily driven by Git-related projects at GitHub such as [GitHub Desktop](https://github.com/desktop/desktop).
4
+
5
+ The source is in TypeScript, but can be consumed by any JavaScript application.
6
+
7
+ ### Getting Started
8
+
9
+ Add it to your project:
10
+
11
+ ```
12
+ > npm install dugite
13
+ ```
14
+
15
+ Then reference it in your application:
16
+
17
+ ```js
18
+ import { GitProcess, GitError, IGitResult } from 'dugite'
19
+
20
+ const pathToRepository = 'C:/path/to/git/repository/'
21
+
22
+ const result = await GitProcess.exec([ 'status' ], pathToRepository)
23
+ if (result.exitCode === 0) {
24
+ const output = result.stdout
25
+ // do some things with the output
26
+ } else {
27
+ const error = result.stderr
28
+ // error handling
29
+ }
30
+ ```
31
+
32
+ ### Features
33
+
34
+ - make it easy to work with Git repositories
35
+ - use the same commands as you would in a shell
36
+ - access to the full set of commands, options and formatting that Git core uses
37
+ - access to the latest features of Git
38
+
39
+ ### Supported Platforms
40
+
41
+ - Windows 7 and later
42
+ - macOS 10.9 and up
43
+ - Linux (tested on Ubuntu Precise/Trusty and Fedora 24)
44
+
45
+ ### Status
46
+
47
+ This project is under active development for Git-related projects at GitHub. This will stabilize as this library gets more usage in production, and is open to external contributions that align with the project's goals.
48
+
49
+ If you are interested in getting involved with this project, refer to the [CONTRIBUTING.md](./CONTRIBUTING.md) file for instructions and the [documentation](./docs/) sections for more information about the project.
50
+
51
+ ### Roadmap
52
+
53
+ As this is under active development, the roadmap is also subject to change. Some ideas:
54
+
55
+ - authentication support in-the-box
56
+ - make environment setup easier to override
57
+ - API additions for common tasks such as parsing output
58
+ - error handling improvements
@@ -0,0 +1,70 @@
1
+ /** The git errors which can be parsed from failed git commands. */
2
+ export declare enum GitError {
3
+ SSHKeyAuditUnverified = 0,
4
+ SSHAuthenticationFailed = 1,
5
+ SSHPermissionDenied = 2,
6
+ HTTPSAuthenticationFailed = 3,
7
+ RemoteDisconnection = 4,
8
+ HostDown = 5,
9
+ RebaseConflicts = 6,
10
+ MergeConflicts = 7,
11
+ HTTPSRepositoryNotFound = 8,
12
+ SSHRepositoryNotFound = 9,
13
+ PushNotFastForward = 10,
14
+ BranchDeletionFailed = 11,
15
+ DefaultBranchDeletionFailed = 12,
16
+ RevertConflicts = 13,
17
+ EmptyRebasePatch = 14,
18
+ NoMatchingRemoteBranch = 15,
19
+ NoExistingRemoteBranch = 16,
20
+ NothingToCommit = 17,
21
+ NoSubmoduleMapping = 18,
22
+ SubmoduleRepositoryDoesNotExist = 19,
23
+ InvalidSubmoduleSHA = 20,
24
+ LocalPermissionDenied = 21,
25
+ InvalidMerge = 22,
26
+ InvalidRebase = 23,
27
+ NonFastForwardMergeIntoEmptyHead = 24,
28
+ PatchDoesNotApply = 25,
29
+ BranchAlreadyExists = 26,
30
+ BadRevision = 27,
31
+ NotAGitRepository = 28,
32
+ CannotMergeUnrelatedHistories = 29,
33
+ LFSAttributeDoesNotMatch = 30,
34
+ BranchRenameFailed = 31,
35
+ PathDoesNotExist = 32,
36
+ InvalidObjectName = 33,
37
+ OutsideRepository = 34,
38
+ LockFileAlreadyExists = 35,
39
+ NoMergeToAbort = 36,
40
+ LocalChangesOverwritten = 37,
41
+ UnresolvedConflicts = 38,
42
+ GPGFailedToSignData = 39,
43
+ ConflictModifyDeletedInBranch = 40,
44
+ PushWithFileSizeExceedingLimit = 41,
45
+ HexBranchNameRejected = 42,
46
+ ForcePushRejected = 43,
47
+ InvalidRefLength = 44,
48
+ ProtectedBranchRequiresReview = 45,
49
+ ProtectedBranchForcePush = 46,
50
+ ProtectedBranchDeleteRejected = 47,
51
+ ProtectedBranchRequiredStatus = 48,
52
+ PushWithPrivateEmail = 49,
53
+ ConfigLockFileAlreadyExists = 50,
54
+ RemoteAlreadyExists = 51,
55
+ TagAlreadyExists = 52,
56
+ MergeWithLocalChanges = 53,
57
+ RebaseWithLocalChanges = 54,
58
+ MergeCommitNoMainlineOption = 55
59
+ }
60
+ /** A mapping from regexes to the git error they identify. */
61
+ export declare const GitErrorRegexes: {
62
+ [regexp: string]: GitError;
63
+ };
64
+ /**
65
+ * The error code for when git cannot be found. This most likely indicates a
66
+ * problem with dugite itself.
67
+ */
68
+ export declare const GitNotFoundErrorCode = "git-not-found-error";
69
+ /** The error code for when the path to a repository doesn't exist. */
70
+ export declare const RepositoryDoesNotExistErrorCode = "repository-does-not-exist-error";
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /** The git errors which can be parsed from failed git commands. */
4
+ var GitError;
5
+ (function (GitError) {
6
+ GitError[GitError["SSHKeyAuditUnverified"] = 0] = "SSHKeyAuditUnverified";
7
+ GitError[GitError["SSHAuthenticationFailed"] = 1] = "SSHAuthenticationFailed";
8
+ GitError[GitError["SSHPermissionDenied"] = 2] = "SSHPermissionDenied";
9
+ GitError[GitError["HTTPSAuthenticationFailed"] = 3] = "HTTPSAuthenticationFailed";
10
+ GitError[GitError["RemoteDisconnection"] = 4] = "RemoteDisconnection";
11
+ GitError[GitError["HostDown"] = 5] = "HostDown";
12
+ GitError[GitError["RebaseConflicts"] = 6] = "RebaseConflicts";
13
+ GitError[GitError["MergeConflicts"] = 7] = "MergeConflicts";
14
+ GitError[GitError["HTTPSRepositoryNotFound"] = 8] = "HTTPSRepositoryNotFound";
15
+ GitError[GitError["SSHRepositoryNotFound"] = 9] = "SSHRepositoryNotFound";
16
+ GitError[GitError["PushNotFastForward"] = 10] = "PushNotFastForward";
17
+ GitError[GitError["BranchDeletionFailed"] = 11] = "BranchDeletionFailed";
18
+ GitError[GitError["DefaultBranchDeletionFailed"] = 12] = "DefaultBranchDeletionFailed";
19
+ GitError[GitError["RevertConflicts"] = 13] = "RevertConflicts";
20
+ GitError[GitError["EmptyRebasePatch"] = 14] = "EmptyRebasePatch";
21
+ GitError[GitError["NoMatchingRemoteBranch"] = 15] = "NoMatchingRemoteBranch";
22
+ GitError[GitError["NoExistingRemoteBranch"] = 16] = "NoExistingRemoteBranch";
23
+ GitError[GitError["NothingToCommit"] = 17] = "NothingToCommit";
24
+ GitError[GitError["NoSubmoduleMapping"] = 18] = "NoSubmoduleMapping";
25
+ GitError[GitError["SubmoduleRepositoryDoesNotExist"] = 19] = "SubmoduleRepositoryDoesNotExist";
26
+ GitError[GitError["InvalidSubmoduleSHA"] = 20] = "InvalidSubmoduleSHA";
27
+ GitError[GitError["LocalPermissionDenied"] = 21] = "LocalPermissionDenied";
28
+ GitError[GitError["InvalidMerge"] = 22] = "InvalidMerge";
29
+ GitError[GitError["InvalidRebase"] = 23] = "InvalidRebase";
30
+ GitError[GitError["NonFastForwardMergeIntoEmptyHead"] = 24] = "NonFastForwardMergeIntoEmptyHead";
31
+ GitError[GitError["PatchDoesNotApply"] = 25] = "PatchDoesNotApply";
32
+ GitError[GitError["BranchAlreadyExists"] = 26] = "BranchAlreadyExists";
33
+ GitError[GitError["BadRevision"] = 27] = "BadRevision";
34
+ GitError[GitError["NotAGitRepository"] = 28] = "NotAGitRepository";
35
+ GitError[GitError["CannotMergeUnrelatedHistories"] = 29] = "CannotMergeUnrelatedHistories";
36
+ GitError[GitError["LFSAttributeDoesNotMatch"] = 30] = "LFSAttributeDoesNotMatch";
37
+ GitError[GitError["BranchRenameFailed"] = 31] = "BranchRenameFailed";
38
+ GitError[GitError["PathDoesNotExist"] = 32] = "PathDoesNotExist";
39
+ GitError[GitError["InvalidObjectName"] = 33] = "InvalidObjectName";
40
+ GitError[GitError["OutsideRepository"] = 34] = "OutsideRepository";
41
+ GitError[GitError["LockFileAlreadyExists"] = 35] = "LockFileAlreadyExists";
42
+ GitError[GitError["NoMergeToAbort"] = 36] = "NoMergeToAbort";
43
+ GitError[GitError["LocalChangesOverwritten"] = 37] = "LocalChangesOverwritten";
44
+ GitError[GitError["UnresolvedConflicts"] = 38] = "UnresolvedConflicts";
45
+ GitError[GitError["GPGFailedToSignData"] = 39] = "GPGFailedToSignData";
46
+ GitError[GitError["ConflictModifyDeletedInBranch"] = 40] = "ConflictModifyDeletedInBranch";
47
+ // Start of GitHub-specific error codes
48
+ GitError[GitError["PushWithFileSizeExceedingLimit"] = 41] = "PushWithFileSizeExceedingLimit";
49
+ GitError[GitError["HexBranchNameRejected"] = 42] = "HexBranchNameRejected";
50
+ GitError[GitError["ForcePushRejected"] = 43] = "ForcePushRejected";
51
+ GitError[GitError["InvalidRefLength"] = 44] = "InvalidRefLength";
52
+ GitError[GitError["ProtectedBranchRequiresReview"] = 45] = "ProtectedBranchRequiresReview";
53
+ GitError[GitError["ProtectedBranchForcePush"] = 46] = "ProtectedBranchForcePush";
54
+ GitError[GitError["ProtectedBranchDeleteRejected"] = 47] = "ProtectedBranchDeleteRejected";
55
+ GitError[GitError["ProtectedBranchRequiredStatus"] = 48] = "ProtectedBranchRequiredStatus";
56
+ GitError[GitError["PushWithPrivateEmail"] = 49] = "PushWithPrivateEmail";
57
+ // End of GitHub-specific error codes
58
+ GitError[GitError["ConfigLockFileAlreadyExists"] = 50] = "ConfigLockFileAlreadyExists";
59
+ GitError[GitError["RemoteAlreadyExists"] = 51] = "RemoteAlreadyExists";
60
+ GitError[GitError["TagAlreadyExists"] = 52] = "TagAlreadyExists";
61
+ GitError[GitError["MergeWithLocalChanges"] = 53] = "MergeWithLocalChanges";
62
+ GitError[GitError["RebaseWithLocalChanges"] = 54] = "RebaseWithLocalChanges";
63
+ GitError[GitError["MergeCommitNoMainlineOption"] = 55] = "MergeCommitNoMainlineOption";
64
+ })(GitError = exports.GitError || (exports.GitError = {}));
65
+ /** A mapping from regexes to the git error they identify. */
66
+ exports.GitErrorRegexes = {
67
+ 'ERROR: ([\\s\\S]+?)\\n+\\[EPOLICYKEYAGE\\]\\n+fatal: Could not read from remote repository.': GitError.SSHKeyAuditUnverified,
68
+ "fatal: Authentication failed for 'https://": GitError.HTTPSAuthenticationFailed,
69
+ 'fatal: Authentication failed': GitError.SSHAuthenticationFailed,
70
+ 'fatal: Could not read from remote repository.': GitError.SSHPermissionDenied,
71
+ 'The requested URL returned error: 403': GitError.HTTPSAuthenticationFailed,
72
+ 'fatal: The remote end hung up unexpectedly': GitError.RemoteDisconnection,
73
+ "fatal: unable to access '(.+)': Failed to connect to (.+): Host is down": GitError.HostDown,
74
+ "Cloning into '(.+)'...\nfatal: unable to access '(.+)': Could not resolve host: (.+)": GitError.HostDown,
75
+ 'Resolve all conflicts manually, mark them as resolved with': GitError.RebaseConflicts,
76
+ '(Merge conflict|Automatic merge failed; fix conflicts and then commit the result)': GitError.MergeConflicts,
77
+ "fatal: repository '(.+)' not found": GitError.HTTPSRepositoryNotFound,
78
+ 'ERROR: Repository not found': GitError.SSHRepositoryNotFound,
79
+ "\\((non-fast-forward|fetch first)\\)\nerror: failed to push some refs to '.*'": GitError.PushNotFastForward,
80
+ "error: unable to delete '(.+)': remote ref does not exist": GitError.BranchDeletionFailed,
81
+ '\\[remote rejected\\] (.+) \\(deletion of the current branch prohibited\\)': GitError.DefaultBranchDeletionFailed,
82
+ "error: could not revert .*\nhint: after resolving the conflicts, mark the corrected paths\nhint: with 'git add <paths>' or 'git rm <paths>'\nhint: and commit the result with 'git commit'": GitError.RevertConflicts,
83
+ "Applying: .*\nNo changes - did you forget to use 'git add'\\?\nIf there is nothing left to stage, chances are that something else\n.*": GitError.EmptyRebasePatch,
84
+ 'There are no candidates for (rebasing|merging) among the refs that you just fetched.\nGenerally this means that you provided a wildcard refspec which had no\nmatches on the remote end.': GitError.NoMatchingRemoteBranch,
85
+ "Your configuration specifies to merge with the ref '(.+)'\nfrom the remote, but no such ref was fetched.": GitError.NoExistingRemoteBranch,
86
+ 'nothing to commit': GitError.NothingToCommit,
87
+ "No submodule mapping found in .gitmodules for path '(.+)'": GitError.NoSubmoduleMapping,
88
+ "fatal: repository '(.+)' does not exist\nfatal: clone of '.+' into submodule path '(.+)' failed": GitError.SubmoduleRepositoryDoesNotExist,
89
+ "Fetched in submodule path '(.+)', but it did not contain (.+). Direct fetching of that commit failed.": GitError.InvalidSubmoduleSHA,
90
+ "fatal: could not create work tree dir '(.+)'.*: Permission denied": GitError.LocalPermissionDenied,
91
+ 'merge: (.+) - not something we can merge': GitError.InvalidMerge,
92
+ 'invalid upstream (.+)': GitError.InvalidRebase,
93
+ 'fatal: Non-fast-forward commit does not make sense into an empty head': GitError.NonFastForwardMergeIntoEmptyHead,
94
+ 'error: (.+): (patch does not apply|already exists in working directory)': GitError.PatchDoesNotApply,
95
+ "fatal: A branch named '(.+)' already exists.": GitError.BranchAlreadyExists,
96
+ "fatal: bad revision '(.*)'": GitError.BadRevision,
97
+ 'fatal: [Nn]ot a git repository \\(or any of the parent directories\\): (.*)': GitError.NotAGitRepository,
98
+ 'fatal: refusing to merge unrelated histories': GitError.CannotMergeUnrelatedHistories,
99
+ 'The .+ attribute should be .+ but is .+': GitError.LFSAttributeDoesNotMatch,
100
+ 'fatal: Branch rename failed': GitError.BranchRenameFailed,
101
+ "fatal: path '(.+)' does not exist .+": GitError.PathDoesNotExist,
102
+ "fatal: invalid object name '(.+)'.": GitError.InvalidObjectName,
103
+ "fatal: .+: '(.+)' is outside repository": GitError.OutsideRepository,
104
+ 'Another git process seems to be running in this repository, e.g.': GitError.LockFileAlreadyExists,
105
+ 'fatal: There is no merge to abort': GitError.NoMergeToAbort,
106
+ 'error: (?:Your local changes to the following|The following untracked working tree) files would be overwritten by checkout:': GitError.LocalChangesOverwritten,
107
+ 'You must edit all merge conflicts and then\nmark them as resolved using git add|fatal: Exiting because of an unresolved conflict': GitError.UnresolvedConflicts,
108
+ 'error: gpg failed to sign the data': GitError.GPGFailedToSignData,
109
+ 'CONFLICT \\(modify/delete\\): (.+) deleted in (.+) and modified in (.+)': GitError.ConflictModifyDeletedInBranch,
110
+ // GitHub-specific errors
111
+ 'error: GH001: ': GitError.PushWithFileSizeExceedingLimit,
112
+ 'error: GH002: ': GitError.HexBranchNameRejected,
113
+ 'error: GH003: Sorry, force-pushing to (.+) is not allowed.': GitError.ForcePushRejected,
114
+ 'error: GH005: Sorry, refs longer than (.+) bytes are not allowed': GitError.InvalidRefLength,
115
+ 'error: GH006: Protected branch update failed for (.+)\nremote: error: At least one approved review is required': GitError.ProtectedBranchRequiresReview,
116
+ 'error: GH006: Protected branch update failed for (.+)\nremote: error: Cannot force-push to a protected branch': GitError.ProtectedBranchForcePush,
117
+ 'error: GH006: Protected branch update failed for (.+)\nremote: error: Cannot delete a protected branch': GitError.ProtectedBranchDeleteRejected,
118
+ 'error: GH006: Protected branch update failed for (.+).\nremote: error: Required status check "(.+)" is expected': GitError.ProtectedBranchRequiredStatus,
119
+ 'error: GH007: Your push would publish a private email address.': GitError.PushWithPrivateEmail,
120
+ 'error: could not lock config file (.+): File exists': GitError.ConfigLockFileAlreadyExists,
121
+ 'error: remote (.+) already exists.': GitError.RemoteAlreadyExists,
122
+ "fatal: tag '(.+)' already exists": GitError.TagAlreadyExists,
123
+ 'error: Your local changes to the following files would be overwritten by merge:\n': GitError.MergeWithLocalChanges,
124
+ 'error: cannot (pull with rebase|rebase): You have unstaged changes\\.\n\\s*error: [Pp]lease commit or stash them\\.': GitError.RebaseWithLocalChanges,
125
+ 'error: commit (.+) is a merge but no -m option was given': GitError.MergeCommitNoMainlineOption
126
+ };
127
+ /**
128
+ * The error code for when git cannot be found. This most likely indicates a
129
+ * problem with dugite itself.
130
+ */
131
+ exports.GitNotFoundErrorCode = 'git-not-found-error';
132
+ /** The error code for when the path to a repository doesn't exist. */
133
+ exports.RepositoryDoesNotExistErrorCode = 'repository-does-not-exist-error';
134
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../lib/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * Setup the process environment before invoking Git.
4
+ *
5
+ * This method resolves the Git executable and creates the array of key-value
6
+ * pairs which should be used as environment variables.
7
+ *
8
+ * @param additional options to include with the process
9
+ */
10
+ export declare function setupEnvironment(environmentVariables: NodeJS.ProcessEnv): {
11
+ env: NodeJS.ProcessEnv;
12
+ gitLocation: string;
13
+ };
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path = require("path");
4
+ function resolveEmbeddedGitDir() {
5
+ if (process.platform === 'darwin' ||
6
+ process.platform === 'linux' ||
7
+ process.platform === 'android' ||
8
+ process.platform === 'win32') {
9
+ const s = path.sep;
10
+ return path
11
+ .resolve(__dirname, '..', '..', 'git')
12
+ .replace(/[\\\/]app.asar[\\\/]/, `${s}app.asar.unpacked${s}`);
13
+ }
14
+ throw new Error('Git not supported on platform: ' + process.platform);
15
+ }
16
+ /**
17
+ * Find the path to the embedded Git environment.
18
+ *
19
+ * If a custom Git directory path is defined as the `LOCAL_GIT_DIRECTORY` environment variable, then
20
+ * returns with it after resolving it as a path.
21
+ */
22
+ function resolveGitDir() {
23
+ if (process.env.LOCAL_GIT_DIRECTORY != null) {
24
+ return path.resolve(process.env.LOCAL_GIT_DIRECTORY);
25
+ }
26
+ else {
27
+ return resolveEmbeddedGitDir();
28
+ }
29
+ }
30
+ /**
31
+ * Find the path to the embedded Git binary.
32
+ */
33
+ function resolveGitBinary() {
34
+ const gitDir = resolveGitDir();
35
+ if (process.platform === 'win32') {
36
+ return path.join(gitDir, 'cmd', 'git.exe');
37
+ }
38
+ else {
39
+ return path.join(gitDir, 'bin', 'git');
40
+ }
41
+ }
42
+ /**
43
+ * Find the path to the embedded git exec path.
44
+ *
45
+ * If a custom git exec path is given as the `GIT_EXEC_PATH` environment variable,
46
+ * then it returns with it after resolving it as a path.
47
+ */
48
+ function resolveGitExecPath() {
49
+ if (process.env.GIT_EXEC_PATH != null) {
50
+ return path.resolve(process.env.GIT_EXEC_PATH);
51
+ }
52
+ const gitDir = resolveGitDir();
53
+ if (process.platform === 'win32') {
54
+ if (process.arch === 'x64') {
55
+ return path.join(gitDir, 'mingw64', 'libexec', 'git-core');
56
+ }
57
+ return path.join(gitDir, 'mingw32', 'libexec', 'git-core');
58
+ }
59
+ else {
60
+ return path.join(gitDir, 'libexec', 'git-core');
61
+ }
62
+ }
63
+ /**
64
+ * Setup the process environment before invoking Git.
65
+ *
66
+ * This method resolves the Git executable and creates the array of key-value
67
+ * pairs which should be used as environment variables.
68
+ *
69
+ * @param additional options to include with the process
70
+ */
71
+ function setupEnvironment(environmentVariables) {
72
+ const gitLocation = resolveGitBinary();
73
+ let envPath = process.env.PATH || '';
74
+ const gitDir = resolveGitDir();
75
+ if (process.platform === 'win32') {
76
+ if (process.arch === 'x64') {
77
+ envPath = `${gitDir}\\mingw64\\bin;${gitDir}\\mingw64\\usr\\bin;${envPath}`;
78
+ }
79
+ else {
80
+ envPath = `${gitDir}\\mingw32\\bin;${gitDir}\\mingw32\\usr\\bin;${envPath}`;
81
+ }
82
+ }
83
+ const env = Object.assign({}, process.env, {
84
+ GIT_EXEC_PATH: resolveGitExecPath(),
85
+ PATH: envPath
86
+ }, environmentVariables);
87
+ if (process.platform === 'win32') {
88
+ // while reading the environment variable is case-insensitive
89
+ // you can create a hash with multiple values, which means the
90
+ // wrong value might be used when spawning the child process
91
+ //
92
+ // this ensures we only ever supply one value for PATH
93
+ if (env.Path) {
94
+ delete env.Path;
95
+ }
96
+ }
97
+ if (process.platform === 'darwin' || process.platform === 'linux') {
98
+ // templates are used to populate your .git folder
99
+ // when a repository is initialized locally
100
+ const templateDir = `${gitDir}/share/git-core/templates`;
101
+ env.GIT_TEMPLATE_DIR = templateDir;
102
+ }
103
+ if (process.platform === 'linux') {
104
+ // when building Git for Linux and then running it from
105
+ // an arbitrary location, you should set PREFIX for the
106
+ // process to ensure that it knows how to resolve things
107
+ env.PREFIX = gitDir;
108
+ if (!env.GIT_SSL_CAINFO && !env.LOCAL_GIT_DIRECTORY) {
109
+ // use the SSL certificate bundle included in the distribution only
110
+ // when using embedded Git and not providing your own bundle
111
+ const distDir = resolveEmbeddedGitDir();
112
+ const sslCABundle = `${distDir}/ssl/cacert.pem`;
113
+ env.GIT_SSL_CAINFO = sslCABundle;
114
+ }
115
+ }
116
+ return { env, gitLocation };
117
+ }
118
+ exports.setupEnvironment = setupEnvironment;
119
+ //# sourceMappingURL=git-environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-environment.js","sourceRoot":"","sources":["../../lib/git-environment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ /// <reference types="node" />
2
+ import { GitError } from './errors';
3
+ import { ChildProcess } from 'child_process';
4
+ /** The result of shelling out to git. */
5
+ export interface IGitResult {
6
+ /** The standard output from git. */
7
+ readonly stdout: string;
8
+ /** The standard error output from git. */
9
+ readonly stderr: string;
10
+ /** The exit code of the git process. */
11
+ readonly exitCode: number;
12
+ }
13
+ /**
14
+ * A set of configuration options that can be passed when
15
+ * executing a streaming Git command.
16
+ */
17
+ export interface IGitSpawnExecutionOptions {
18
+ /**
19
+ * An optional collection of key-value pairs which will be
20
+ * set as environment variables before executing the git
21
+ * process.
22
+ */
23
+ readonly env?: Object;
24
+ }
25
+ /**
26
+ * A set of configuration options that can be passed when
27
+ * executing a git command.
28
+ */
29
+ export interface IGitExecutionOptions {
30
+ /**
31
+ * An optional collection of key-value pairs which will be
32
+ * set as environment variables before executing the git
33
+ * process.
34
+ */
35
+ readonly env?: Object;
36
+ /**
37
+ * An optional string or buffer which will be written to
38
+ * the child process stdin stream immediately immediately
39
+ * after spawning the process.
40
+ */
41
+ readonly stdin?: string | Buffer;
42
+ /**
43
+ * The encoding to use when writing to stdin, if the stdin
44
+ * parameter is a string.
45
+ */
46
+ readonly stdinEncoding?: string;
47
+ /**
48
+ * The size the output buffer to allocate to the spawned process. Set this
49
+ * if you are anticipating a large amount of output.
50
+ *
51
+ * If not specified, this will be 10MB (10485760 bytes) which should be
52
+ * enough for most Git operations.
53
+ */
54
+ readonly maxBuffer?: number;
55
+ /**
56
+ * An optional callback which will be invoked with the child
57
+ * process instance after spawning the git process.
58
+ *
59
+ * Note that if the stdin parameter was specified the stdin
60
+ * stream will be closed by the time this callback fires.
61
+ */
62
+ readonly processCallback?: (process: ChildProcess) => void;
63
+ }
64
+ export declare class GitProcess {
65
+ private static pathExists;
66
+ /**
67
+ * Execute a command and interact with the process outputs directly.
68
+ *
69
+ * The returned promise will reject when the git executable fails to launch,
70
+ * in which case the thrown Error will have a string `code` property. See
71
+ * `errors.ts` for some of the known error codes.
72
+ */
73
+ static spawn(args: string[], path: string, options?: IGitSpawnExecutionOptions): ChildProcess;
74
+ /**
75
+ * Execute a command and read the output using the embedded Git environment.
76
+ *
77
+ * The returned promise will reject when the git executable fails to launch,
78
+ * in which case the thrown Error will have a string `code` property. See
79
+ * `errors.ts` for some of the known error codes.
80
+ *
81
+ * See the result's `stderr` and `exitCode` for any potential git error
82
+ * information.
83
+ */
84
+ static exec(args: string[], path: string, options?: IGitExecutionOptions): Promise<IGitResult>;
85
+ /**
86
+ * Execute a command and read the output using the embedded Git environment.
87
+ *
88
+ * The returned GitTask will will contain `result`, `setPid`, `cancel`
89
+ * `result` will be a promise, which will reject when the git
90
+ * executable fails to launch, in which case the thrown Error will
91
+ * have a string `code` property. See `errors.ts` for some of the
92
+ * known error codes.
93
+ * See the result's `stderr` and `exitCode` for any potential git error
94
+ * information.
95
+ *
96
+ * As for, `setPid(pid)`, this is to set the PID
97
+ *
98
+ * And `cancel()` will try to cancel the git process
99
+ */
100
+ static execTask(args: string[], path: string, options?: IGitExecutionOptions): IGitTask;
101
+ /** Try to parse an error type from stderr. */
102
+ static parseError(stderr: string): GitError | null;
103
+ }
104
+ export declare enum GitTaskCancelResult {
105
+ successfulCancel = 0,
106
+ processAlreadyEnded = 1,
107
+ noProcessIdDefined = 2,
108
+ failedToCancel = 3
109
+ }
110
+ /** This interface represents a git task (process). */
111
+ export interface IGitTask {
112
+ /** Result of the git process. */
113
+ readonly result: Promise<IGitResult>;
114
+ /** Allows to cancel the process if it's running. Returns true if the process was killed. */
115
+ readonly cancel: () => Promise<GitTaskCancelResult>;
116
+ }
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ const fs = require("fs");
12
+ const process_1 = require("process");
13
+ const child_process_1 = require("child_process");
14
+ const errors_1 = require("./errors");
15
+ const git_environment_1 = require("./git-environment");
16
+ class GitProcess {
17
+ static pathExists(path) {
18
+ try {
19
+ fs.accessSync(path, fs.F_OK);
20
+ return true;
21
+ }
22
+ catch (_a) {
23
+ return false;
24
+ }
25
+ }
26
+ /**
27
+ * Execute a command and interact with the process outputs directly.
28
+ *
29
+ * The returned promise will reject when the git executable fails to launch,
30
+ * in which case the thrown Error will have a string `code` property. See
31
+ * `errors.ts` for some of the known error codes.
32
+ */
33
+ static spawn(args, path, options) {
34
+ let customEnv = {};
35
+ if (options && options.env) {
36
+ customEnv = options.env;
37
+ }
38
+ const { env, gitLocation } = git_environment_1.setupEnvironment(customEnv);
39
+ const spawnArgs = {
40
+ env,
41
+ cwd: path
42
+ };
43
+ const spawnedProcess = child_process_1.spawn(gitLocation, args, spawnArgs);
44
+ ignoreClosedInputStream(spawnedProcess);
45
+ return spawnedProcess;
46
+ }
47
+ /**
48
+ * Execute a command and read the output using the embedded Git environment.
49
+ *
50
+ * The returned promise will reject when the git executable fails to launch,
51
+ * in which case the thrown Error will have a string `code` property. See
52
+ * `errors.ts` for some of the known error codes.
53
+ *
54
+ * See the result's `stderr` and `exitCode` for any potential git error
55
+ * information.
56
+ */
57
+ static exec(args, path, options) {
58
+ return this.execTask(args, path, options).result;
59
+ }
60
+ /**
61
+ * Execute a command and read the output using the embedded Git environment.
62
+ *
63
+ * The returned GitTask will will contain `result`, `setPid`, `cancel`
64
+ * `result` will be a promise, which will reject when the git
65
+ * executable fails to launch, in which case the thrown Error will
66
+ * have a string `code` property. See `errors.ts` for some of the
67
+ * known error codes.
68
+ * See the result's `stderr` and `exitCode` for any potential git error
69
+ * information.
70
+ *
71
+ * As for, `setPid(pid)`, this is to set the PID
72
+ *
73
+ * And `cancel()` will try to cancel the git process
74
+ */
75
+ static execTask(args, path, options) {
76
+ let pidResolve;
77
+ const pidPromise = new Promise(function (resolve) {
78
+ pidResolve = resolve;
79
+ });
80
+ let result = new GitTask(new Promise(function (resolve, reject) {
81
+ let customEnv = {};
82
+ if (options && options.env) {
83
+ customEnv = options.env;
84
+ }
85
+ const { env, gitLocation } = git_environment_1.setupEnvironment(customEnv);
86
+ // Explicitly annotate opts since typescript is unable to infer the correct
87
+ // signature for execFile when options is passed as an opaque hash. The type
88
+ // definition for execFile currently infers based on the encoding parameter
89
+ // which could change between declaration time and being passed to execFile.
90
+ // See https://git.io/vixyQ
91
+ const execOptions = {
92
+ cwd: path,
93
+ encoding: 'utf8',
94
+ maxBuffer: options ? options.maxBuffer : 10 * 1024 * 1024,
95
+ env
96
+ };
97
+ const spawnedProcess = child_process_1.execFile(gitLocation, args, execOptions, function (err, stdout, stderr) {
98
+ result.updateProcessEnded();
99
+ if (!err) {
100
+ resolve({ stdout, stderr, exitCode: 0 });
101
+ return;
102
+ }
103
+ const errWithCode = err;
104
+ let code = errWithCode.code;
105
+ // If the error's code is a string then it means the code isn't the
106
+ // process's exit code but rather an error coming from Node's bowels,
107
+ // e.g., ENOENT.
108
+ if (typeof code === 'string') {
109
+ if (code === 'ENOENT') {
110
+ let message = err.message;
111
+ if (GitProcess.pathExists(path) === false) {
112
+ message = 'Unable to find path to repository on disk.';
113
+ code = errors_1.RepositoryDoesNotExistErrorCode;
114
+ }
115
+ else {
116
+ message = `Git could not be found at the expected path: '${gitLocation}'. This might be a problem with how the application is packaged, so confirm this folder hasn't been removed when packaging.`;
117
+ code = errors_1.GitNotFoundErrorCode;
118
+ }
119
+ const error = new Error(message);
120
+ error.name = err.name;
121
+ error.code = code;
122
+ reject(error);
123
+ }
124
+ else {
125
+ reject(err);
126
+ }
127
+ return;
128
+ }
129
+ if (typeof code === 'number') {
130
+ resolve({ stdout, stderr, exitCode: code });
131
+ return;
132
+ }
133
+ // Git has returned an output that couldn't fit in the specified buffer
134
+ // as we don't know how many bytes it requires, rethrow the error with
135
+ // details about what it was previously set to...
136
+ if (err.message === 'stdout maxBuffer exceeded') {
137
+ reject(new Error(`The output from the command could not fit into the allocated stdout buffer. Set options.maxBuffer to a larger value than ${execOptions.maxBuffer} bytes`));
138
+ }
139
+ else {
140
+ reject(err);
141
+ }
142
+ });
143
+ pidResolve(spawnedProcess.pid);
144
+ ignoreClosedInputStream(spawnedProcess);
145
+ if (options && options.stdin !== undefined) {
146
+ // See https://github.com/nodejs/node/blob/7b5ffa46fe4d2868c1662694da06eb55ec744bde/test/parallel/test-stdin-pipe-large.js
147
+ spawnedProcess.stdin.end(options.stdin, options.stdinEncoding);
148
+ }
149
+ if (options && options.processCallback) {
150
+ options.processCallback(spawnedProcess);
151
+ }
152
+ }), pidPromise);
153
+ return result;
154
+ }
155
+ /** Try to parse an error type from stderr. */
156
+ static parseError(stderr) {
157
+ for (const [regex, error] of Object.entries(errors_1.GitErrorRegexes)) {
158
+ if (stderr.match(regex)) {
159
+ return error;
160
+ }
161
+ }
162
+ return null;
163
+ }
164
+ }
165
+ exports.GitProcess = GitProcess;
166
+ /**
167
+ * Prevent errors originating from the stdin stream related
168
+ * to the child process closing the pipe from bubbling up and
169
+ * causing an unhandled exception when no error handler is
170
+ * attached to the input stream.
171
+ *
172
+ * The common scenario where this happens is if the consumer
173
+ * is writing data to the stdin stream of a child process and
174
+ * the child process for one reason or another decides to either
175
+ * terminate or simply close its standard input. Imagine this
176
+ * scenario
177
+ *
178
+ * cat /dev/zero | head -c 1
179
+ *
180
+ * The 'head' command would close its standard input (by terminating)
181
+ * the moment it has read one byte. In the case of Git this could
182
+ * happen if you for example pass badly formed input to apply-patch.
183
+ *
184
+ * Since consumers of dugite using the `exec` api are unable to get
185
+ * a hold of the stream until after we've written data to it they're
186
+ * unable to fix it themselves so we'll just go ahead and ignore the
187
+ * error for them. By supressing the stream error we can pick up on
188
+ * the real error when the process exits when we parse the exit code
189
+ * and the standard error.
190
+ *
191
+ * See https://github.com/desktop/desktop/pull/4027#issuecomment-366213276
192
+ */
193
+ function ignoreClosedInputStream(process) {
194
+ // If Node fails to spawn due to a runtime error (EACCESS, EAGAIN, etc)
195
+ // it will not setup the stdio streams, see
196
+ // https://github.com/nodejs/node/blob/v10.16.0/lib/internal/child_process.js#L342-L354
197
+ // The error itself will be emitted asynchronously but we're still in
198
+ // the synchronous path so if we attempts to call `.on` on `.stdin`
199
+ // (which is undefined) that error would be thrown before the underlying
200
+ // error.
201
+ if (!process.stdin) {
202
+ return;
203
+ }
204
+ process.stdin.on('error', err => {
205
+ const code = err.code;
206
+ // Is the error one that we'd expect from the input stream being
207
+ // closed, i.e. EPIPE on macOS and EOF on Windows. We've also
208
+ // seen ECONNRESET failures on Linux hosts so let's throw that in
209
+ // there for good measure.
210
+ if (code === 'EPIPE' || code === 'EOF' || code === 'ECONNRESET') {
211
+ return;
212
+ }
213
+ // Nope, this is something else. Are there any other error listeners
214
+ // attached than us? If not we'll have to mimic the behavior of
215
+ // EventEmitter.
216
+ //
217
+ // See https://nodejs.org/api/errors.html#errors_error_propagation_and_interception
218
+ //
219
+ // "For all EventEmitter objects, if an 'error' event handler is not
220
+ // provided, the error will be thrown"
221
+ if (process.stdin.listeners('error').length <= 1) {
222
+ throw err;
223
+ }
224
+ });
225
+ }
226
+ var GitTaskCancelResult;
227
+ (function (GitTaskCancelResult) {
228
+ GitTaskCancelResult[GitTaskCancelResult["successfulCancel"] = 0] = "successfulCancel";
229
+ GitTaskCancelResult[GitTaskCancelResult["processAlreadyEnded"] = 1] = "processAlreadyEnded";
230
+ GitTaskCancelResult[GitTaskCancelResult["noProcessIdDefined"] = 2] = "noProcessIdDefined";
231
+ GitTaskCancelResult[GitTaskCancelResult["failedToCancel"] = 3] = "failedToCancel";
232
+ })(GitTaskCancelResult = exports.GitTaskCancelResult || (exports.GitTaskCancelResult = {}));
233
+ class GitTask {
234
+ constructor(result, pid) {
235
+ this.result = result;
236
+ this.pid = pid;
237
+ this.processEnded = false;
238
+ }
239
+ updateProcessEnded() {
240
+ this.processEnded = true;
241
+ }
242
+ cancel() {
243
+ return __awaiter(this, void 0, void 0, function* () {
244
+ if (this.processEnded) {
245
+ return GitTaskCancelResult.processAlreadyEnded;
246
+ }
247
+ const pid = yield this.pid;
248
+ if (pid === undefined) {
249
+ return GitTaskCancelResult.noProcessIdDefined;
250
+ }
251
+ try {
252
+ process_1.kill(pid);
253
+ return GitTaskCancelResult.successfulCancel;
254
+ }
255
+ catch (e) { }
256
+ return GitTaskCancelResult.failedToCancel;
257
+ });
258
+ }
259
+ }
260
+ //# sourceMappingURL=git-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-process.js","sourceRoot":"","sources":["../../lib/git-process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { GitProcess, IGitResult, IGitExecutionOptions, IGitTask, GitTaskCancelResult } from './git-process';
2
+ export { GitError, RepositoryDoesNotExistErrorCode, GitNotFoundErrorCode } from './errors';
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var git_process_1 = require("./git-process");
4
+ exports.GitProcess = git_process_1.GitProcess;
5
+ exports.GitTaskCancelResult = git_process_1.GitTaskCancelResult;
6
+ var errors_1 = require("./errors");
7
+ exports.GitError = errors_1.GitError;
8
+ exports.RepositoryDoesNotExistErrorCode = errors_1.RepositoryDoesNotExistErrorCode;
9
+ exports.GitNotFoundErrorCode = errors_1.GitNotFoundErrorCode;
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":";;AAAA,6CAMsB;AALpB,mCAAA,UAAU,CAAA;AAIV,4CAAA,mBAAmB,CAAA;AAErB,mCAA0F;AAAjF,4BAAA,QAAQ,CAAA;AAAE,mDAAA,+BAA+B,CAAA;AAAE,wCAAA,oBAAoB,CAAA"}
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ roots: ['<rootDir>/lib/', '<rootDir>/test/'],
3
+ testMatch: ['**/test/external/**/*-test.ts'],
4
+ setupFilesAfterEnv: ['<rootDir>/test/slow-setup.ts'],
5
+ collectCoverageFrom: ['lib/**/*.{js,ts}', '!**/node_modules/**', '!**/index.ts'],
6
+ coverageReporters: ['text-summary', 'json'],
7
+ globals: {
8
+ 'ts-jest': {
9
+ babelConfig: true
10
+ }
11
+ },
12
+ preset: 'ts-jest'
13
+ }
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ roots: ['<rootDir>/lib/', '<rootDir>/test/'],
3
+ testMatch: ['**/test/fast/**/*-test.ts'],
4
+ setupFilesAfterEnv: ['<rootDir>/test/fast-setup.ts'],
5
+ collectCoverageFrom: ['lib/**/*.{js,ts}', '!**/node_modules/**', '!**/index.ts'],
6
+ coverageReporters: ['text-summary', 'json'],
7
+ globals: {
8
+ 'ts-jest': {
9
+ babelConfig: true
10
+ }
11
+ },
12
+ preset: 'ts-jest'
13
+ }
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ roots: ['<rootDir>/lib/', '<rootDir>/test/'],
3
+ testMatch: ['**/test/slow/**/*-test.ts'],
4
+ setupFilesAfterEnv: ['<rootDir>/test/slow-setup.ts'],
5
+ collectCoverageFrom: ['lib/**/*.{js,ts}', '!**/node_modules/**', '!**/index.ts'],
6
+ coverageReporters: ['text-summary', 'json'],
7
+ globals: {
8
+ 'ts-jest': {
9
+ babelConfig: true
10
+ }
11
+ },
12
+ preset: 'ts-jest'
13
+ }
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "dugite",
3
+ "version": "1.104.0",
4
+ "description": "Elegant bindings for Git",
5
+ "main": "./build/lib/index.js",
6
+ "typings": "./build/lib/index.d.ts",
7
+ "scripts": {
8
+ "clean": "rimraf build",
9
+ "build": "npm run clean && tsc -p ./tsconfig.json && tsc -p ./examples/tsconfig.json",
10
+ "prepack": "npm run build && npm run test",
11
+ "postpublish": "git push --follow-tags",
12
+ "test": "npm run test:fast && npm run test:slow && npm run test:external",
13
+ "test:fast": "cross-env LOCAL_GIT_DIRECTORY=./git/ jest --runInBand --silent --config ./jest.fast.config.js",
14
+ "test:slow": "cross-env LOCAL_GIT_DIRECTORY=./git/ jest --runInBand --silent --config ./jest.slow.config.js",
15
+ "test:external": "jest --runInBand --silent --config ./jest.external.config.js",
16
+ "postinstall": "node ./script/download-git.js",
17
+ "prettify": "prettier \"{examples,lib,script,test}/**/*.ts\" --write",
18
+ "is-it-pretty": "prettier --check \"{examples,lib,script,test}/**/*.ts\"",
19
+ "update-embedded-git": "node ./script/update-embedded-git.js"
20
+ },
21
+ "engines": {
22
+ "node": ">= 6",
23
+ "npm": ">= 3"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/desktop/dugite.git"
28
+ },
29
+ "author": "GitHub and contributors",
30
+ "license": "MIT",
31
+ "bugs": {
32
+ "url": "https://github.com/desktop/dugite/issues"
33
+ },
34
+ "homepage": "https://github.com/desktop/dugite#readme",
35
+ "dependencies": {
36
+ "checksum": "^0.1.1",
37
+ "got": "^9.6.0",
38
+ "mkdirp": "^0.5.1",
39
+ "progress": "^2.0.3",
40
+ "rimraf": "^2.5.4",
41
+ "tar": "^4.4.7"
42
+ },
43
+ "devDependencies": {
44
+ "@types/checksum": "^0.1.30",
45
+ "@types/got": "^9.6.0",
46
+ "@types/jest": "^24.0.0",
47
+ "@types/mkdirp": "^0.5.2",
48
+ "@types/node": "^11.9.0",
49
+ "@types/progress": "^2.0.1",
50
+ "@types/rimraf": "2.0.2",
51
+ "byline": "^5.0.0",
52
+ "cross-env": "^5.2.0",
53
+ "find-git-exec": "0.0.1-alpha.2",
54
+ "jest": "^24.1.0",
55
+ "prettier": "^1.15.2",
56
+ "temp": "^0.9.0",
57
+ "ts-jest": "^24.0.0",
58
+ "typescript": "^3.1.6"
59
+ }
60
+ }
@@ -0,0 +1,70 @@
1
+ const URL = require('url')
2
+ const path = require('path')
3
+ const os = require('os')
4
+ const fs = require('fs')
5
+
6
+ const embeddedGit = require('./embedded-git.json')
7
+
8
+ function getConfig() {
9
+ const config = {
10
+ outputPath: path.join(__dirname, '..', 'git'),
11
+ source: '',
12
+ checksum: '',
13
+ fileName: '',
14
+ tempFile: ''
15
+ }
16
+
17
+ let arch = os.arch();
18
+
19
+ if (process.env.npm_config_arch) {
20
+ // If a specific npm_config_arch is set, we use that one instead of the OS arch (to support cross compilation)
21
+ console.log('npm_config_arch detected: ' + process.env.npm_config_arch);
22
+ arch = process.env.npm_config_arch;
23
+ }
24
+
25
+ if (process.platform === 'win32' && arch === 'arm64') {
26
+ // Use the Dugite Native ia32 package for Windows arm64 (arm64 can run 32-bit code through emulation)
27
+ console.log('Downloading 32-bit Dugite Native for Windows arm64');
28
+ arch = 'ia32';
29
+ }
30
+
31
+ // Os.arch() calls it x32, we use x86 in actions, dugite-native calls it x86 and our embedded-git.json calls it ia32
32
+ if (arch === 'x32' || arch === 'x86') {
33
+ arch = 'ia32'
34
+ }
35
+
36
+ const key = `${process.platform}-${arch}`
37
+
38
+ const entry = embeddedGit[key]
39
+
40
+ if (entry != null) {
41
+ config.checksum = entry.checksum
42
+ config.source = entry.url
43
+ } else {
44
+ console.log(`No embedded Git found for ${process.platform} and architecture ${arch}`)
45
+ }
46
+
47
+ if (config.source !== '') {
48
+ // compute the filename from the download source
49
+ const url = URL.parse(config.source)
50
+ const pathName = url.pathname
51
+ const index = pathName.lastIndexOf('/')
52
+ config.fileName = pathName.substr(index + 1)
53
+
54
+ const cacheDirEnv = process.env.DUGITE_CACHE_DIR
55
+
56
+ const cacheDir = cacheDirEnv ? path.resolve(cacheDirEnv) : os.tmpdir()
57
+
58
+ try {
59
+ fs.statSync(cacheDir)
60
+ } catch (e) {
61
+ fs.mkdirSync(cacheDir)
62
+ }
63
+
64
+ config.tempFile = path.join(cacheDir, config.fileName)
65
+ }
66
+
67
+ return config
68
+ }
69
+
70
+ module.exports = getConfig
@@ -0,0 +1,154 @@
1
+ const fs = require('fs')
2
+
3
+ const got = require('got')
4
+ const ProgressBar = require('progress')
5
+ const mkdirp = require('mkdirp')
6
+ const checksum = require('checksum')
7
+ const rimraf = require('rimraf')
8
+ const tar = require('tar')
9
+ const zlib = require('zlib')
10
+
11
+ const config = require('./config')()
12
+
13
+ function extract(source, callback) {
14
+ const extractor = tar
15
+ .extract({ cwd: config.outputPath })
16
+ .on('error', function(error) {
17
+ callback(error)
18
+ })
19
+ .on('end', function() {
20
+ callback()
21
+ })
22
+
23
+ fs.createReadStream(source)
24
+ .on('error', function(error) {
25
+ callback(error)
26
+ })
27
+ .pipe(zlib.Gunzip())
28
+ .pipe(extractor)
29
+ }
30
+
31
+ const verifyFile = function(file, callback) {
32
+ checksum.file(file, { algorithm: 'sha256' }, (_, hash) => {
33
+ const match = hash === config.checksum
34
+
35
+ if (!match) {
36
+ console.log(`Validation failed. Expected '${config.checksum}' but got '${hash}'`)
37
+ }
38
+
39
+ callback(match)
40
+ })
41
+ }
42
+
43
+ const unpackFile = function(file) {
44
+ extract(file, function(error) {
45
+ if (error) {
46
+ console.log('Unable to extract archive, aborting...', error)
47
+ process.exit(1)
48
+ }
49
+ })
50
+ }
51
+
52
+ const downloadAndUnpack = () => {
53
+ console.log(`Downloading Git from: ${config.source}`)
54
+
55
+ const options = {
56
+ headers: {
57
+ Accept: 'application/octet-stream',
58
+ 'User-Agent': 'dugite'
59
+ },
60
+ secureProtocol: 'TLSv1_2_method'
61
+ }
62
+
63
+ const client = got.stream(config.source, options)
64
+
65
+ client.pipe(fs.createWriteStream(config.tempFile))
66
+
67
+ client.on('error', function(error) {
68
+ if (error.code === 'ETIMEDOUT') {
69
+ console.log(
70
+ `A timeout has occurred while downloading '${config.source}' - check ` +
71
+ `your internet connection and try again. If you are using a proxy, ` +
72
+ `make sure that the HTTP_PROXY and HTTPS_PROXY environment variables are set.`,
73
+ error
74
+ )
75
+ } else {
76
+ console.log(`Error raised while downloading ${config.source}`, error)
77
+ }
78
+ process.exit(1)
79
+ })
80
+
81
+ client.on('response', function(res) {
82
+ if (res.statusCode !== 200) {
83
+ console.log(`Non-200 response returned from ${config.source} - (${res.statusCode})`)
84
+ process.exit(1)
85
+ }
86
+
87
+ const len = parseInt(res.headers['content-length'], 10)
88
+
89
+ console.log()
90
+ const bar = new ProgressBar('Downloading Git [:bar] :percent :etas', {
91
+ complete: '=',
92
+ incomplete: ' ',
93
+ width: 50,
94
+ total: len
95
+ })
96
+
97
+ res.on('data', function(chunk) {
98
+ bar.tick(chunk.length)
99
+ })
100
+
101
+ res.on('end', function() {
102
+ console.log('\n')
103
+
104
+ verifyFile(config.tempFile, valid => {
105
+ if (valid) {
106
+ unpackFile(config.tempFile)
107
+ } else {
108
+ console.log(`checksum verification failed, refusing to unpack...`)
109
+ process.exit(1)
110
+ }
111
+ })
112
+ })
113
+ })
114
+ }
115
+
116
+ if (config.source === '') {
117
+ console.log(
118
+ `Skipping downloading embedded Git as platform '${process.platform}' is not supported.`
119
+ )
120
+ console.log(`To learn more about using dugite with a system Git: https://git.io/vF5oj`)
121
+ process.exit(0)
122
+ }
123
+
124
+ if (fs.existsSync(config.outputPath)) {
125
+ try {
126
+ rimraf.sync(config.outputPath)
127
+ } catch (err) {
128
+ console.error(err)
129
+ return
130
+ }
131
+ }
132
+
133
+ mkdirp(config.outputPath, function(error) {
134
+ if (error) {
135
+ console.log(`Unable to create directory at ${config.outputPath}`, error)
136
+ process.exit(1)
137
+ }
138
+
139
+ const tempFile = config.tempFile
140
+
141
+ if (fs.existsSync(tempFile)) {
142
+ verifyFile(tempFile, valid => {
143
+ if (valid) {
144
+ unpackFile(tempFile)
145
+ } else {
146
+ rimraf.sync(tempFile)
147
+ downloadAndUnpack()
148
+ }
149
+ })
150
+ return
151
+ }
152
+
153
+ downloadAndUnpack()
154
+ })
@@ -0,0 +1,27 @@
1
+ {
2
+ "win32-x64": {
3
+ "name": "dugite-native-v2.32.0-e5e7a87-windows-x64.tar.gz",
4
+ "url": "https://github.com/desktop/dugite-native/releases/download/v2.32.0-1/dugite-native-v2.32.0-e5e7a87-windows-x64.tar.gz",
5
+ "checksum": "4d5247c6a837f4280cb4e5bd77d0a17cfc3b4aa000c8f5feaf94a99c6b997374"
6
+ },
7
+ "win32-ia32": {
8
+ "name": "dugite-native-v2.32.0-e5e7a87-windows-x86.tar.gz",
9
+ "url": "https://github.com/desktop/dugite-native/releases/download/v2.32.0-1/dugite-native-v2.32.0-e5e7a87-windows-x86.tar.gz",
10
+ "checksum": "3588a76e84f6658d0598f087f6fa7ae882fb0fd61c59a0ccbb8a613c490f3b4f"
11
+ },
12
+ "darwin-x64": {
13
+ "name": "dugite-native-v2.32.0-e5e7a87-macOS-x64.tar.gz",
14
+ "url": "https://github.com/desktop/dugite-native/releases/download/v2.32.0-1/dugite-native-v2.32.0-e5e7a87-macOS-x64.tar.gz",
15
+ "checksum": "488cbc7e8f294d073b486a0f9839d3fbcc82c5c56b0bca825bb60d12c19b04b9"
16
+ },
17
+ "darwin-arm64": {
18
+ "name": "dugite-native-v2.32.0-e5e7a87-macOS-arm64.tar.gz",
19
+ "url": "https://github.com/desktop/dugite-native/releases/download/v2.32.0-1/dugite-native-v2.32.0-e5e7a87-macOS-arm64.tar.gz",
20
+ "checksum": "d1f67b13417d2e335349ff917877d420778b0b1621ff8f85163379dcff5f0338"
21
+ },
22
+ "linux-x64": {
23
+ "name": "dugite-native-v2.32.0-e5e7a87-ubuntu.tar.gz",
24
+ "url": "https://github.com/desktop/dugite-native/releases/download/v2.32.0-1/dugite-native-v2.32.0-e5e7a87-ubuntu.tar.gz",
25
+ "checksum": "d1bec4d9618b009e46c023ff4d03cdf8da3ce0419536cecf72e05e5bb350bc0d"
26
+ }
27
+ }