tests/helpers/package-cache.js:102
PackageCache
The PackageCache wraps all package management functions. It also handles initial global state setup.
Usage:
let cache = new PackageCache();
let dir = cache.create('your-cache', 'yarn', '{
"dependencies": {
"lodash": "*",
"ember-cli": "*"
}
}');
// => process.cwd()/tmp/your-cache-A3B4C6D
This will generate a persistent cache which contains the results
of a clean installation of the dependencies
as you specified in
the manifest argument. It will save the results of these in a
temporary folder, returned as dir
. On a second invocation
(in the same process, or in a subsequent run) PackageCache will first
compare the manifest to the previously installed one, using the manifest
as the cache key, and make a decision as to the fastest way to get
the cache up-to-date. PackageCache guarantees that your cache will
always be up-to-date.
If done in the same process, this simply returns the existing cache directory with no change, making the following invocation simply a cache validation check:
let dir2 = cache.create('your-cache', 'yarn', '{
"dependencies": {
"lodash": "*",
"ember-cli": "*"
}
}');
// => process.cwd()/tmp/your-cache-A3B4C6D
If you wish to modify a cache you can do so using the update
API:
let dir3 = cache.update('your-cache', 'yarn', '{
"dependencies": {
"": "*",
"lodash": "*",
"ember-cli": "*"
}
}');
// => process.cwd()/tmp/your-cache-A3B4C6D
Underneath the hood create
and update
are identical–which
makes clear the simplicity of this tool. It will always do the
right thing. You can think of the outcome of any create
or
update
call as identical to rm -rf node_modules && npm install
except as performant as possible.
If you need to make modifications to a cache but wish to retain
the original you can invoke the clone
command:
let newDir = cache.clone('your-cache', 'modified-cache');
let manifest = fs.readJsonSync(path.join(newDir, 'package.json'));
manifest.dependencies['express'] = '*';
cache.update('modified-cache', 'yarn', JSON.stringify(manifest));
// => process.cwd()/tmp/modified-cache-F8D5C8B
This mental model makes it easy to prevent coding mistakes, state leakage across multiple test runs by making multiple caches cheap, and has tremendous performance benefits.
You can even programatically update a cache:
let CommandGenerator = require('./command-generator');
let yarn = new CommandGenerator('yarn');
let dir = cache.create('your-cache', 'yarn', '{ ... }');
yarn.invoke('add', 'some-addon', { cwd: dir });
The programmatic approach enables the entire set of usecases that the underlying package manager supports while continuing to wrap it in a persistent cache. You should not directly modify any files in the cache other than the manifest unless you really know what you're doing as that can put the cache into a possibly invalid state.
PackageCache also supports linking. If you pass an array of module names to
in the fourth position it will ensure that those are linked, and remain
linked for the lifetime of the cache. When you link a package it uses the
current global link provided by the underlying package manager and invokes
their built-in link
command.
let dir = cache.create('your-cache', 'yarn', '{ ... }', ['ember-cli']);
// => yarn link ember-cli
happens along the way.
Sometimes this global linking behavior is not what you want. Instead you wish
to link in some other working directory. PackageCache makes a best effort
attempt at supporting this workflow by allowing you to specify an object in
the links
argument array passed to create
.
let dir = cache.create('your-cache', 'yarn', '{ ... }', [ { name: 'ember-cli', path: '/the/absolute/path/to/the/package' }, 'other-package' ]);
This creates a symlink at the named package path to the specified directory. As package managers do different things for their own linking behavior this is "best effort" only. Be sure to review upstream behavior to identify if you rely on those features for your code to function:
As the only caveat, PackageCache is persistent. The consuming code is responsible for ensuring that the cache size does not grow unbounded.
Constructor Summary
Private Constructors | |
---|---|
private |
PackageCache(rootPath)
The PackageCache wraps all package management functions. It also handles initial global state setup. |
Method Summary
Public Methods | |
---|---|
public |
The |
public |
destroy(label, type)
The |
public |
destroy(fromLabel, toLabel)
The |
public |
The |
public |
The |
Private Methods | |
---|---|
private |
The |
private |
The |
private |
_checkManifest(label, type, manifest): Boolean
The |
private |
_cleanDirs( )
The |
private |
_install(label, type)
The |
private |
_readManifest(label, type): String
The |
private |
_removeLinks(label, type)
The |
private |
_restoreLinks(label, type)
The |
private |
_upgrade(label, type)
The |
private |
_writeManifest(label, type, manifest)
The |
private |
bower(subcommand, [arguments], [options={}])
The |
private |
npm(subcommand, [arguments], [options={}])
The |
private |
translate(type, lookup)
The |
private |
yarn(subcommand, [arguments], [options={}])
The |
Private Constructors
tests/helpers/package-cache.js:102
private PackageCache(rootPath)
Parameters:
Name | Type | Attribute | Description |
---|---|---|---|
rootPath | String |
|
Root of the directory for |
Public Methods
tests/helpers/package-cache.js:578
public create(label, type, manifest, links): String
The create
method adds a new package cache entry.
Parameters:
Name | Type | Attribute | Description |
---|---|---|---|
label | String |
|
The label for the cache. |
type | String |
|
The type of package cache. |
manifest | String |
|
The contents of the manifest file for the cache. |
links | Array |
|
Packages to omit for install and link. |
Return:
The directory on disk which contains the cache.
tests/helpers/package-cache.js:644
public destroy(label, type)
The destroy
method removes all evidence of the package cache.
tests/helpers/package-cache.js:659
public destroy(fromLabel, toLabel)
The clone
method duplicates a cache. Some package managers can
leverage a pre-existing state to speed up their installation.
tests/helpers/package-cache.js:633
public get(label): String
The get
method returns the directory for the cache.
Parameters:
Name | Type | Attribute | Description |
---|---|---|---|
label | String |
|
The label for the cache. |
Return:
The directory on disk which contains the cache.
tests/helpers/package-cache.js:619
public update(label, type, manifest, links): String
The update
method aliases the create
method.
Parameters:
Name | Type | Attribute | Description |
---|---|---|---|
label | String |
|
The label for the cache. |
type | String |
|
The type of package cache. |
manifest | String |
|
The contents of the manifest file for the cache. |
links | Array |
|
Packages to elide for install and link. |
Return:
The directory on disk which contains the cache.
Private Methods
tests/helpers/package-cache.js:264
private __resetForTesting( )
The __resetForTesting
puts things back in module scope.
tests/helpers/package-cache.js:253
private __setupForTesting( )
The __setupForTesting
modifies things in module scope.
tests/helpers/package-cache.js:483
private _checkManifest(label, type, manifest): Boolean
The _checkManifest
method compares the desired manifest to that which
exists in the cache.
Parameters:
Name | Type | Attribute | Description |
---|---|---|---|
label | String |
|
The label for the cache. |
type | String |
|
The type of package cache. |
manifest | String |
|
The contents of the manifest file to compare to cache. |
Return:
true
if identical.
tests/helpers/package-cache.js:274
private _cleanDirs( )
The _cleanDirs
method deals with sync issues between the
Configstore and what exists on disk. Non-existent directories
are removed from this.dirs
.
tests/helpers/package-cache.js:524
private _install(label, type)
The _install
method installs the contents of the manifest into the
specified package cache.
tests/helpers/package-cache.js:295
private _readManifest(label, type): String
The _readManifest
method reads the on-disk manifest for the current
cache and returns its value.
Parameters:
Name | Type | Attribute | Description |
---|---|---|---|
label | String |
|
The label for the cache. |
type | String |
|
The type of package cache. |
Return:
The manifest file contents on disk.
tests/helpers/package-cache.js:360
private _removeLinks(label, type)
The _removeLinks
method removes from the dependencies of the manifest the
assets which will be linked in so that we don't duplicate install. It saves
off the values in the internal PackageCache
metadata for restoration after
linking as those values may be necessary.
It is also responsible for removing these links prior to making any changes to the specified cache.
tests/helpers/package-cache.js:433
private _restoreLinks(label, type)
The _restoreLinks
method restores the dependencies from the internal
PackageCache
metadata so that the manifest matches its original state after
performing the links.
It is also responsible for restoring these links into the PackageCache
.
tests/helpers/package-cache.js:542
private _upgrade(label, type)
The _upgrade
method guarantees that the contents of the manifest are
allowed to drift in a SemVer compatible manner. It ensures that CI is
always running against the latest versions of all dependencies.
tests/helpers/package-cache.js:326
private _writeManifest(label, type, manifest)
The _writeManifest
method generates the on-disk folder for the package cache
and saves the manifest into it. If it is a yarn package cache it will remove
the existing lock file.
tests/helpers/package-cache.js:25
private bower(subcommand, [arguments], [options={}])
The bower
command helper.
Parameters:
Name | Type | Attribute | Description |
---|---|---|---|
subcommand | String |
|
The subcommand to be passed into bower. |
arguments | String |
|
Arguments to be passed into the bower subcommand. |
options | Object |
|
The options passed into child_process.spawnSync. (https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options) |
tests/helpers/package-cache.js:37
private npm(subcommand, [arguments], [options={}])
The npm
command helper.
Parameters:
Name | Type | Attribute | Description |
---|---|---|---|
subcommand | String |
|
The subcommand to be passed into npm. |
arguments | String |
|
Arguments to be passed into the npm subcommand. |
options | Object |
|
The options passed into child_process.spawnSync. (https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options) |
tests/helpers/package-cache.js:88
private translate(type, lookup)
The translate
command is used to turn a consistent argument into
appropriate values based upon the context in which it is used. It's
a convenience helper to avoid littering lookups throughout the code.
tests/helpers/package-cache.js:49
private yarn(subcommand, [arguments], [options={}])
The yarn
command helper.
Parameters:
Name | Type | Attribute | Description |
---|---|---|---|
subcommand | String |
|
The subcommand to be passed into yarn. |
arguments | String |
|
Arguments to be passed into the yarn subcommand. |
options | Object |
|
The options passed into child_process.spawnSync. (https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options) |