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-extra");
|
12 | const gs = require("glob-stream");
|
13 | const fpath = require("path");
|
14 | const stream = require("stream");
|
15 | const file_1 = require("../../internal/util/file");
|
16 | const logger_1 = require("../../internal/util/logger");
|
17 | const RepoId_1 = require("../../operations/common/RepoId");
|
18 | const InMemoryProject_1 = require("../mem/InMemoryProject");
|
19 | const AbstractProject_1 = require("../support/AbstractProject");
|
20 | const projectUtils_1 = require("../support/projectUtils");
|
21 | const LocalProject_1 = require("./LocalProject");
|
22 | const NodeFsLocalFile_1 = require("./NodeFsLocalFile");
|
23 | class NodeFsLocalProject extends AbstractProject_1.AbstractProject {
|
24 | |
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | constructor(ident, baseDir, cleanup = () => Promise.resolve()) {
|
32 | super(typeof ident === "string" ? new RepoId_1.SimpleRepoId(undefined, ident) : ident);
|
33 | this.cleanup = cleanup;
|
34 |
|
35 | this.baseDir = "" + baseDir;
|
36 | }
|
37 | |
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 | static fromExistingDirectory(id, baseDir, cleanup = () => Promise.resolve()) {
|
45 | return fs.stat(baseDir).then(stat => {
|
46 | if (!stat.isDirectory()) {
|
47 | throw new Error(`No such directory: [${baseDir}] when trying to create LocalProject`);
|
48 | }
|
49 | else {
|
50 | return new NodeFsLocalProject(id, baseDir, cleanup);
|
51 | }
|
52 | });
|
53 | }
|
54 | |
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | static copy(other, baseDir, cleanup = () => Promise.resolve()) {
|
63 | return fs.ensureDir(baseDir)
|
64 | .then(() => {
|
65 | if (LocalProject_1.isLocalProject(other)) {
|
66 | return fs.copy(other.baseDir, baseDir)
|
67 | .then(() => new NodeFsLocalProject(other.id, baseDir, cleanup));
|
68 | }
|
69 | else {
|
70 |
|
71 |
|
72 | const p = new NodeFsLocalProject(other.id, baseDir, cleanup);
|
73 | return projectUtils_1.copyFiles(other, p)
|
74 | .then(() => {
|
75 |
|
76 | let prom = Promise.resolve(p);
|
77 | if (InMemoryProject_1.isInMemoryProject(other)) {
|
78 | other.addedDirectoryPaths.forEach(path => {
|
79 | prom = prom.then(() => p.addDirectory(path));
|
80 | });
|
81 | }
|
82 | return prom;
|
83 | });
|
84 | }
|
85 | });
|
86 | }
|
87 | release() {
|
88 | return this.cleanup();
|
89 | }
|
90 | addFileSync(path, content) {
|
91 | const realName = this.baseDir + "/" + path;
|
92 | const dir = fpath.dirname(realName);
|
93 | if (!fs.existsSync(dir)) {
|
94 | fs.mkdirsSync(dir);
|
95 | }
|
96 | fs.writeFileSync(realName, content);
|
97 | }
|
98 | addFile(path, content) {
|
99 | const realName = this.baseDir + "/" + path;
|
100 | const dir = fpath.dirname(realName);
|
101 | return fs.pathExists(dir).then(exists => exists ? Promise.resolve() : fs.mkdirs(dir))
|
102 | .then(() => fs.writeFile(realName, content))
|
103 | .then(() => this);
|
104 | }
|
105 | addDirectory(path) {
|
106 | const realName = this.baseDir + "/" + path;
|
107 | return fs.mkdirp(realName)
|
108 | .then(() => this);
|
109 | }
|
110 | deleteDirectory(path) {
|
111 | return fs.remove(this.toRealPath(path))
|
112 | .then(_ => this)
|
113 | .catch(err => {
|
114 | logger_1.logger.warn("Unable to delete directory '%s': %s", path, err);
|
115 | return this;
|
116 | });
|
117 | }
|
118 | deleteDirectorySync(path) {
|
119 | const localPath = this.toRealPath(path);
|
120 | try {
|
121 | file_1.deleteFolderRecursive(localPath);
|
122 | fs.unlinkSync(localPath);
|
123 | }
|
124 | catch (e) {
|
125 | logger_1.logger.warn("Ignoring directory deletion error: " + e);
|
126 | }
|
127 | }
|
128 | deleteFileSync(path) {
|
129 | try {
|
130 | fs.unlinkSync(this.toRealPath(path));
|
131 | }
|
132 | catch (e) {
|
133 | logger_1.logger.warn("Ignoring file deletion error: " + e);
|
134 | }
|
135 | }
|
136 | deleteFile(path) {
|
137 | return fs.unlink(this.toRealPath(path)).then(_ => this);
|
138 | }
|
139 | makeExecutable(path) {
|
140 | return fs.stat(this.toRealPath(path))
|
141 | .then(stats => {
|
142 | logger_1.logger.debug("Starting mode: " + stats.mode);
|
143 |
|
144 | const newMode = stats.mode | fs.constants.S_IXUSR;
|
145 | logger_1.logger.debug("Setting mode to: " + newMode);
|
146 | return fs.chmod(this.toRealPath(path), newMode);
|
147 | })
|
148 | .then(() => this);
|
149 | }
|
150 | makeExecutableSync(path) {
|
151 | throw new Error("makeExecutableSync not implemented.");
|
152 | }
|
153 | directoryExistsSync(path) {
|
154 | throw new Error("directoryExistsSync not implemented.");
|
155 | }
|
156 | fileExistsSync(path) {
|
157 | return fs.existsSync(this.baseDir + "/" + path);
|
158 | }
|
159 | findFile(path) {
|
160 | return fs.pathExists(this.baseDir + "/" + path)
|
161 | .then(exists => exists ?
|
162 | Promise.resolve(new NodeFsLocalFile_1.NodeFsLocalFile(this.baseDir, path)) :
|
163 | Promise.reject(fileNotFound(path)));
|
164 | }
|
165 | getFile(path) {
|
166 | return __awaiter(this, void 0, void 0, function* () {
|
167 | const exists = yield fs.pathExists(this.baseDir + "/" + path);
|
168 | return exists ? new NodeFsLocalFile_1.NodeFsLocalFile(this.baseDir, path) :
|
169 | undefined;
|
170 | });
|
171 | }
|
172 | findFileSync(path) {
|
173 | if (!this.fileExistsSync(path)) {
|
174 | return undefined;
|
175 | }
|
176 | return new NodeFsLocalFile_1.NodeFsLocalFile(this.baseDir, path);
|
177 | }
|
178 | streamFilesRaw(globPatterns, opts) {
|
179 |
|
180 | const baseDir = this.baseDir;
|
181 | const toFileTransform = new stream.Transform({ objectMode: true });
|
182 | toFileTransform._transform = function (chunk, encoding, done) {
|
183 | const f = new NodeFsLocalFile_1.NodeFsLocalFile(baseDir, pathWithinArchive(baseDir, chunk.path));
|
184 | this.push(f);
|
185 | done();
|
186 | };
|
187 | const optsToUse = Object.assign({
|
188 |
|
189 | nodir: true, allowEmpty: true }, opts, {
|
190 |
|
191 | cwd: this.baseDir });
|
192 | return gs(globPatterns, optsToUse)
|
193 | .pipe(toFileTransform);
|
194 | }
|
195 | toRealPath(path) {
|
196 | return this.baseDir + "/" + path;
|
197 | }
|
198 | }
|
199 | exports.NodeFsLocalProject = NodeFsLocalProject;
|
200 | function pathWithinArchive(baseDir, rawPath) {
|
201 | return rawPath.substr(baseDir.length);
|
202 | }
|
203 |
|
204 | function fileNotFound(path) {
|
205 | const error = new Error(`File not found at ${path}`);
|
206 | error.code = "ENOENT";
|
207 | return error;
|
208 | }
|
209 |
|
\ | No newline at end of file |