This repository has been archived by the owner on May 26, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathaquifer-git.js
226 lines (195 loc) · 6.88 KB
/
aquifer-git.js
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/**
* @file
* Git deployment for Aquifer.
*/
/* globals require, Aquifer, AquiferGitConfig, module */
module.exports = (Aquifer, AquiferGitConfig) => {
'use strict';
const AquiferGit = () => {};
const _ = require('lodash');
const mktemp = require('mktemp');
const path = require('path');
const fs = require('fs-extra');
/**
* Informs Aquifer of what this deployment script does.
* @returns {object} details about this deployment script.
*/
AquiferGit.commands = () => {
return {
'deploy-git': {
description: 'Deploys the site to a remote Git repository.',
options: {
remote: {
name: '-r, --remote <remote>',
description: 'The repository to deploy to.'
},
branch: {
name: '-b, --branch <branch>',
description: 'The branch to deploy to.'
},
message: {
name: '-m, --message <message>',
default: 'Deployment from source repository.',
description: 'The message to use with the deployment commit.'
},
folder: {
name: '-f, --folder <folder_name>',
default: false,
description: 'Subfolder in remote repository that should hold the build.'
},
name: {
name: '-n, --name <name>',
default: false,
description: 'Name to use for the deployment commit signature.'
},
email: {
name: '-a, --email <email>',
default: false,
description: 'Email to use for the deployment commit signature.'
},
debug: {
name: '-d, --debug',
default: false,
description: 'Don\'t delete the temporary aquifer-git-* directory.'
}
}
}
};
};
/**
* Run when user runs commands within this extension.
* @param {string} command string representing the name of the command defined in AquiferGit.commands that should run.
* @param {object} commandOptions options passed from the command.
* @param {function} callback function that is called when there is an error message to send.
* @returns {undefined} null.
*/
AquiferGit.run = (command, commandOptions, callback) => {
if (command !== 'deploy-git') {
callback('Invalid command.');
return;
}
let options = {
deploymentFiles: [],
excludeLinks: ['sites/default/files'],
addLinks: [],
delPatterns: ['*', '!.git']
};
let requiredOptions = ['remote', 'branch', 'message'];
let optionsMissing = false;
let build;
let destPath;
let run = new Aquifer.api.run(Aquifer);
// Parse options and make sure they all exist.
_.assign(options, AquiferGitConfig, commandOptions, (lastValue, nextValue, name) => {
return nextValue ? nextValue : lastValue;
});
requiredOptions.forEach((name) => {
if (!options[name]) {
callback('"' + name + '" option is missing. Cannot deploy.');
optionsMissing = true;
}
});
if (optionsMissing) {
return;
}
// If we have an email without a name, then we cannot create a custom
// signature and need to bail out.
if (options.email && !options.name) {
callback('Name is required for a custom commit signature if the email is provided.');
return;
}
// Create the destination directory and initiate the promise chain.
mktemp.createDir('aquifer-git-XXXXXXX')
// Clone the repository.
.then((destPath_) => {
Aquifer.console.log('Cloning the repository into ' + destPath_ + '...', 'status');
destPath = destPath_;
return run.invoke('git clone ' + options.remote + ' ' + destPath);
})
// Checkout or create the specified branch.
.then(() => {
return run.invoke('git -C ' + path.join(Aquifer.projectDir, destPath) + ' checkout ' + options.branch)
.then(() => {
Aquifer.console.log('Checking out branch: ' + options.branch + '...', 'status');
})
.catch(() => {
Aquifer.console.log('Creating new branch: ' + options.branch + '...', 'status');
return run.invoke('git -C ' + path.join(Aquifer.projectDir, destPath) + ' checkout -b ' + options.branch);
});
})
// Build the site.
.then(() => {
Aquifer.console.log('Building the site...', 'status');
let buildOptions = {
symlink: false,
delPatterns: options.delPatterns,
excludeLinks: options.excludeLinks,
addLinks: options.addLinks
};
// Calculate build path.
let buildPath = destPath;
// If a folder is specified, add it to the build path.
if (options.folder) {
buildPath = path.join(buildPath, options.folder);
}
// Create instance of build object.
build = new Aquifer.api.build(Aquifer);
return build.create(buildPath, buildOptions);
})
// Copy over additional deployment files.
.then(() => {
Aquifer.console.log('Copying deployment files...', 'status');
options.deploymentFiles.forEach(function (link) {
let src = path.join(Aquifer.projectDir, link.src);
let dest = path.join(destPath, link.dest);
fs.removeSync(dest);
fs.copySync(src, dest, {clobber: true});
});
})
// Clear the current index.
.then(() => {
Aquifer.console.log('Clearing the index...', 'status');
fs.removeSync(path.join(Aquifer.projectDir, destPath, '.git/index'));
})
// Add all files to the index.
.then(() => {
Aquifer.console.log('Adding all files to the index...', 'status');
return run.invoke('git -C ' + path.join(Aquifer.projectDir, destPath) + ' add -A');
})
// Commit changes.
.then(() => {
Aquifer.console.log('Committing changes...', 'status');
let command = 'git -C ' + path.join(Aquifer.projectDir, destPath) + ' commit -m "' + options.message + '"';
// Add author info to commit if we have it in config options.
if (options.name) {
options.email = options.email || '';
command += ' --author "' + options.name + ' <' + options.email + '>"';
}
return run.invoke(command);
})
// Push to origin.
.then(() => {
Aquifer.console.log('Pushing branch: ' + options.branch + '...', 'status');
return run.invoke('git -C ' + path.join(Aquifer.projectDir, destPath) + ' push origin ' + options.branch);
})
// Remove the destination path.
.then(() => {
if (!options.debug) {
Aquifer.console.log('Removing the ' + destPath + ' directory...', 'status');
fs.removeSync(destPath);
}
})
// Success!
.then(() => {
Aquifer.console.log('The site has been successfully deployed!', 'success');
})
// Catch any errors.
.catch((err) => {
if (!options.debug) {
fs.removeSync(destPath);
}
callback(err);
});
};
return AquiferGit;
};