1 | # node-fixturify-project
|
2 |
|
3 | [![npm version](https://badge.fury.io/js/fixturify-project.svg)](https://badge.fury.io/js/fixturify-project)
|
4 | [![CI](https://github.com/stefanpenner/node-fixturify-project/workflows/CI/badge.svg)](https://github.com/stefanpenner/node-fixturify-project/actions/workflows/ci.yml)
|
5 |
|
6 | When implementing JS build tooling it is common to have complete projects as
|
7 | fixture data. Unfortunately fixtures committed to disk can be somewhat hard to
|
8 | maintain and augment.
|
9 |
|
10 | ## Basic Usage
|
11 |
|
12 | ```sh
|
13 | npm install --save-dev fixturify-project
|
14 | ```
|
15 |
|
16 | ```js
|
17 | const { Project } = require('fixturify-project');
|
18 | const project = new Project('rsvp', '3.1.4', {
|
19 | files: {
|
20 | 'index.js': 'module.exports = "Hello, World!"',
|
21 | },
|
22 | });
|
23 |
|
24 | project.addDependency('mocha', '5.2.0');
|
25 | project.addDependency('chai', '5.2.0');
|
26 |
|
27 | project.pkg; // => the contents of package.json for the given project
|
28 | project.files; // => read or write the set of files further
|
29 |
|
30 | // if you don't set this, a new temp dir will be made for you when you write()
|
31 | project.baseDir = 'some/base/dir/';
|
32 |
|
33 | await project.write();
|
34 |
|
35 | // after write(), you can read project.baseDir even if you didn't set it
|
36 | expect(fs.existsSync(join(project.baseDir, 'index.js'))).to.eql(true);
|
37 | ```
|
38 |
|
39 | The above example produces the following files (and most importantly the
|
40 | appropriate file contents:
|
41 |
|
42 | ```sh
|
43 | some/base/dir/package.json
|
44 | some/base/dir/index.js
|
45 | some/base/dir/node_modules/mocha/package.json
|
46 | some/base/dir/node_modules/chai/package.json
|
47 | ```
|
48 |
|
49 | ### Nesting Dependencies
|
50 |
|
51 | `addDependency` returns another `Project` instance, so you can nest arbitrarily deep:
|
52 |
|
53 | ```js
|
54 | const { Project } = require('fixturify-project');
|
55 |
|
56 | let project = new Project('rsvp');
|
57 | let a = project.addDependency('a');
|
58 | let b = a.addDependency('b');
|
59 | let c = b.addDependency('c');
|
60 |
|
61 | await project.write();
|
62 | ```
|
63 |
|
64 | Which produces:
|
65 |
|
66 | ```sh
|
67 | $TMPDIR/xxx/package.json
|
68 | $TMPDIR/xxx/index.js
|
69 | $TMPDIR/xxx/node_modules/a/package.json
|
70 | $TMPDIR/xxx/node_modules/a/node_modules/b/package.json
|
71 | $TMPDIR/xxx/node_modules/b/node_modules/b/node_modules/c/package.json
|
72 | ```
|
73 |
|
74 | ### Linking to real dependencies
|
75 |
|
76 | Instead of creating all packages from scratch, you can link to real preexisting
|
77 | packages. This lets you take a real working package and modify it and its
|
78 | dependencies and watch how it behaves.
|
79 |
|
80 | ```js
|
81 | const { Project } = require('fixturify-project');
|
82 |
|
83 | let project = new Project();
|
84 | let a = project.addDependency('a');
|
85 |
|
86 | // explicit target
|
87 | project.linkDependency('b', { target: '/example/b' });
|
88 |
|
89 | // this will follow node resolution rules to lookup "c" from "../elsewhere"
|
90 | project.linkDependency('c', { baseDir: '/example' });
|
91 |
|
92 | // this will follow node resolution rules to lookup "my-aliased-name" from "../elsewhere"
|
93 | project.linkDependency('d', { baseDir: '/example', resolveName: 'my-aliased-name' });
|
94 |
|
95 | await project.write();
|
96 | ```
|
97 |
|
98 | Produces:
|
99 |
|
100 | ```sh
|
101 | $TMPDIR/xxx/package.json
|
102 | $TMPDIR/xxx/index.js
|
103 | $TMPDIR/xxx/node_modules/a/package.json
|
104 | $TMPDIR/xxx/node_modules/a/node_modules/b -> /example/b
|
105 | $TMPDIR/xxx/node_modules/b/node_modules/c -> /example/node_modules/c
|
106 | $TMPDIR/xxx/node_modules/b/node_modules/d -> /example/node_modules/my-aliased-name
|
107 | ```
|
108 |
|
109 | When constructing a whole Project from a directory, you can choose to link all
|
110 | dependencies instead of copying them in as Projects:
|
111 |
|
112 | ```js
|
113 | let project = Project.fromDir('./sample-project', { linkDeps: true });
|
114 | project.files['extra.js'] = '// stuff';
|
115 | await project.write();
|
116 | ```
|
117 |
|
118 | This will generate a new copy of sample-project, with symlinks to all its
|
119 | original dependencies, but with "extra.js" added.
|
120 |
|
121 | By default, `linkDeps` will only link up `dependencies` (which is appropriate
|
122 | for libraries). If you want to also include `devDependencies` (which is
|
123 | appropriate for apps) you can use `linkDevDeps` instead.
|
124 |
|
125 | ## API
|
126 |
|
127 |
|
128 | <a name="Project"></a>
|
129 |
|
130 | ## Project
|
131 | **Kind**: global class
|
132 |
|
133 | - [node-fixturify-project](#node-fixturify-project)
|
134 | - [Basic Usage](#basic-usage)
|
135 | - [Nesting Dependencies](#nesting-dependencies)
|
136 | - [Linking to real dependencies](#linking-to-real-dependencies)
|
137 | - [API](#api)
|
138 | - [Project](#project)
|
139 | - [project.baseDir](#projectbasedir)
|
140 | - [project.baseDir](#projectbasedir-1)
|
141 | - [project.name : string](#projectname--string)
|
142 | - [project.name](#projectname)
|
143 | - [project.version : string](#projectversion--string)
|
144 | - [project.version](#projectversion)
|
145 | - [project.mergeFiles(dirJSON)](#projectmergefilesdirjson)
|
146 | - [project.write(dirJSON?)](#projectwritedirjson)
|
147 | - [project.addDependency() ⇒](#projectadddependency-)
|
148 | - [project.addDevDependency() ⇒](#projectadddevdependency-)
|
149 | - [project.removeDependency(name)](#projectremovedependencyname)
|
150 | - [project.removeDevDependency(name)](#projectremovedevdependencyname)
|
151 | - [project.linkDependency(name)](#projectlinkdependencyname)
|
152 | - [project.linkDevDependency(name)](#projectlinkdevdependencyname)
|
153 | - [project.dependencyProjects() ⇒](#projectdependencyprojects-)
|
154 | - [project.devDependencyProjects() ⇒](#projectdevdependencyprojects-)
|
155 | - [project.clone() ⇒](#projectclone-)
|
156 | - [project.dispose()](#projectdispose)
|
157 | - [Project.fromDir(baseDir, opts) ⇒](#projectfromdirbasedir-opts-)
|
158 |
|
159 | ### project.baseDir
|
160 | <p>Sets the base directory of the project.</p>
|
161 |
|
162 | **Kind**: instance property of [<code>Project</code>](#Project)
|
163 |
|
164 | | Param | Description |
|
165 | | --- | --- |
|
166 | | dir | <p>The directory path.</p> |
|
167 |
|
168 | <a name="Project+baseDir"></a>
|
169 |
|
170 | ### project.baseDir
|
171 | <p>Gets the base directory path, usually a tmp directory unless a baseDir has been explicitly set.</p>
|
172 |
|
173 | **Kind**: instance property of [<code>Project</code>](#Project)
|
174 | **Read only**: true
|
175 | <a name="Project+name"></a>
|
176 |
|
177 | ### project.name : <code>string</code>
|
178 | <p>Gets the package name from the package.json.</p>
|
179 |
|
180 | **Kind**: instance property of [<code>Project</code>](#Project)
|
181 | <a name="Project+name"></a>
|
182 |
|
183 | ### project.name
|
184 | <p>Sets the package name in the package.json.</p>
|
185 |
|
186 | **Kind**: instance property of [<code>Project</code>](#Project)
|
187 | <a name="Project+version"></a>
|
188 |
|
189 | ### project.version : <code>string</code>
|
190 | <p>Gets the version number from the package.json.</p>
|
191 |
|
192 | **Kind**: instance property of [<code>Project</code>](#Project)
|
193 | <a name="Project+version"></a>
|
194 |
|
195 | ### project.version
|
196 | <p>Sets the version number in the package.json.</p>
|
197 |
|
198 | **Kind**: instance property of [<code>Project</code>](#Project)
|
199 | <a name="Project+mergeFiles"></a>
|
200 |
|
201 | ### project.mergeFiles(dirJSON)
|
202 | <p>Merges an object containing a directory represention with the existing files.</p>
|
203 |
|
204 | **Kind**: instance method of [<code>Project</code>](#Project)
|
205 |
|
206 | | Param | Description |
|
207 | | --- | --- |
|
208 | | dirJSON | <p>An object containing a directory representation to merge.</p> |
|
209 |
|
210 | <a name="Project+write"></a>
|
211 |
|
212 | ### project.write(dirJSON?)
|
213 | <p>Writes the existing files property containing a directory representation to the tmp directory.</p>
|
214 |
|
215 | **Kind**: instance method of [<code>Project</code>](#Project)
|
216 |
|
217 | | Param | Description |
|
218 | | --- | --- |
|
219 | | dirJSON? | <p>An optional object containing a directory representation to write.</p> |
|
220 |
|
221 | ### project.addDependency() ⇒
|
222 | <p>Adds a dependency to the Project's package.json.</p>
|
223 |
|
224 | **Kind**: instance method of [<code>Project</code>](#Project)
|
225 | **Returns**: <ul>
|
226 | <li>The Project instance.</li>
|
227 | </ul>
|
228 | <a name="Project+addDevDependency"></a>
|
229 |
|
230 | ### project.addDevDependency() ⇒
|
231 | <p>Adds a devDependency to the Project's package.json.</p>
|
232 |
|
233 | **Kind**: instance method of [<code>Project</code>](#Project)
|
234 | **Returns**: <ul>
|
235 | <li>The Project instance.</li>
|
236 | </ul>
|
237 | <a name="Project+removeDependency"></a>
|
238 |
|
239 | ### project.removeDependency(name)
|
240 | <p>Removes a dependency to the Project's package.json.</p>
|
241 |
|
242 | **Kind**: instance method of [<code>Project</code>](#Project)
|
243 |
|
244 | | Param | Description |
|
245 | | --- | --- |
|
246 | | name | <p>The name of the dependency to remove.</p> |
|
247 |
|
248 | <a name="Project+removeDevDependency"></a>
|
249 |
|
250 | ### project.removeDevDependency(name)
|
251 | <p>Removes a devDependency.</p>
|
252 |
|
253 | **Kind**: instance method of [<code>Project</code>](#Project)
|
254 |
|
255 | | Param | Description |
|
256 | | --- | --- |
|
257 | | name | <p>The name of the devDependency to remove.</p> |
|
258 |
|
259 | <a name="Project+linkDependency"></a>
|
260 |
|
261 | ### project.linkDependency(name)
|
262 | <p>Links a dependency.</p>
|
263 |
|
264 | **Kind**: instance method of [<code>Project</code>](#Project)
|
265 |
|
266 | | Param | Description |
|
267 | | --- | --- |
|
268 | | name | <p>The name of the dependency to link.</p> |
|
269 |
|
270 | <a name="Project+linkDevDependency"></a>
|
271 |
|
272 | ### project.linkDevDependency(name)
|
273 | <p>Links a devDependency.</p>
|
274 |
|
275 | **Kind**: instance method of [<code>Project</code>](#Project)
|
276 |
|
277 | | Param | Description |
|
278 | | --- | --- |
|
279 | | name | <p>The name of the dependency to link.</p> |
|
280 |
|
281 | <a name="Project+dependencyProjects"></a>
|
282 |
|
283 | ### project.dependencyProjects() ⇒
|
284 | **Kind**: instance method of [<code>Project</code>](#Project)
|
285 | **Returns**: <ul>
|
286 | <li>An array of the dependencies for this Projct.</li>
|
287 | </ul>
|
288 | <a name="Project+devDependencyProjects"></a>
|
289 |
|
290 | ### project.devDependencyProjects() ⇒
|
291 | **Kind**: instance method of [<code>Project</code>](#Project)
|
292 | **Returns**: <ul>
|
293 | <li>An array of the devDependencies for this Projct.</li>
|
294 | </ul>
|
295 | <a name="Project+clone"></a>
|
296 |
|
297 | ### project.clone() ⇒
|
298 | **Kind**: instance method of [<code>Project</code>](#Project)
|
299 | **Returns**: <ul>
|
300 | <li>The cloned Project.</li>
|
301 | </ul>
|
302 | <a name="Project+dispose"></a>
|
303 |
|
304 | ### project.dispose()
|
305 | <p>Disposes of the tmp directory that the Project is stored in.</p>
|
306 |
|
307 | **Kind**: instance method of [<code>Project</code>](#Project)
|
308 | <a name="Project.fromDir"></a>
|
309 |
|
310 | ### Project.fromDir(baseDir, opts) ⇒
|
311 | <p>Reads an existing project from the specified base dir.</p>
|
312 |
|
313 | **Kind**: static method of [<code>Project</code>](#Project)
|
314 | **Returns**: <ul>
|
315 | <li>The deserialized Project.</li>
|
316 | </ul>
|
317 |
|
318 | | Param | Description |
|
319 | | --- | --- |
|
320 | | baseDir | <p>The base directory to read the project from.</p> |
|
321 | | opts | <p>An options object.</p> |
|
322 | | opts.linkDeps | <p>Include linking dependencies from the Project's node_modules.</p> |
|
323 | | opts.linkDevDeps | <p>Include linking devDependencies from the Project's node_modules.</p> |
|
324 |
|
325 |
|
326 |
|