mirror of
https://github.com/bower/bower.git
synced 2026-04-24 03:00:19 -04:00
Compare commits
96 Commits
fix/window
...
v1.7.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbaaee67a1 | ||
|
|
ad27112b58 | ||
|
|
38c3cee1a7 | ||
|
|
b485c5d3cb | ||
|
|
d63047b4ee | ||
|
|
f0a54d0018 | ||
|
|
1d73764788 | ||
|
|
9d2681b0c4 | ||
|
|
f3330e8612 | ||
|
|
11996c04b7 | ||
|
|
35e73a619a | ||
|
|
fe615fd517 | ||
|
|
3e3b64218d | ||
|
|
afe76e57f8 | ||
|
|
6ee3ef7aa8 | ||
|
|
64db869bd4 | ||
|
|
a4ea05800d | ||
|
|
8cf897cd19 | ||
|
|
d06af7a3d7 | ||
|
|
d4fd71986e | ||
|
|
3154444556 | ||
|
|
24f8b913b9 | ||
|
|
fe6b6863ea | ||
|
|
671c23ad50 | ||
|
|
5384fa54b1 | ||
|
|
4bfa8227d9 | ||
|
|
55d78f7928 | ||
|
|
2110148830 | ||
|
|
afc4bfbd42 | ||
|
|
9c42a008aa | ||
|
|
67884744c3 | ||
|
|
ed881e3f29 | ||
|
|
e6e60d5d5e | ||
|
|
d8f166a933 | ||
|
|
bb626d1605 | ||
|
|
daa5b8ddf9 | ||
|
|
db087dfe13 | ||
|
|
848e401efd | ||
|
|
3cf597fccf | ||
|
|
e2adbc37f1 | ||
|
|
6c3b7dbf58 | ||
|
|
d3ab3c1fa7 | ||
|
|
b1ba9be7f6 | ||
|
|
1e5122c023 | ||
|
|
4255d7d4a8 | ||
|
|
cdf45239f4 | ||
|
|
8b2fad32f6 | ||
|
|
d1ae0b1982 | ||
|
|
87cf578ba8 | ||
|
|
3ead440c7c | ||
|
|
e168c894a2 | ||
|
|
75e3661371 | ||
|
|
baf8f7bf6b | ||
|
|
88758cd98c | ||
|
|
3bd2d62e67 | ||
|
|
d3eef5772a | ||
|
|
7c714901d4 | ||
|
|
7792b6d35d | ||
|
|
2db983dba3 | ||
|
|
b9718bb309 | ||
|
|
26f609e614 | ||
|
|
4c2b56096b | ||
|
|
5af929f0be | ||
|
|
686e883d87 | ||
|
|
f2767648e7 | ||
|
|
9e4bdd270d | ||
|
|
7cb88ab49f | ||
|
|
a532c55dca | ||
|
|
c559432c19 | ||
|
|
322c49edf4 | ||
|
|
fe9b27a647 | ||
|
|
1605374a25 | ||
|
|
ac244a1400 | ||
|
|
d50e50f3b5 | ||
|
|
3030469c59 | ||
|
|
977e0ddc52 | ||
|
|
de3e1089da | ||
|
|
7897ad7dba | ||
|
|
accdab3ece | ||
|
|
612aaa88eb | ||
|
|
338ac99080 | ||
|
|
9605bbea5f | ||
|
|
3791aee9d6 | ||
|
|
20a223a959 | ||
|
|
ea5bd51327 | ||
|
|
b94c20b8da | ||
|
|
b81ba140e3 | ||
|
|
4ffdb500b9 | ||
|
|
1696cde273 | ||
|
|
94ffc35b25 | ||
|
|
5a1e5eb9c7 | ||
|
|
8c1f30b1c8 | ||
|
|
e3f402fc66 | ||
|
|
6616d09f47 | ||
|
|
25ad2ef946 | ||
|
|
ba4a1a9d45 |
45
.eslintrc
Normal file
45
.eslintrc
Normal file
@@ -0,0 +1,45 @@
|
||||
env:
|
||||
node: true
|
||||
|
||||
# enable ECMAScript features
|
||||
ecmaFeatures:
|
||||
arrowFunctions: true
|
||||
binaryLiterals: true
|
||||
blockBindings: true
|
||||
classes: true
|
||||
forOf: true
|
||||
generators: true
|
||||
objectLiteralShorthandMethods: true
|
||||
objectLiteralShorthandProperties: true
|
||||
octalLiterals: true
|
||||
templateStrings: true
|
||||
|
||||
rules:
|
||||
no-debugger: 2
|
||||
no-dupe-args: 2
|
||||
no-dupe-keys: 2
|
||||
no-duplicate-case: 2
|
||||
no-ex-assign: 2
|
||||
no-reserved-keys: 2
|
||||
no-unreachable: 2
|
||||
valid-typeof: 2
|
||||
no-fallthrough: 2
|
||||
quotes: [2, "single", "avoid-escape"]
|
||||
indent: [2, 2]
|
||||
comma-spacing: 2
|
||||
semi: 2
|
||||
space-infix-ops: 2
|
||||
space-return-throw-case: 2
|
||||
space-before-function-paren: [2, "never"]
|
||||
space-before-blocks: [2, "always"]
|
||||
new-parens: 2
|
||||
max-len: [2, 80, 2]
|
||||
no-multiple-empty-lines: [2, {max: 2}]
|
||||
eol-last: 2
|
||||
no-trailing-spaces: 2
|
||||
space-after-keywords: 2
|
||||
|
||||
# ECMAScript 6
|
||||
prefer-const: 2
|
||||
strict: [2, "global"]
|
||||
no-undef: 2
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -9,3 +9,6 @@
|
||||
/bower.json
|
||||
/component.json
|
||||
/bower_components
|
||||
/test/sample
|
||||
!/test/sample/bower.json
|
||||
/npm-shrinkwrap.json
|
||||
|
||||
4
.npmignore
Normal file
4
.npmignore
Normal file
@@ -0,0 +1,4 @@
|
||||
test
|
||||
appveyor.yml
|
||||
Gruntfile.js
|
||||
CONTRIBUTING.md
|
||||
43
CHANGELOG.md
43
CHANGELOG.md
@@ -1,5 +1,48 @@
|
||||
# Changelog
|
||||
|
||||
## 1.7.3 - 2015-01-20
|
||||
|
||||
- Remove analytics from Bower, fixes ([#2150](https://github.com/bower/bower/pull/2150))
|
||||
- Default to ^ operator on `bower install --save` ([#2145](https://github.com/bower/bower/pull/2145))
|
||||
- Support absolute path in .bowerrc directory option ([#2130](https://github.com/bower/bower/pull/2130))
|
||||
- Display user's name upon `bower login` command ([#2133](https://github.com/bower/bower/pull/2133))
|
||||
- Decompress gzip files ([#2092](https://github.com/bower/bower/pull/2092))
|
||||
- Prevent name clashes in package extraction ([#2102](https://github.com/bower/bower/pull/2102))
|
||||
- Update request to 2.67.0
|
||||
- Update fs-write-stream-atomic to 1.0.8
|
||||
- Documentation improvements
|
||||
|
||||
## 1.7.2 - 2015-12-31
|
||||
|
||||
- Lock "fs-write-stream-atomic" to 1.0.5
|
||||
|
||||
## 1.7.1 - 2015-12-11
|
||||
|
||||
- Rollback "Add `bower update --save` functionality", it causes issues and needs more testing
|
||||
- Fix backward-compatibility of `bower search --json` ([#2066](https://github.com/bower/bower/issues/2066))
|
||||
- Ignore prerelease versions from `bower info` output
|
||||
- Update update-notifier to 0.6.0
|
||||
- Better formatting of help messages (https://github.com/bower/bower/commit/de3e1089da80f47ea3667c5ab80d301cddfd8c3e)
|
||||
- Add help menu for update `--save` and `update --save-dev` (https://github.com/bower/bower/commit/612aaa88eb4d4b268b2d8665c338ac086af3a5b0)
|
||||
|
||||
## 1.7.0 - 2015-12-07
|
||||
|
||||
- Add `bower update --save` functionality ([#2035](https://github.com/bower/bower/issues/2035))
|
||||
- `bower search` shows help message when no package name is specified ([#2066](https://github.com/bower/bower/issues/2066))
|
||||
- Update only those packages that are explicitly requested by the user. Related Issues
|
||||
- [#256](https://github.com/bower/bower/issues/256)
|
||||
- [#924](https://github.com/bower/bower/issues/924)
|
||||
- [#1770](https://github.com/bower/bower/issues/1770)
|
||||
- Allow for @ in username for SVN on windows ([#1650](https://github.com/bower/bower/issues/1650))
|
||||
- Update bower config
|
||||
- Loads the .bowerrc file from the cwd specified on the command line
|
||||
- Allow the use of environment variables in .bowerrc ([#41](https://github.com/bower/config/issues/41))
|
||||
- Allow for array notation in ENV variables ([#44](https://github.com/bower/config/issues/44))
|
||||
|
||||
## 1.6.9 - 2015-12-04
|
||||
|
||||
- Change git version of fs-write-stream-atomic back to npm version ([#2079](https://github.com/bower/bower/issues/2079))
|
||||
|
||||
## 1.6.8 - 2015-11-27
|
||||
|
||||
- Use fs-write-stream-atomic for downloads
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. If you're interested in becoming Bower maintainer or supporting in in any way, please full the following form: http://goo.gl/forms/P1ndzCNoiG. There is more information about [contributing](https://github.com/bower/bower/wiki/Contributor-Guidelines) in the Wiki.
|
||||
|
||||
<a name="bugs"></a>
|
||||
## 🐛 [Bug reports](https://github.com/bower/bower/wiki/Report-a-Bug)
|
||||
|
||||
## Casual Involvement
|
||||
|
||||
* Improve the bower.io site ([tickets](https://github.com/bower/bower.github.io/issues))
|
||||
@@ -35,48 +38,6 @@ requests](#pull-requests), but please respect the following restrictions:
|
||||
* Please **do not** derail or troll issues. Keep the discussion on topic and
|
||||
respect the opinions of others.
|
||||
|
||||
<a name="bugs"></a>
|
||||
## Bug reports
|
||||
|
||||
A bug is a _demonstrable problem_ that is caused by the code in the repository.
|
||||
Good bug reports are extremely helpful - thank you!
|
||||
|
||||
Guidelines for bug reports:
|
||||
|
||||
1. **Use the GitHub issue search** — check if the issue has already been
|
||||
reported.
|
||||
|
||||
2. **Check if the issue has been fixed** — try to reproduce it using the
|
||||
latest `master` or development branch in the repository.
|
||||
|
||||
3. **Isolate the problem** — ideally create a [reduced test
|
||||
case](http://css-tricks.com/6263-reduced-test-cases/).
|
||||
|
||||
A good bug report shouldn't leave others needing to chase you up for more
|
||||
information. Please try to be as detailed as possible in your report. What is
|
||||
your environment? What steps will reproduce the issue? What OS experiences the
|
||||
problem? What would you expect to be the outcome? All these details will help
|
||||
people to fix any potential bugs.
|
||||
|
||||
Example:
|
||||
|
||||
> Short and descriptive example bug report title
|
||||
>
|
||||
> A summary of the issue and the browser/OS environment in which it occurs. If
|
||||
> suitable, include the steps required to reproduce the bug.
|
||||
>
|
||||
> 1. This is the first step
|
||||
> 2. This is the second step
|
||||
> 3. Further steps, etc.
|
||||
>
|
||||
> `<url>` - a link to the reduced test case
|
||||
>
|
||||
> Any other information you want to share that is relevant to the issue being
|
||||
> reported. This might include the lines of code that you have identified as
|
||||
> causing the bug, and potential solutions (and your opinions on their
|
||||
> merits).
|
||||
|
||||
|
||||
<a name="features"></a>
|
||||
## Feature requests
|
||||
|
||||
@@ -160,6 +121,8 @@ included in the project:
|
||||
force push to your remote feature branch. You may also be asked to squash
|
||||
commits.
|
||||
|
||||
10. If you are asked to squash your commits, then please use `git rebase -i master`. It will ask you to pick your commits - pick the major commits and squash the rest.
|
||||
|
||||
**IMPORTANT**: By submitting a patch, you agree to license your work under the
|
||||
same license as that used by the project.
|
||||
|
||||
|
||||
163
Gruntfile.js
163
Gruntfile.js
@@ -1,4 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
var tmp = require('tmp');
|
||||
var childProcess = require('child_process');
|
||||
var arraydiff = require('arr-diff');
|
||||
var fs = require('fs');
|
||||
var wrench = require('wrench');
|
||||
var inquirer = require('inquirer');
|
||||
var path = require('path');
|
||||
|
||||
module.exports = function (grunt) {
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
@@ -14,6 +23,7 @@ module.exports = function (grunt) {
|
||||
'test/**/*.js',
|
||||
'!test/assets/**/*',
|
||||
'!test/reports/**/*',
|
||||
'!test/sample/**/*',
|
||||
'!test/tmp/**/*'
|
||||
]
|
||||
},
|
||||
@@ -29,6 +39,7 @@ module.exports = function (grunt) {
|
||||
'test/**/*.js',
|
||||
'!test/assets/**/*',
|
||||
'!test/reports/**/*',
|
||||
'!test/sample/**/*',
|
||||
'!test/tmp/**/*'
|
||||
]
|
||||
},
|
||||
@@ -55,10 +66,11 @@ module.exports = function (grunt) {
|
||||
command: 'node test/packages.js --force && node test/packages-svn.js --force'
|
||||
},
|
||||
cover: {
|
||||
command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js'
|
||||
command: 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js'
|
||||
},
|
||||
coveralls: {
|
||||
command: 'node node_modules/.bin/coveralls < test/reports/lcov.info'
|
||||
command: 'npm run coveralls < test/reports/lcov.info',
|
||||
exitCodes: [0,1,2,3] // Alow for failure for coverage report
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -68,8 +80,153 @@ module.exports = function (grunt) {
|
||||
});
|
||||
|
||||
grunt.registerTask('assets', ['exec:assets-force']);
|
||||
grunt.registerTask('test', ['jshint', 'jscs', 'exec:assets', 'simplemocha:full']);
|
||||
grunt.registerTask('test', ['jscs', 'jshint', 'exec:assets', 'simplemocha:full']);
|
||||
grunt.registerTask('cover', 'exec:cover');
|
||||
grunt.registerTask('travis', ['jshint', 'exec:assets', 'exec:cover', 'exec:coveralls']);
|
||||
grunt.registerTask('default', 'test');
|
||||
|
||||
grunt.task.registerTask('publish', 'Perform final checks and publish Bower', function () {
|
||||
var npmVersion = JSON.parse(childProcess.execSync('npm version --json').toString()).npm.split('.');
|
||||
var npmMajor = parseInt(npmVersion[0], 10);
|
||||
var npmMinor = parseInt(npmVersion[1], 10);
|
||||
|
||||
if (npmMajor !== 3 || npmMinor < 5) {
|
||||
grunt.log.writeln('You need to use at least npm@3.5 to publish bower.');
|
||||
grunt.log.writeln('It is because npm 2.x produces too long paths that Windows does not handle.');
|
||||
grunt.log.writeln('Please upgrade it: npm install -g npm');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var version = require('./package').version;
|
||||
var changelog = fs.readFileSync('./CHANGELOG.md');
|
||||
|
||||
if (changelog.indexOf('## ' + version) === -1) {
|
||||
grunt.log.writeln('Please add changelog.md entry for this bower version (' + version + ')');
|
||||
|
||||
var lastRelease = childProcess.execSync('git tag | tail -1').toString().trim();
|
||||
|
||||
grunt.log.writeln('Commits since last release (' + lastRelease + '): \n');
|
||||
|
||||
grunt.log.writeln(childProcess.execSync('git log --oneline ' + lastRelease + '..').toString());
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (childProcess.execSync('git rev-parse --abbrev-ref HEAD').toString().trim() !== 'master') {
|
||||
grunt.log.writeln('You need to release bower from the "master" branch');
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
grunt.log.writeln('Reinstalling dependencies...');
|
||||
childProcess.execSync('rm -rf node_modules && npm install', { stdio: [0, 1, 2] });
|
||||
|
||||
grunt.log.writeln('Running test suite...');
|
||||
childProcess.execSync('grunt test', { stdio: [0, 1, 2] });
|
||||
|
||||
var dir = tmp.dirSync().name;
|
||||
var pkgDir = path.resolve(dir, 'lib');
|
||||
|
||||
wrench.copyDirSyncRecursive(__dirname, pkgDir, {
|
||||
forceDelete: true,
|
||||
include: function (path) {
|
||||
return !path.match(/node_modules|\.git|test/);
|
||||
}
|
||||
});
|
||||
|
||||
grunt.log.writeln('Installing dependencies');
|
||||
childProcess.execSync('npm install --production --silent', { cwd: pkgDir, stdio: [0, 1, 2] });
|
||||
|
||||
fs.createReadStream(
|
||||
path.resolve(__dirname, 'README.md')
|
||||
).pipe(
|
||||
fs.createWriteStream(path.resolve(dir, 'README.md'))
|
||||
);
|
||||
|
||||
var json = require('./package');
|
||||
json.bin = 'lib/' + json.bin;
|
||||
json.main = 'lib/' + json.main;
|
||||
delete json.dependencies;
|
||||
delete json.devDependencies;
|
||||
delete json.scripts;
|
||||
delete json.files;
|
||||
|
||||
fs.writeFileSync(path.resolve(dir, 'package.json'), JSON.stringify(json, null, ' '));
|
||||
|
||||
// So node_modules are not ignored
|
||||
fs.unlinkSync(path.resolve(pkgDir, 'package.json'));
|
||||
|
||||
childProcess.execSync('npm install --production --silent', { cwd: pkgDir, stdio: [0, 1, 2] });
|
||||
|
||||
grunt.log.writeln('Testing bower on sample project...');
|
||||
|
||||
childProcess.execSync(
|
||||
'cd test/sample && rm -rf bower_components && ' + pkgDir + '/bin/bower install --force', { stdio: [0, 1, 2] }
|
||||
);
|
||||
|
||||
var expectedPackages = (
|
||||
'SHA-1 ace-builds almond angular angular-animate angular-bootstrap angular-charts angular-contenteditable ' +
|
||||
'angular-deckgrid angular-fullscreen angular-gravatar angular-hotkeys angular-local-storage angular-marked ' +
|
||||
'angular-moment angular-sanitize angular-touch angular-ui-router angular-ui-sortable ' +
|
||||
'angulartics asEvented bootstrap coffee-script d3 es6-shim font-awesome howler jquery ' +
|
||||
'jquery-ui jquery-waypoints js-beautify lodash lz-string marked moment ng-file-upload peerjs ' +
|
||||
'requirejs restangular slimScroll slimScrollHorizontal venturocket-angular-slider'
|
||||
).split(' ');
|
||||
|
||||
var installedPackages = fs.readdirSync('./test/sample/bower_components');
|
||||
|
||||
var installedDiff = arraydiff(expectedPackages, installedPackages);
|
||||
|
||||
if (installedDiff.length > 0) {
|
||||
grunt.log.writeln('ERROR. Some packages were not installed by bower: ');
|
||||
grunt.log.writeln(installedDiff.join(', '));
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var questions = [
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'review',
|
||||
message: 'Did you review all the changes with "git diff"?',
|
||||
default: false
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'changelog',
|
||||
message: 'Are you sure the CHANGELOG.md contains all changes?',
|
||||
default: false
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'tests',
|
||||
message: 'Are you sure all tests are passing on Travis and Appveyor?',
|
||||
default: false
|
||||
},
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'publish',
|
||||
message: 'Are you SURE you want to publish ' + require('./package').name + '@' + require('./package').version + '?',
|
||||
default: false
|
||||
}
|
||||
];
|
||||
|
||||
var done = this.async();
|
||||
|
||||
inquirer.prompt(questions, function (answers) {
|
||||
if (!answers.review || !answers.changelog || !answers.tests || !answers.publish) {
|
||||
grunt.log.writeln('Please publish bower after you fix this issue');
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
grunt.log.writeln('\nPlease remember to tag this relese, and add a release on Github!');
|
||||
grunt.log.writeln('\nAlso, please remember to test published Bower one more time!');
|
||||
grunt.log.writeln('\nPublishing Bower...');
|
||||
|
||||
childProcess.execSync('npm publish', { cwd: dir, stdio: [0, 1, 2] });
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
21
HOOKS.md
21
HOOKS.md
@@ -1,21 +0,0 @@
|
||||
# Install and Uninstall Hooks
|
||||
|
||||
Bower provides 3 separate hooks that can be used to trigger other automated tools during Bower usage. Importantly, these hooks are intended to allow external tools to help wire up the newly installed components into the parent project and other similar tasks. These hooks are not intended to provide a post-installation build step for component authors. As such, the configuration for these hooks is provided in the `.bowerrc` file in the parent project's directory.
|
||||
|
||||
## Configuring
|
||||
|
||||
In `.bowerrc` do:
|
||||
|
||||
```js
|
||||
{
|
||||
"scripts": {
|
||||
"preinstall": "<your command here>",
|
||||
"postinstall": "<your command here>",
|
||||
"preuninstall": "<your command here>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The value of each script hook may contain a % character. When your script is called, the % will be replaced with a space-separated list of components being installed or uninstalled.
|
||||
|
||||
Your script will also include an environment variable `BOWER_PID` containing the PID of the parent Bower process that triggered the script. This can be used to verify that a `preinstall` and `postinstall` steps are part of the same Bower process.
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2015 Twitter and other contributors
|
||||
Copyright (c) 2016 Twitter and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
||||
14
README.md
14
README.md
@@ -1,11 +1,11 @@
|
||||
# Bower - A package manager for the web
|
||||
|
||||
> Bower needs resources for its maintenance. Please fill [<strong>Support Declaration</strong>](http://goo.gl/forms/P1ndzCNoiG) if you think you can help.
|
||||
> Bower needs resources for its maintenance. Please fill [this form](https://docs.google.com/forms/d/1i-Opb-uPdqUBBZQSbngv3Y3bfolG1gbBvtRLfxMnzRE/viewform?c=0&w=1) if you think you can help.
|
||||
|
||||
[](https://travis-ci.org/bower/bower)
|
||||
[](https://ci.appveyor.com/project/sheerun/bower/history)
|
||||
[](https://coveralls.io/r/bower/bower?branch=master)
|
||||
[](https://gitter.im/bower/bower?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://discord.gg/0fFM7QF0KpZRh2cY)
|
||||
[](http://issuestats.com/github/bower/bower)
|
||||
[](http://issuestats.com/github/bower/bower)
|
||||
|
||||
@@ -52,7 +52,7 @@ $ bower install <package>#<version> --save
|
||||
|
||||
We discourage using bower components statically for performance and security reasons (if component has an `upload.php` file that is not ignored, that can be easily exploited to do malicious stuff).
|
||||
|
||||
The best approach is to process components installed by bower with build tool (like [Grunt](http://gruntjs.com/) or [gulp](http://gulpjs.com/)), and serve them concatenated or using module loader (like [RequireJS](http://requirejs.org/)).
|
||||
The best approach is to process components installed by bower with build tool (like [Grunt](http://gruntjs.com/) or [gulp](http://gulpjs.com/)), and serve them concatenated or using a module loader (like [RequireJS](http://requirejs.org/)).
|
||||
|
||||
### Uninstalling packages
|
||||
|
||||
@@ -68,7 +68,7 @@ On `prezto` or `oh-my-zsh`, do not forget to `alias bower='noglob bower'` or `bo
|
||||
|
||||
### Never run Bower with sudo
|
||||
|
||||
Bower is a user command, there is no need to execute it with superuser permissions.
|
||||
Bower is a user command; there is no need to execute it with superuser permissions.
|
||||
|
||||
### Windows users
|
||||
|
||||
@@ -100,15 +100,13 @@ Bower can be configured using JSON in a `.bowerrc` file. Read over available opt
|
||||
|
||||
## Support
|
||||
|
||||
* [Discord chat](https://discord.gg/0fFM7QF0KpZRh2cY)
|
||||
* [StackOverflow](http://stackoverflow.com/questions/tagged/bower)
|
||||
* [Mailinglist](http://groups.google.com/group/twitter-bower) - twitter-bower@googlegroups.com
|
||||
* [\#bower](http://webchat.freenode.net/?channels=bower) on Freenode
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome [contributions](https://github.com/bower/bower/graphs/contributors) of all kinds from anyone. Please take a moment to
|
||||
review the [guidelines for contributing](CONTRIBUTING.md).
|
||||
We welcome [contributions](https://github.com/bower/bower/graphs/contributors) of all kinds from anyone. Please take a moment to review the [guidelines for contributing](CONTRIBUTING.md).
|
||||
|
||||
* [Bug reports](https://github.com/bower/bower/wiki/Report-a-Bug)
|
||||
* [Feature requests](CONTRIBUTING.md#features)
|
||||
|
||||
@@ -18,6 +18,7 @@ environment:
|
||||
matrix:
|
||||
allow_failures:
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "5"
|
||||
|
||||
# Install scripts. (runs after repo cloning)
|
||||
install:
|
||||
@@ -33,7 +34,7 @@ install:
|
||||
|
||||
# Post-install test scripts.
|
||||
test_script:
|
||||
- cmd: npm test
|
||||
- cmd: npm run ci
|
||||
|
||||
# Don't actually build.
|
||||
build: off
|
||||
|
||||
100
bin/bower
100
bin/bower
@@ -8,10 +8,9 @@ var mout = require('mout');
|
||||
var Logger = require('bower-logger');
|
||||
var userHome = require('user-home');
|
||||
var bower = require('../lib');
|
||||
var pkg = require('../package.json');
|
||||
var version = require('../lib/version');
|
||||
var cli = require('../lib/util/cli');
|
||||
var rootCheck = require('../lib/util/rootCheck');
|
||||
var analytics = require('../lib/util/analytics');
|
||||
|
||||
var options;
|
||||
var renderer;
|
||||
@@ -29,7 +28,7 @@ options = cli.readOptions({
|
||||
|
||||
// Handle print of version
|
||||
if (options.version) {
|
||||
process.stdout.write(pkg.version + '\n');
|
||||
process.stdout.write(version + '\n');
|
||||
process.exit();
|
||||
}
|
||||
|
||||
@@ -68,37 +67,36 @@ while (options.argv.remain.length) {
|
||||
options.argv.remain.pop();
|
||||
}
|
||||
|
||||
// Ask for Insights on first run.
|
||||
analytics.setup(bower.config).then(function () {
|
||||
// Execute the command
|
||||
commandFunc = command && mout.object.get(bower.commands, command);
|
||||
command = command && command.replace(/\./g, ' ');
|
||||
// Execute the command
|
||||
commandFunc = command && mout.object.get(bower.commands, command);
|
||||
command = command && command.replace(/\./g, ' ');
|
||||
|
||||
// If no command was specified, show bower help
|
||||
// Do the same if the command is unknown
|
||||
if (!commandFunc) {
|
||||
logger = bower.commands.help();
|
||||
command = 'help';
|
||||
// If the user requested help, show the command's help
|
||||
// Do the same if the actual command is a group of other commands (e.g.: cache)
|
||||
} else if (options.help || !commandFunc.line) {
|
||||
// If no command was specified, show bower help
|
||||
// Do the same if the command is unknown
|
||||
if (!commandFunc) {
|
||||
logger = bower.commands.help();
|
||||
command = 'help';
|
||||
// If the user requested help, show the command's help
|
||||
// Do the same if the actual command is a group of other commands (e.g.: cache)
|
||||
} else if (options.help || !commandFunc.line) {
|
||||
logger = bower.commands.help(command);
|
||||
command = 'help';
|
||||
// Call the line method
|
||||
} else {
|
||||
logger = commandFunc.line(process.argv);
|
||||
|
||||
// If the method failed to interpret the process arguments
|
||||
// show the command help
|
||||
if (!logger) {
|
||||
logger = bower.commands.help(command);
|
||||
command = 'help';
|
||||
// Call the line method
|
||||
} else {
|
||||
logger = commandFunc.line(process.argv);
|
||||
|
||||
// If the method failed to interpret the process arguments
|
||||
// show the command help
|
||||
if (!logger) {
|
||||
logger = bower.commands.help(command);
|
||||
command = 'help';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the renderer and configure it with the executed command
|
||||
renderer = cli.getRenderer(command, logger.json, bower.config);
|
||||
// Get the renderer and configure it with the executed command
|
||||
renderer = cli.getRenderer(command, logger.json, bower.config);
|
||||
|
||||
function handleLogger(logger, renderer) {
|
||||
logger
|
||||
.on('end', function (data) {
|
||||
if (!bower.config.silent && !bower.config.quiet) {
|
||||
@@ -106,11 +104,17 @@ analytics.setup(bower.config).then(function () {
|
||||
}
|
||||
})
|
||||
.on('error', function (err) {
|
||||
if (levels.error >= loglevel) {
|
||||
renderer.error(err);
|
||||
}
|
||||
if (command !== 'help' && err.code === cli.READ_OPTIONS_ERROR_CODE) {
|
||||
logger = bower.commands.help(command);
|
||||
renderer = cli.getRenderer('help', logger.json, bower.config);
|
||||
handleLogger(logger, renderer);
|
||||
} else {
|
||||
if (levels.error >= loglevel) {
|
||||
renderer.error(err);
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
process.exit(1);
|
||||
}
|
||||
})
|
||||
.on('log', function (log) {
|
||||
if (levels[log.level] >= loglevel) {
|
||||
@@ -123,20 +127,22 @@ analytics.setup(bower.config).then(function () {
|
||||
callback(answer);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Warn if HOME is not SET
|
||||
if (!userHome) {
|
||||
logger.warn('no-home', 'HOME environment variable not set. User config will not be loaded.');
|
||||
handleLogger(logger, renderer);
|
||||
|
||||
// Warn if HOME is not SET
|
||||
if (!userHome) {
|
||||
logger.warn('no-home', 'HOME environment variable not set. User config will not be loaded.');
|
||||
}
|
||||
|
||||
if (bower.config.interactive) {
|
||||
var updateNotifier = require('update-notifier');
|
||||
|
||||
// Check for newer version of Bower
|
||||
var notifier = updateNotifier({ pkg: { name: 'bower', version: version } });
|
||||
|
||||
if (notifier.update && levels.info >= loglevel) {
|
||||
notifier.notify();
|
||||
}
|
||||
|
||||
if (bower.config.interactive) {
|
||||
var updateNotifier = require('update-notifier');
|
||||
|
||||
// Check for newer version of Bower
|
||||
var notifier = updateNotifier({pkg: pkg});
|
||||
|
||||
if (notifier.update && levels.info >= loglevel) {
|
||||
notifier.notify();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,24 +10,24 @@ var config = require('../config');
|
||||
* return as soon as possible and load and execute the command asynchronously.
|
||||
*/
|
||||
function commandFactory(id) {
|
||||
if (process.env.STRICT_REQUIRE) {
|
||||
require(id);
|
||||
}
|
||||
|
||||
function command() {
|
||||
function runApi() {
|
||||
var command = require(id);
|
||||
var commandArgs = [].slice.call(arguments);
|
||||
|
||||
return withLogger(function (logger) {
|
||||
commandArgs.unshift(logger);
|
||||
return require(id).apply(undefined, commandArgs);
|
||||
|
||||
return command.apply(undefined, commandArgs);
|
||||
});
|
||||
}
|
||||
|
||||
function runFromArgv(argv) {
|
||||
return withLogger(function (logger) {
|
||||
var command = require(id);
|
||||
var commandArgs;
|
||||
var command = require(id);
|
||||
|
||||
var commandArgs = command.readOptions(argv);
|
||||
commandArgs = command.readOptions(argv);
|
||||
|
||||
return withLogger(function (logger) {
|
||||
commandArgs.unshift(logger);
|
||||
|
||||
return command.apply(undefined, commandArgs);
|
||||
@@ -38,7 +38,7 @@ function commandFactory(id) {
|
||||
var logger = new Logger();
|
||||
|
||||
Q.try(func, logger)
|
||||
.done(function () {
|
||||
.then(function () {
|
||||
config.restore();
|
||||
var args = [].slice.call(arguments);
|
||||
args.unshift('end');
|
||||
@@ -51,9 +51,9 @@ function commandFactory(id) {
|
||||
return logger;
|
||||
}
|
||||
|
||||
command.line = runFromArgv;
|
||||
runApi.line = runFromArgv;
|
||||
|
||||
return command;
|
||||
return runApi;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ var mout = require('mout');
|
||||
var Q = require('q');
|
||||
var endpointParser = require('bower-endpoint-parser');
|
||||
var PackageRepository = require('../core/PackageRepository');
|
||||
var Tracker = require('../util/analytics').Tracker;
|
||||
var defaultConfig = require('../config');
|
||||
|
||||
function info(logger, endpoint, property, config) {
|
||||
@@ -12,14 +11,11 @@ function info(logger, endpoint, property, config) {
|
||||
|
||||
var repository;
|
||||
var decEndpoint;
|
||||
var tracker;
|
||||
|
||||
config = defaultConfig(config);
|
||||
repository = new PackageRepository(config, logger);
|
||||
tracker = new Tracker(config);
|
||||
|
||||
decEndpoint = endpointParser.decompose(endpoint);
|
||||
tracker.trackDecomposedEndpoints('info', [decEndpoint]);
|
||||
|
||||
return Q.all([
|
||||
getPkgMeta(repository, decEndpoint, property),
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
var endpointParser = require('bower-endpoint-parser');
|
||||
var Project = require('../core/Project');
|
||||
var Tracker = require('../util/analytics').Tracker;
|
||||
var defaultConfig = require('../config');
|
||||
|
||||
function install(logger, endpoints, options, config) {
|
||||
var project;
|
||||
var decEndpoints;
|
||||
var tracker;
|
||||
|
||||
options = options || {};
|
||||
config = defaultConfig(config);
|
||||
@@ -14,14 +12,12 @@ function install(logger, endpoints, options, config) {
|
||||
options.save = config.defaultSave;
|
||||
}
|
||||
project = new Project(config, logger);
|
||||
tracker = new Tracker(config);
|
||||
|
||||
// Convert endpoints to decomposed endpoints
|
||||
endpoints = endpoints || [];
|
||||
decEndpoints = endpoints.map(function (endpoint) {
|
||||
return endpointParser.decompose(endpoint);
|
||||
});
|
||||
tracker.trackDecomposedEndpoints('install', decEndpoints);
|
||||
|
||||
return project.install(decEndpoints, options, config);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ var Q = require('q');
|
||||
var Project = require('../core/Project');
|
||||
var createLink = require('../util/createLink');
|
||||
var defaultConfig = require('../config');
|
||||
var relativeToBaseDir = require('../util/relativeToBaseDir');
|
||||
|
||||
function link(logger, name, localName, config) {
|
||||
if (name) {
|
||||
@@ -49,7 +50,7 @@ function linkTo(logger, name, localName, config) {
|
||||
|
||||
localName = localName || name;
|
||||
src = path.join(config.storage.links, name);
|
||||
dst = path.join(config.cwd, config.directory, localName);
|
||||
dst = path.join(relativeToBaseDir(config.cwd)(config.directory), localName);
|
||||
|
||||
// Delete destination folder if any
|
||||
return Q.nfcall(rimraf, dst)
|
||||
|
||||
@@ -63,6 +63,7 @@ function login(logger, options, config) {
|
||||
|
||||
return promise.then(function (result) {
|
||||
configstore.set('accessToken', result.token);
|
||||
logger.info('EAUTH', 'Logged in as ' + configstore.get('username'), {});
|
||||
|
||||
return result;
|
||||
}, function (error) {
|
||||
@@ -95,6 +96,7 @@ function login(logger, options, config) {
|
||||
})
|
||||
.then(function (result) {
|
||||
configstore.set('accessToken', result.token);
|
||||
logger.info('EAUTH', 'Logged in as ' + configstore.get('username'), {});
|
||||
|
||||
return result;
|
||||
}, function () {
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
var Q = require('q');
|
||||
var chalk = require('chalk');
|
||||
var PackageRepository = require('../core/PackageRepository');
|
||||
var Tracker = require('../util/analytics').Tracker;
|
||||
var createError = require('../util/createError');
|
||||
var defaultConfig = require('../config');
|
||||
|
||||
function register(logger, name, url, config) {
|
||||
var repository;
|
||||
var registryClient;
|
||||
var tracker;
|
||||
var force;
|
||||
|
||||
config = defaultConfig(config);
|
||||
force = config.force;
|
||||
tracker = new Tracker(config);
|
||||
|
||||
name = (name || '').trim();
|
||||
url = (url || '').trim();
|
||||
@@ -28,8 +25,6 @@ function register(logger, name, url, config) {
|
||||
throw createError('Usage: bower register <name> <url>', 'EINVFORMAT');
|
||||
}
|
||||
|
||||
tracker.track('register');
|
||||
|
||||
// Attempt to resolve the package referenced by the URL to ensure
|
||||
// everything is ok before registering
|
||||
repository = new PackageRepository(config, logger);
|
||||
|
||||
@@ -1,34 +1,38 @@
|
||||
var Q = require('q');
|
||||
var RegistryClient = require('bower-registry-client');
|
||||
var Tracker = require('../util/analytics').Tracker;
|
||||
var defaultConfig = require('../config');
|
||||
var cli = require('../util/cli');
|
||||
|
||||
function search(logger, name, config) {
|
||||
var registryClient;
|
||||
var tracker;
|
||||
|
||||
var json = config ? config.json : undefined;
|
||||
config = defaultConfig(config);
|
||||
config.json = config.json || json; // Hack until bower-config is fixed...
|
||||
config.cache = config.storage.registry;
|
||||
|
||||
registryClient = new RegistryClient(config, logger);
|
||||
tracker = new Tracker(config);
|
||||
tracker.track('search', name);
|
||||
|
||||
// If no name was specified, list all packages
|
||||
if (!name) {
|
||||
return Q.nfcall(registryClient.list.bind(registryClient));
|
||||
// Otherwise search it
|
||||
} else {
|
||||
if (name) {
|
||||
return Q.nfcall(registryClient.search.bind(registryClient), name);
|
||||
} else {
|
||||
// List all packages when in interactive mode + json enabled, and
|
||||
// always when in non-interactive mode
|
||||
if (config.interactive && !config.json) {
|
||||
throw cli.createReadOptionsError('search');
|
||||
}
|
||||
|
||||
return Q.nfcall(registryClient.list.bind(registryClient));
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------
|
||||
|
||||
search.readOptions = function (argv) {
|
||||
var cli = require('../util/cli');
|
||||
var options = cli.readOptions(argv);
|
||||
var name = options.argv.remain.slice(1).join(' ');
|
||||
var terms = options.argv.remain.slice(1);
|
||||
|
||||
var name = terms.join(' ');
|
||||
|
||||
return [name];
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
var mout = require('mout');
|
||||
var Q = require('q');
|
||||
var Project = require('../core/Project');
|
||||
var Tracker = require('../util/analytics').Tracker;
|
||||
var defaultConfig = require('../config');
|
||||
|
||||
function uninstall(logger, names, options, config) {
|
||||
@@ -10,14 +9,10 @@ function uninstall(logger, names, options, config) {
|
||||
}
|
||||
|
||||
var project;
|
||||
var tracker;
|
||||
|
||||
options = options || {};
|
||||
config = defaultConfig(config);
|
||||
project = new Project(config, logger);
|
||||
tracker = new Tracker(config);
|
||||
|
||||
tracker.trackNames('uninstall', names);
|
||||
|
||||
return project.getTree(options)
|
||||
.spread(function (tree, flattened) {
|
||||
|
||||
@@ -3,7 +3,6 @@ var Q = require('q');
|
||||
|
||||
var defaultConfig = require('../config');
|
||||
var PackageRepository = require('../core/PackageRepository');
|
||||
var Tracker = require('../util/analytics').Tracker;
|
||||
var createError = require('../util/createError');
|
||||
|
||||
function unregister(logger, name, config) {
|
||||
@@ -14,12 +13,10 @@ function unregister(logger, name, config) {
|
||||
|
||||
var repository;
|
||||
var registryClient;
|
||||
var tracker;
|
||||
var force;
|
||||
|
||||
config = defaultConfig(config);
|
||||
force = config.force;
|
||||
tracker = new Tracker(config);
|
||||
|
||||
// Bypass any cache
|
||||
config.offline = false;
|
||||
@@ -30,8 +27,6 @@ function unregister(logger, name, config) {
|
||||
|
||||
repository = new PackageRepository(config, logger);
|
||||
|
||||
tracker.track('unregister');
|
||||
|
||||
if (!config.accessToken) {
|
||||
return logger.emit('error',
|
||||
createError('Use "bower login" with collaborator credentials', 'EFORBIDDEN')
|
||||
@@ -64,7 +59,6 @@ function unregister(logger, name, config) {
|
||||
return Q.nfcall(registryClient.unregister.bind(registryClient), name);
|
||||
})
|
||||
.then(function (result) {
|
||||
tracker.track('unregistered');
|
||||
logger.info('Package unregistered', name);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -23,9 +23,7 @@ update.readOptions = function (argv) {
|
||||
|
||||
var options = cli.readOptions({
|
||||
'force-latest': { type: Boolean, shorthand: 'F' },
|
||||
'production': { type: Boolean, shorthand: 'p' },
|
||||
'save': { type: Boolean, shorthand: 'S' },
|
||||
'save-dev': { type: Boolean, shorthand: 'D' }
|
||||
'production': { type: Boolean, shorthand: 'p' }
|
||||
}, argv);
|
||||
|
||||
var names = options.argv.remain.slice(1);
|
||||
|
||||
@@ -10,6 +10,7 @@ var semver = require('../util/semver');
|
||||
var copy = require('../util/copy');
|
||||
var createError = require('../util/createError');
|
||||
var scripts = require('./scripts');
|
||||
var relativeToBaseDir = require('../util/relativeToBaseDir');
|
||||
|
||||
function Manager(config, logger) {
|
||||
this._config = config;
|
||||
@@ -124,7 +125,7 @@ Manager.prototype.resolve = function () {
|
||||
|
||||
Manager.prototype.preinstall = function (json) {
|
||||
var that = this;
|
||||
var componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
var componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
|
||||
// If nothing to install, skip the code bellow
|
||||
if (mout.lang.isEmpty(that._dissected)) {
|
||||
@@ -141,7 +142,7 @@ Manager.prototype.preinstall = function (json) {
|
||||
|
||||
Manager.prototype.postinstall = function (json) {
|
||||
var that = this;
|
||||
var componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
var componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
|
||||
// If nothing to install, skip the code bellow
|
||||
if (mout.lang.isEmpty(that._dissected)) {
|
||||
@@ -171,7 +172,7 @@ Manager.prototype.install = function (json) {
|
||||
return Q.resolve({});
|
||||
}
|
||||
|
||||
componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
return Q.nfcall(mkdirp, componentsDir)
|
||||
.then(function () {
|
||||
var promises = [];
|
||||
@@ -385,7 +386,7 @@ Manager.prototype._onFetchSuccess = function (decEndpoint, canonicalDir, pkgMeta
|
||||
|
||||
// If the package is not targetable, flag it
|
||||
// It will be needed later so that untargetable endpoints
|
||||
// will not get * converted to ~version
|
||||
// will not get * converted to ^version
|
||||
if (!isTargetable) {
|
||||
decEndpoint.untargetable = true;
|
||||
}
|
||||
@@ -594,7 +595,7 @@ Manager.prototype._dissect = function () {
|
||||
// If they are not, the resolver is incapable of handling targets
|
||||
semvers.forEach(function (decEndpoint) {
|
||||
if (decEndpoint.newly && decEndpoint.target === '*' && !decEndpoint.untargetable) {
|
||||
decEndpoint.target = '~' + decEndpoint.pkgMeta.version;
|
||||
decEndpoint.target = '^' + decEndpoint.pkgMeta.version;
|
||||
decEndpoint.originalTarget = '*';
|
||||
}
|
||||
});
|
||||
@@ -634,7 +635,7 @@ Manager.prototype._dissect = function () {
|
||||
}, this);
|
||||
|
||||
// Filter only packages that need to be installed
|
||||
componentsDir = path.resolve(that._config.cwd, that._config.directory);
|
||||
componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
this._dissected = mout.object.filter(suitables, function (decEndpoint, name) {
|
||||
var installedMeta = this._installed[name];
|
||||
var dst;
|
||||
|
||||
@@ -13,6 +13,7 @@ var createError = require('../util/createError');
|
||||
var readJson = require('../util/readJson');
|
||||
var validLink = require('../util/validLink');
|
||||
var scripts = require('./scripts');
|
||||
var relativeToBaseDir = require('../util/relativeToBaseDir');
|
||||
|
||||
function Project(config, logger) {
|
||||
this._config = config;
|
||||
@@ -197,27 +198,6 @@ Project.prototype.update = function (names, options) {
|
||||
return that._manager.install(that._json);
|
||||
})
|
||||
.then(function (installed) {
|
||||
if (that._options.save || that._options.saveDev) {
|
||||
// Cycle through the specified endpoints
|
||||
targets.forEach(function (target) {
|
||||
// Abort if current and new version are identical
|
||||
if (target.target === target.pkgMeta.version) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var jsonEndpoint = endpointParser.decomposed2json(target);
|
||||
// Bower uses the ~ range specifier for new installs
|
||||
jsonEndpoint[target.name] = '~' + target.pkgMeta.version;
|
||||
|
||||
if (that._options.saveDev && mout.object.has(that._json, 'devDependencies.' + target.name)) {
|
||||
that._json.devDependencies = mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint);
|
||||
}
|
||||
|
||||
if (that._options.save && mout.object.has(that._json, 'dependencies.' + target.name)) {
|
||||
that._json.dependencies = mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Save JSON, might contain changes to resolutions
|
||||
return that.saveJson()
|
||||
.then(function () {
|
||||
@@ -628,7 +608,7 @@ Project.prototype._readInstalled = function () {
|
||||
|
||||
// Gather all folders that are actual packages by
|
||||
// looking for the package metadata file
|
||||
componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
return this._installed = Q.nfcall(glob, '*/.bower.json', {
|
||||
cwd: componentsDir,
|
||||
dot: true
|
||||
@@ -669,7 +649,7 @@ Project.prototype._readLinks = function () {
|
||||
var that = this;
|
||||
|
||||
// Read directory, looking for links
|
||||
componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
return Q.nfcall(fs.readdir, componentsDir)
|
||||
.then(function (filenames) {
|
||||
var promises;
|
||||
|
||||
@@ -11,7 +11,7 @@ var pluginResolverFactory = require('./resolvers/pluginResolverFactory');
|
||||
function createInstance(decEndpoint, options, registryClient) {
|
||||
decEndpoint = mout.object.pick(decEndpoint, ['name', 'target', 'source']);
|
||||
|
||||
options.version = require('../../package.json').version;
|
||||
options.version = require('../version');
|
||||
|
||||
return getConstructor(decEndpoint, options, registryClient)
|
||||
.spread(function (ConcreteResolver, decEndpoint) {
|
||||
@@ -25,7 +25,7 @@ function getConstructor(decEndpoint, options, registryClient) {
|
||||
|
||||
// Below we try a series of async tests to guess the type of resolver to use
|
||||
// If a step was unable to guess the resolver, it returns undefined
|
||||
// If a step can guess the resolver, it returns with construcotor of resolver
|
||||
// If a step can guess the resolver, it returns with constructor of resolver
|
||||
|
||||
var promise = Q.resolve();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ function GitResolver(decEndpoint, config, logger) {
|
||||
// anyway
|
||||
mkdirp.sync(config.storage.empty);
|
||||
process.env.GIT_TEMPLATE_DIR = config.storage.empty;
|
||||
process.env.GIT_SSL_NO_VERIFY = (!config.strictSsl).toString();
|
||||
|
||||
Resolver.call(this, decEndpoint, config, logger);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var commands = require('./commands');
|
||||
var pkg = require('../package.json');
|
||||
var version = require('./version');
|
||||
var abbreviations = require('./abbreviations')(commands);
|
||||
|
||||
function clearRuntimeCache() {
|
||||
@@ -11,7 +11,7 @@ function clearRuntimeCache() {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
version: pkg.version,
|
||||
version: version,
|
||||
commands: commands,
|
||||
config: require('./config')(),
|
||||
abbreviations: abbreviations,
|
||||
|
||||
@@ -5,7 +5,8 @@ var archy = require('archy');
|
||||
var Q = require('q');
|
||||
var stringifyObject = require('stringify-object');
|
||||
var os = require('os');
|
||||
var pkg = require(path.join(__dirname, '../..', 'package.json'));
|
||||
var semverUtils = require('semver-utils');
|
||||
var version = require('../version');
|
||||
var template = require('../util/template');
|
||||
|
||||
function StandardRenderer(command, config) {
|
||||
@@ -83,7 +84,7 @@ StandardRenderer.prototype.error = function (err) {
|
||||
|
||||
// Print bower version, node version and system info.
|
||||
this._write(process.stderr, chalk.yellow('\nSystem info:\n'));
|
||||
this._write(process.stderr, 'Bower version: ' + pkg.version + '\n');
|
||||
this._write(process.stderr, 'Bower version: ' + version + '\n');
|
||||
this._write(process.stderr, 'Node version: ' + process.versions.node + '\n');
|
||||
this._write(process.stderr, 'OS: ' + os.type() + ' ' + os.release() + ' ' + os.arch() + '\n');
|
||||
}
|
||||
@@ -209,6 +210,19 @@ StandardRenderer.prototype._info = function (data) {
|
||||
|
||||
// Render the versions at the end
|
||||
if (includeVersions) {
|
||||
data.hidePreReleases = false;
|
||||
data.numPreReleases = 0;
|
||||
// If output isn't verbose, hide prereleases
|
||||
if (!this._config.verbose) {
|
||||
data.versions = mout.array.filter(data.versions, function(version) {
|
||||
version = semverUtils.parse(version);
|
||||
if (!version.release && !version.build) {
|
||||
return true;
|
||||
}
|
||||
data.numPreReleases++;
|
||||
});
|
||||
data.hidePreReleases = !!data.numPreReleases;
|
||||
}
|
||||
str += '\n' + template.render('std/info.std', data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
var Q = require('q');
|
||||
var mout = require('mout');
|
||||
|
||||
var analytics = module.exports;
|
||||
|
||||
var insight;
|
||||
|
||||
var enableAnalytics = false;
|
||||
|
||||
// Insight takes long to load, and often causes problems
|
||||
// in non-interactive environment, so we load it lazily
|
||||
//
|
||||
// Insight is used in two cases:
|
||||
//
|
||||
// 1. Read insight configuration (whether track user actions)
|
||||
// 2. Track user actions (Tracker.track method)
|
||||
//
|
||||
// We don't want to instantiate Insight in non-interactive mode
|
||||
// because it takes time to read config and configstore has concurrency issues:
|
||||
//
|
||||
// https://github.com/yeoman/configstore/issues/20
|
||||
|
||||
function ensureInsight () {
|
||||
if (!insight) {
|
||||
var Insight = require('insight');
|
||||
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
insight = new Insight({
|
||||
trackingCode: 'UA-00000000-0',
|
||||
pkg: {
|
||||
name: 'bower-test',
|
||||
version: '1.0.0'
|
||||
}
|
||||
});
|
||||
|
||||
insight.config.clear();
|
||||
} else {
|
||||
insight = new Insight({
|
||||
trackingCode: 'UA-43531210-1',
|
||||
pkg: require('../../package.json')
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initializes the application-wide insight singleton and asks for the
|
||||
// permission on the CLI during the first run.
|
||||
//
|
||||
// This method is called only from bin/bower. Programmatic API skips it.
|
||||
analytics.setup = function setup (config) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
// No need for asking if analytics is set in bower config
|
||||
if (config.analytics === undefined) {
|
||||
ensureInsight();
|
||||
|
||||
// For non-interactive call from bin/bower we disable analytics
|
||||
if (config.interactive) {
|
||||
if (insight.optOut !== undefined) {
|
||||
deferred.resolve(!insight.optOut);
|
||||
} else {
|
||||
insight.askPermission(null, function(err, optIn) {
|
||||
// optIn callback param was exactly opposite before 0.4.3
|
||||
// so we force at least insight@0.4.3 in package.json
|
||||
deferred.resolve(optIn);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// no specified value, no stored value, and can't prompt for one
|
||||
// most likely CI environment; defaults to false to reduce data noise
|
||||
deferred.resolve(false);
|
||||
}
|
||||
} else {
|
||||
// use the specified value
|
||||
deferred.resolve(config.analytics);
|
||||
}
|
||||
|
||||
return deferred.promise.then(function (enabled) {
|
||||
enableAnalytics = enabled;
|
||||
|
||||
return enabled;
|
||||
});
|
||||
};
|
||||
|
||||
var Tracker = analytics.Tracker = function Tracker (config) {
|
||||
function analyticsEnabled () {
|
||||
// Allow for overriding analytics default
|
||||
if (config && config.analytics !== undefined) {
|
||||
return config.analytics;
|
||||
}
|
||||
|
||||
// TODO: let bower pass this variable from bin/bower instead closure
|
||||
return enableAnalytics;
|
||||
}
|
||||
|
||||
if (analyticsEnabled()) {
|
||||
ensureInsight();
|
||||
} else {
|
||||
this.track = function noop () {};
|
||||
this.trackDecomposedEndpoints = function noop () {};
|
||||
this.trackPackages = function noop () {};
|
||||
this.trackNames = function noop () {};
|
||||
}
|
||||
};
|
||||
|
||||
Tracker.prototype.track = function track () {
|
||||
insight.track.apply(insight, arguments);
|
||||
};
|
||||
|
||||
Tracker.prototype.trackDecomposedEndpoints = function trackDecomposedEndpoints (command, endpoints) {
|
||||
endpoints.forEach(function (endpoint) {
|
||||
this.track(command, endpoint.source, endpoint.target);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Tracker.prototype.trackPackages = function trackPackages (command, packages) {
|
||||
mout.object.forOwn(packages, function (_package) {
|
||||
var meta = _package.pkgMeta;
|
||||
this.track(command, meta.name, meta.version);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
Tracker.prototype.trackNames = function trackNames (command, names) {
|
||||
names.forEach(function (name) {
|
||||
this.track(command, name);
|
||||
}.bind(this));
|
||||
};
|
||||
@@ -1,6 +1,9 @@
|
||||
var mout = require('mout');
|
||||
var nopt = require('nopt');
|
||||
var renderers = require('../renderers');
|
||||
var createError = require('./createError');
|
||||
|
||||
var READ_OPTIONS_ERROR_CODE = 'EREADOPTIONS';
|
||||
|
||||
function readOptions(options, argv) {
|
||||
var types;
|
||||
@@ -37,6 +40,16 @@ function readOptions(options, argv) {
|
||||
return parsedOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an error for the case where a command has trouble parsing command
|
||||
* line options.
|
||||
**/
|
||||
function createReadOptionsError(commandName) {
|
||||
var errorString = commandName + ' syntax error';
|
||||
|
||||
return createError(errorString, READ_OPTIONS_ERROR_CODE);
|
||||
}
|
||||
|
||||
function getRenderer(command, json, config) {
|
||||
if (config.json || json) {
|
||||
return new renderers.Json(command, config);
|
||||
@@ -47,3 +60,6 @@ function getRenderer(command, json, config) {
|
||||
|
||||
module.exports.readOptions = readOptions;
|
||||
module.exports.getRenderer = getRenderer;
|
||||
|
||||
module.exports.createReadOptionsError = createReadOptionsError;
|
||||
module.exports.READ_OPTIONS_ERROR_CODE = READ_OPTIONS_ERROR_CODE;
|
||||
|
||||
@@ -26,7 +26,8 @@ function download(url, file, options) {
|
||||
minTimeout: 1000,
|
||||
maxTimeout: 35000,
|
||||
randomize: true,
|
||||
progressDelay: progressDelay
|
||||
progressDelay: progressDelay,
|
||||
gzip: true
|
||||
}, options || {});
|
||||
|
||||
// Retry on network errors
|
||||
|
||||
@@ -9,6 +9,7 @@ var junk = require('junk');
|
||||
var createError = require('./createError');
|
||||
var createWriteStream = require('fs-write-stream-atomic');
|
||||
var destroy = require('destroy');
|
||||
var tmp = require('tmp');
|
||||
|
||||
// This forces the default chunk size to something small in an attempt
|
||||
// to avoid issue #314
|
||||
@@ -164,15 +165,11 @@ function isSingleDir(dir) {
|
||||
});
|
||||
}
|
||||
|
||||
function moveSingleDirContents(dir) {
|
||||
var destDir = path.dirname(dir);
|
||||
|
||||
return Q.nfcall(fs.readdir, dir)
|
||||
.then(function (files) {
|
||||
var promises;
|
||||
|
||||
promises = files.map(function (file) {
|
||||
var src = path.join(dir, file);
|
||||
function moveDirectory(srcDir, destDir) {
|
||||
return Q.nfcall(fs.readdir, srcDir)
|
||||
.then(function(files) {
|
||||
var promises = files.map(function (file) {
|
||||
var src = path.join(srcDir, file);
|
||||
var dst = path.join(destDir, file);
|
||||
|
||||
return Q.nfcall(fs.rename, src, dst);
|
||||
@@ -181,7 +178,7 @@ function moveSingleDirContents(dir) {
|
||||
return Q.all(promises);
|
||||
})
|
||||
.then(function () {
|
||||
return Q.nfcall(fs.rmdir, dir);
|
||||
return Q.nfcall(fs.rmdir, srcDir);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -215,44 +212,53 @@ function extract(src, dst, opts) {
|
||||
return Q.reject(createError('File ' + src + ' is not a known archive', 'ENOTARCHIVE'));
|
||||
}
|
||||
|
||||
// Check archive file size
|
||||
promise = Q.nfcall(fs.stat, src)
|
||||
.then(function (stat) {
|
||||
if (stat.size <= 8) {
|
||||
throw createError('File ' + src + ' is an invalid archive', 'ENOTARCHIVE');
|
||||
// Extract to a temporary directory in case of file name clashes
|
||||
return Q.nfcall(tmp.dir, {
|
||||
template: dst + '-XXXXXX',
|
||||
mode: 0777 & ~process.umask()
|
||||
}).then(function (tempDir) {
|
||||
// nfcall may return multiple callback arguments as an array
|
||||
return Array.isArray(tempDir) ? tempDir[0] : tempDir;
|
||||
}).then(function (tempDir) {
|
||||
|
||||
// Check archive file size
|
||||
promise = Q.nfcall(fs.stat, src)
|
||||
.then(function (stat) {
|
||||
if (stat.size <= 8) {
|
||||
throw createError('File ' + src + ' is an invalid archive', 'ENOTARCHIVE');
|
||||
}
|
||||
|
||||
// Extract archive
|
||||
return extractor(src, tempDir);
|
||||
});
|
||||
|
||||
// Remove archive
|
||||
if (!opts.keepArchive) {
|
||||
promise = promise
|
||||
.then(function () {
|
||||
return Q.nfcall(fs.unlink, src);
|
||||
});
|
||||
}
|
||||
|
||||
// Extract archive
|
||||
return extractor(src, dst);
|
||||
});
|
||||
|
||||
// TODO: There's an issue here if the src and dst are the same and
|
||||
// The zip name is the same as some of the zip file contents
|
||||
// Maybe create a temp directory inside dst, unzip it there,
|
||||
// unlink zip and then move contents
|
||||
|
||||
// Remove archive
|
||||
if (!opts.keepArchive) {
|
||||
// Move contents from the temporary directory
|
||||
// If the contents are a single directory (and we're not preserving structure),
|
||||
// move its contents directly instead.
|
||||
promise = promise
|
||||
.then(function () {
|
||||
return Q.nfcall(fs.unlink, src);
|
||||
});
|
||||
}
|
||||
|
||||
// Move contents if a single directory was extracted
|
||||
if (!opts.keepStructure) {
|
||||
promise = promise
|
||||
.then(function () {
|
||||
return isSingleDir(dst);
|
||||
return isSingleDir(tempDir);
|
||||
})
|
||||
.then(function (singleDir) {
|
||||
return singleDir ? moveSingleDirContents(singleDir) : null;
|
||||
if (singleDir && !opts.keepStructure) {
|
||||
return moveDirectory(singleDir, dst);
|
||||
} else {
|
||||
return moveDirectory(tempDir, dst);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Resolve promise to the dst dir
|
||||
return promise.then(function () {
|
||||
return dst;
|
||||
// Resolve promise to the dst dir
|
||||
return promise.then(function () {
|
||||
return dst;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
5
lib/util/isPathAbsolute.js
Normal file
5
lib/util/isPathAbsolute.js
Normal file
@@ -0,0 +1,5 @@
|
||||
function isPathAbsolute(filePath) {
|
||||
return filePath.charAt(0) === '/';
|
||||
}
|
||||
|
||||
module.exports = isPathAbsolute;
|
||||
14
lib/util/relativeToBaseDir.js
Normal file
14
lib/util/relativeToBaseDir.js
Normal file
@@ -0,0 +1,14 @@
|
||||
var path = require('path');
|
||||
var isPathAbsolute = require('./isPathAbsolute');
|
||||
|
||||
function relativeToBaseDir(baseDir) {
|
||||
return function(filePath) {
|
||||
if(isPathAbsolute(filePath)) {
|
||||
return path.resolve(filePath);
|
||||
} else {
|
||||
return path.resolve(baseDir, filePath);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = relativeToBaseDir;
|
||||
@@ -1,3 +1,3 @@
|
||||
var pkg = require('../../package.json');
|
||||
var version = require('../version');
|
||||
|
||||
module.exports = 'node/' + process.version + ' ' + process.platform + ' ' + process.arch + ' ' + ';Bower ' + pkg.version;
|
||||
module.exports = 'node/' + process.version + ' ' + process.platform + ' ' + process.arch + ' ' + ';Bower ' + version;
|
||||
|
||||
3
lib/version.js
Normal file
3
lib/version.js
Normal file
@@ -0,0 +1,3 @@
|
||||
var findup = require('findup-sync');
|
||||
|
||||
module.exports = require(findup('package.json', { cwd: __dirname })).version;
|
||||
82
package.json
82
package.json
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"name": "bower",
|
||||
"version": "1.6.8",
|
||||
"version": "1.7.3",
|
||||
"description": "The browser package manager",
|
||||
"author": "Twitter",
|
||||
"license": "MIT",
|
||||
"repository": "bower/bower",
|
||||
"main": "lib",
|
||||
"bin": "bin/bower",
|
||||
"homepage": "http://bower.io",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -16,7 +17,7 @@
|
||||
"dependencies": {
|
||||
"abbrev": "^1.0.5",
|
||||
"archy": "1.0.0",
|
||||
"bower-config": "^1.2.3",
|
||||
"bower-config": "^1.3.0",
|
||||
"bower-endpoint-parser": "^0.2.2",
|
||||
"bower-json": "^0.4.0",
|
||||
"bower-logger": "^0.2.2",
|
||||
@@ -27,7 +28,8 @@
|
||||
"configstore": "^0.3.2",
|
||||
"decompress-zip": "^0.1.0",
|
||||
"destroy": "^1.0.3",
|
||||
"fs-write-stream-atomic": "^1.0.4",
|
||||
"findup-sync": "^0.3.0",
|
||||
"fs-write-stream-atomic": "1.0.8",
|
||||
"fstream": "^1.0.3",
|
||||
"fstream-ignore": "^1.0.2",
|
||||
"github": "^0.2.3",
|
||||
@@ -35,7 +37,6 @@
|
||||
"graceful-fs": "^3.0.5",
|
||||
"handlebars": "^2.0.0",
|
||||
"inquirer": "0.10.0",
|
||||
"insight": "^0.7.0",
|
||||
"is-root": "^1.0.0",
|
||||
"junk": "^1.0.0",
|
||||
"lockfile": "^1.0.0",
|
||||
@@ -48,20 +49,22 @@
|
||||
"p-throttler": "0.1.1",
|
||||
"promptly": "0.2.0",
|
||||
"q": "^1.1.2",
|
||||
"request": "2.53.0",
|
||||
"request": "2.67.0",
|
||||
"request-progress": "0.3.1",
|
||||
"retry": "0.6.1",
|
||||
"rimraf": "^2.2.8",
|
||||
"semver": "^2.3.0",
|
||||
"semver-utils": "^1.1.1",
|
||||
"shell-quote": "^1.4.2",
|
||||
"stringify-object": "^1.0.0",
|
||||
"tar-fs": "^1.4.1",
|
||||
"tmp": "0.0.24",
|
||||
"update-notifier": "^0.3.0",
|
||||
"tmp": "0.0.28",
|
||||
"update-notifier": "^0.6.0",
|
||||
"user-home": "^1.1.0",
|
||||
"which": "^1.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"arr-diff": "^2.0.0",
|
||||
"chai": "^1.10.0",
|
||||
"coveralls": "^2.11.2",
|
||||
"expect.js": "^0.3.1",
|
||||
@@ -72,6 +75,7 @@
|
||||
"grunt-exec": "^0.4.6",
|
||||
"grunt-jscs": "^2.3.0",
|
||||
"grunt-simple-mocha": "^0.4.0",
|
||||
"in-publish": "^2.0.0",
|
||||
"istanbul": "^0.3.5",
|
||||
"load-grunt-tasks": "^2.0.0",
|
||||
"mocha": "^2.1.0",
|
||||
@@ -79,63 +83,13 @@
|
||||
"nock": "^3.1.0",
|
||||
"node-uuid": "^1.4.2",
|
||||
"proxyquire": "^1.3.0",
|
||||
"spawn-sync": "1.0.13"
|
||||
"spawn-sync": "1.0.13",
|
||||
"wrench": "^1.5.8"
|
||||
},
|
||||
"bundledDependencies": [
|
||||
"abbrev",
|
||||
"archy",
|
||||
"bower-config",
|
||||
"bower-endpoint-parser",
|
||||
"bower-json",
|
||||
"bower-logger",
|
||||
"bower-registry-client",
|
||||
"cardinal",
|
||||
"chalk",
|
||||
"chmodr",
|
||||
"configstore",
|
||||
"decompress-zip",
|
||||
"destroy",
|
||||
"fs-write-stream-atomic",
|
||||
"fstream",
|
||||
"fstream-ignore",
|
||||
"github",
|
||||
"glob",
|
||||
"graceful-fs",
|
||||
"handlebars",
|
||||
"inquirer",
|
||||
"insight",
|
||||
"is-root",
|
||||
"junk",
|
||||
"lockfile",
|
||||
"lru-cache",
|
||||
"md5-hex",
|
||||
"mkdirp",
|
||||
"mout",
|
||||
"nopt",
|
||||
"opn",
|
||||
"p-throttler",
|
||||
"promptly",
|
||||
"q",
|
||||
"request",
|
||||
"request-progress",
|
||||
"retry",
|
||||
"rimraf",
|
||||
"semver",
|
||||
"shell-quote",
|
||||
"stringify-object",
|
||||
"tar-fs",
|
||||
"tmp",
|
||||
"update-notifier",
|
||||
"user-home",
|
||||
"which"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "grunt test"
|
||||
},
|
||||
"bin": "bin/bower",
|
||||
"files": [
|
||||
"bin",
|
||||
"lib",
|
||||
"templates"
|
||||
]
|
||||
"test": "grunt test",
|
||||
"ci": "grunt travis",
|
||||
"coveralls": "coveralls",
|
||||
"prepublish": "in-publish && echo 'You need to use \"grunt publush\" to publish bower' && false || not-in-publish"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
"flag": "--force-latest",
|
||||
"description": "Force latest version on conflict"
|
||||
},
|
||||
{
|
||||
"shorthand": "-f",
|
||||
"flag": "--force",
|
||||
"description": "If dependencies are installed, it reinstalls all installed components. It also forces installation even when there are non-bower directories with the same name in the components directory. Also bypasses the cache and overwrites to the cache anyway."
|
||||
},
|
||||
{
|
||||
"shorthand": "-h",
|
||||
"flag": "--help",
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
"register <name> <url> [<options>]"
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"shorthand": "-f",
|
||||
"flag": "--force",
|
||||
"description": "Bypasses confirmation. Bower login is still needed."
|
||||
},
|
||||
{
|
||||
"shorthand": "-h",
|
||||
"flag": "--help",
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"command": "search",
|
||||
"description": "Finds all packages or a specific package.",
|
||||
"usage": [
|
||||
"search [<options>]",
|
||||
"search <name> [<options>]"
|
||||
],
|
||||
"options": [
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
"uninstall <name> [<name> ..] [<options>]"
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"shorthand": "-f",
|
||||
"flag": "--force",
|
||||
"description": "Continues uninstallation even after a dependency conflict"
|
||||
},
|
||||
{
|
||||
"shorthand": "-h",
|
||||
"flag": "--help",
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
"unregister <name> [<options>]"
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"shorthand": "-f",
|
||||
"flag": "--force",
|
||||
"description": "Bypasses confirmation. Bower login is still needed."
|
||||
},
|
||||
{
|
||||
"shorthand": "-h",
|
||||
"flag": "--help",
|
||||
|
||||
@@ -19,6 +19,16 @@
|
||||
"shorthand": "-p",
|
||||
"flag": "--production",
|
||||
"description": "Do not install project devDependencies"
|
||||
},
|
||||
{
|
||||
"shorthand": "-S",
|
||||
"flag": "--save",
|
||||
"description": "Update dependencies in bower.json"
|
||||
},
|
||||
{
|
||||
"shorthand": "-D",
|
||||
"flag": "--save-dev",
|
||||
"description": "Update devDependencies in bower.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
},
|
||||
{
|
||||
"shorthand": "-l",
|
||||
"flag": "--log-level",
|
||||
"flag": "--loglevel",
|
||||
"description": "What level of logs to report"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ Usage:
|
||||
{{/each}}
|
||||
{{/condense}}
|
||||
|
||||
|
||||
Options:
|
||||
|
||||
{{#condense}}
|
||||
@@ -20,3 +21,4 @@ Options:
|
||||
Description:
|
||||
|
||||
{{#indent level="4"}}{{description}}{{/indent}}
|
||||
|
||||
|
||||
@@ -24,3 +24,4 @@ Options:
|
||||
{{/condense}}
|
||||
|
||||
See 'bower help <command>' for more information on a specific command.
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
{{/versions}}
|
||||
{{/condense}}
|
||||
|
||||
|
||||
{{#if hidePreReleases}}
|
||||
Show {{numPreReleases}} additional prereleases with ‘bower info {{name}} --verbose’
|
||||
{{/if}}
|
||||
You can request info for a specific version with 'bower info {{name}}#<version>'
|
||||
{{else}}No versions available.
|
||||
{{/if}}
|
||||
BIN
test/assets/package-tar.tar
Normal file
BIN
test/assets/package-tar.tar
Normal file
Binary file not shown.
BIN
test/assets/test-gz.txt
Normal file
BIN
test/assets/test-gz.txt
Normal file
Binary file not shown.
BIN
test/assets/test-gz.txt.gz
Normal file
BIN
test/assets/test-gz.txt.gz
Normal file
Binary file not shown.
@@ -1,36 +1,47 @@
|
||||
var expect = require('expect.js');
|
||||
var path = require('path');
|
||||
var helpers = require('../helpers');
|
||||
var nock = require('nock');
|
||||
var rimraf = require('rimraf');
|
||||
var fs = require('../../lib/util/fs');
|
||||
var tar = require('tar-fs');
|
||||
var destroy = require('destroy');
|
||||
var Q = require('q');
|
||||
|
||||
describe('bower install', function () {
|
||||
describe('bower install', function() {
|
||||
|
||||
var tempDir = new helpers.TempDir();
|
||||
|
||||
var install = helpers.command('install', { cwd: tempDir.path });
|
||||
var install = helpers.command('install', {
|
||||
cwd: tempDir.path
|
||||
});
|
||||
|
||||
it('correctly reads arguments', function() {
|
||||
expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D', '-E']))
|
||||
.to.eql([['jquery', 'angular'], {
|
||||
forceLatest: true,
|
||||
production: true,
|
||||
save: true,
|
||||
saveDev: true,
|
||||
saveExact: true
|
||||
}]);
|
||||
.to.eql([
|
||||
['jquery', 'angular'], {
|
||||
forceLatest: true,
|
||||
production: true,
|
||||
save: true,
|
||||
saveDev: true,
|
||||
saveExact: true
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it('correctly reads long arguments', function() {
|
||||
expect(install.readOptions([
|
||||
'jquery', 'angular',
|
||||
'--force-latest', '--production', '--save', '--save-dev', '--save-exact'
|
||||
])).to.eql([['jquery', 'angular'], {
|
||||
forceLatest: true,
|
||||
production: true,
|
||||
save: true,
|
||||
saveDev: true,
|
||||
saveExact: true
|
||||
}]);
|
||||
'jquery', 'angular',
|
||||
'--force-latest', '--production', '--save', '--save-dev', '--save-exact'
|
||||
])).to.eql([
|
||||
['jquery', 'angular'], {
|
||||
forceLatest: true,
|
||||
production: true,
|
||||
save: true,
|
||||
saveDev: true,
|
||||
saveExact: true
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
var mainPackage = new helpers.TempDir({
|
||||
@@ -41,7 +52,22 @@ describe('bower install', function () {
|
||||
|
||||
var gitPackage = new helpers.TempDir();
|
||||
|
||||
it('writes to bower.json if --save flag is used', function () {
|
||||
gitPackage.prepareGit({
|
||||
'1.0.0': {
|
||||
'bower.json': {
|
||||
name: 'package'
|
||||
},
|
||||
'version.txt': '1.0.0'
|
||||
},
|
||||
'1.0.1': {
|
||||
'bower.json': {
|
||||
name: 'package'
|
||||
},
|
||||
'version.txt': '1.0.1'
|
||||
}
|
||||
});
|
||||
|
||||
it('writes to bower.json if --save flag is used', function() {
|
||||
mainPackage.prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -50,12 +76,16 @@ describe('bower install', function () {
|
||||
}
|
||||
});
|
||||
|
||||
return helpers.run(install, [[mainPackage.path], { save: true }]).then(function() {
|
||||
return helpers.run(install, [
|
||||
[mainPackage.path], {
|
||||
save: true
|
||||
}
|
||||
]).then(function() {
|
||||
expect(tempDir.read('bower.json')).to.contain('dependencies');
|
||||
});
|
||||
});
|
||||
|
||||
it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () {
|
||||
it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function() {
|
||||
mainPackage.prepare({
|
||||
'bower.json': {
|
||||
name: 'package',
|
||||
@@ -70,14 +100,16 @@ describe('bower install', function () {
|
||||
});
|
||||
|
||||
return helpers.run(install, [
|
||||
[mainPackage.path],
|
||||
{ saveExact: true, save: true }
|
||||
]).then(function() {
|
||||
expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3');
|
||||
});
|
||||
[mainPackage.path], {
|
||||
saveExact: true,
|
||||
save: true
|
||||
}
|
||||
]).then(function() {
|
||||
expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3');
|
||||
});
|
||||
});
|
||||
|
||||
it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () {
|
||||
it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function() {
|
||||
mainPackage.prepare({
|
||||
'bower.json': {
|
||||
name: 'package',
|
||||
@@ -92,18 +124,24 @@ describe('bower install', function () {
|
||||
});
|
||||
|
||||
return helpers.run(install, [
|
||||
[mainPackage.path],
|
||||
{ saveExact: true, saveDev: true }
|
||||
]).then(function() {
|
||||
expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0');
|
||||
});
|
||||
[mainPackage.path], {
|
||||
saveExact: true,
|
||||
saveDev: true
|
||||
}
|
||||
]).then(function() {
|
||||
expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0');
|
||||
});
|
||||
});
|
||||
|
||||
it('reads .bowerrc from cwd', function () {
|
||||
mainPackage.prepare({ foo: 'bar' });
|
||||
it('reads .bowerrc from cwd', function() {
|
||||
mainPackage.prepare({
|
||||
foo: 'bar'
|
||||
});
|
||||
|
||||
tempDir.prepare({
|
||||
'.bowerrc': { directory: 'assets' },
|
||||
'.bowerrc': {
|
||||
directory: 'assets'
|
||||
},
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
@@ -117,7 +155,38 @@ describe('bower install', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('runs preinstall hook', function () {
|
||||
it('.bowerrc directory can be an absolute path', function() {
|
||||
mainPackage.prepare({
|
||||
foo: 'bar'
|
||||
});
|
||||
|
||||
tempDir.prepare({
|
||||
'.bowerrc': {
|
||||
directory: '/tmp/bower-absolute-destination-directory'
|
||||
},
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
package: mainPackage.path
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return helpers.run(install).then(function() {
|
||||
expect(require('fs').readFileSync('/tmp/bower-absolute-destination-directory/package/foo', 'utf8').toString()).to.be('bar');
|
||||
var deferred = Q.defer();
|
||||
rimraf('/tmp/bower-absolute-destination-directory', function(err) {
|
||||
if(err) {
|
||||
deferred.reject(err);
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
return deferred;
|
||||
});
|
||||
});
|
||||
|
||||
it('runs preinstall hook', function() {
|
||||
mainPackage.prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -139,7 +208,7 @@ describe('bower install', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('runs preinstall hook', function () {
|
||||
it('runs postinstall hook', function() {
|
||||
mainPackage.prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -162,7 +231,7 @@ describe('bower install', function () {
|
||||
});
|
||||
|
||||
// To be discussed, but that's the implementation now
|
||||
it('does not run hooks if nothing is installed', function () {
|
||||
it('does not run hooks if nothing is installed', function() {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test'
|
||||
@@ -180,7 +249,7 @@ describe('bower install', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('runs postinstall after bower.json is written', function () {
|
||||
it('runs postinstall after bower.json is written', function() {
|
||||
mainPackage.prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -194,12 +263,16 @@ describe('bower install', function () {
|
||||
}
|
||||
});
|
||||
|
||||
return helpers.run(install, [[mainPackage.path], { save: true }]).then(function() {
|
||||
return helpers.run(install, [
|
||||
[mainPackage.path], {
|
||||
save: true
|
||||
}
|
||||
]).then(function() {
|
||||
expect(tempDir.read('hook.txt')).to.contain('dependencies');
|
||||
});
|
||||
});
|
||||
|
||||
it('display the output of hook scripts', function (next) {
|
||||
it('display the output of hook scripts', function(next) {
|
||||
mainPackage.prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -217,37 +290,36 @@ describe('bower install', function () {
|
||||
});
|
||||
var lastAction = null;
|
||||
|
||||
helpers.run(install).logger.intercept(function (log) {
|
||||
helpers.run(install).logger.intercept(function(log) {
|
||||
if (log.level === 'action') {
|
||||
lastAction = log;
|
||||
}
|
||||
}).on('end', function () {
|
||||
}).on('end', function() {
|
||||
expect(lastAction.message).to.be('foobar');
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
it('skips components not installed by bower', function () {
|
||||
mainPackage.prepare({
|
||||
'.git': {} //Make a dummy file instead of using slower gitPrepare()
|
||||
});
|
||||
it('skips components not installed by bower', function() {
|
||||
mainPackage.prepare({
|
||||
'.git': {} //Make a dummy file instead of using slower gitPrepare()
|
||||
});
|
||||
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
package: mainPackage.path
|
||||
}
|
||||
}
|
||||
});
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
package: mainPackage.path
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return helpers.run(install).then(function() {
|
||||
var packageFiles = fs.readdirSync(mainPackage.path);
|
||||
//presence of .git file implies folder was not overwritten
|
||||
expect(packageFiles).to.contain('.git');
|
||||
});
|
||||
|
||||
});
|
||||
return helpers.run(install).then(function() {
|
||||
var packageFiles = fs.readdirSync(mainPackage.path);
|
||||
//presence of .git file implies folder was not overwritten
|
||||
expect(packageFiles).to.contain('.git');
|
||||
});
|
||||
});
|
||||
|
||||
it('works for git repositories', function () {
|
||||
gitPackage.prepareGit({
|
||||
@@ -279,6 +351,22 @@ describe('bower install', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('works for dependencies that point to tar files', function() {
|
||||
var packageDir = path.join(__dirname, '../assets/package-tar.tar');
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
package: packageDir
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return helpers.run(install).then(function() {
|
||||
expect(tempDir.read('bower_components/package/index.txt')).to.contain('1.0.0');
|
||||
});
|
||||
});
|
||||
|
||||
it('does not install ignored dependencies', function() {
|
||||
mainPackage.prepare();
|
||||
var package2 = new helpers.TempDir({
|
||||
@@ -313,7 +401,6 @@ describe('bower install', function () {
|
||||
expect(tempDir.exists('bower_components/package')).to.be(false);
|
||||
expect(tempDir.exists('bower_components/package2')).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('does not install ignored dependencies if run multiple times', function() {
|
||||
@@ -351,10 +438,9 @@ describe('bower install', function () {
|
||||
expect(tempDir.exists('bower_components/package2')).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('recognizes proxy option in config', function (done) {
|
||||
it('recognizes proxy option in config', function(done) {
|
||||
this.timeout(10000);
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -371,22 +457,21 @@ describe('bower install', function () {
|
||||
});
|
||||
|
||||
nock('http://dummy.local')
|
||||
.get('http://github.com/yahoo/pure/archive/v0.6.0.tar.gz')
|
||||
.reply(500);
|
||||
.get('http://github.com/yahoo/pure/archive/v0.6.0.tar.gz')
|
||||
.reply(500);
|
||||
|
||||
return helpers.run(install, [
|
||||
undefined,
|
||||
undefined,
|
||||
{ proxy: 'http://dummy.local/' }
|
||||
])
|
||||
.fail(function(error) {
|
||||
expect(error.message).to.equal('Status code of 500');
|
||||
done();
|
||||
});
|
||||
.fail(function(error) {
|
||||
expect(error.message).to.equal('Status code of 500');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('errors if the components directory is not a directory', function () {
|
||||
it('errors if the components directory is not a directory', function() {
|
||||
tempDir.prepare({
|
||||
'.bowerrc': {
|
||||
directory: '.bowerrc'
|
||||
@@ -397,4 +482,73 @@ describe('bower install', function () {
|
||||
expect(error.code).to.equal('ENOTDIR');
|
||||
});
|
||||
});
|
||||
|
||||
it('works if the package is a compressed single directory containing another directory with the same name', function() {
|
||||
var mainPackageBaseName = path.basename(mainPackage.path);
|
||||
var parentDir = path.dirname(mainPackage.path);
|
||||
|
||||
// Setup the main package with a directory with the same name
|
||||
var mainPackageFiles = {};
|
||||
mainPackageFiles[mainPackageBaseName + '/test.js'] = 'test';
|
||||
mainPackage.prepare(mainPackageFiles);
|
||||
|
||||
// Create an archive containing the main package
|
||||
var archiveDeferred = Q.defer();
|
||||
var archivePath = path.join(parentDir, mainPackageBaseName + '.tar');
|
||||
var stream = tar.pack(parentDir, { entries: [mainPackageBaseName] });
|
||||
stream
|
||||
.pipe(fs.createWriteStream(archivePath))
|
||||
.on('finish', function(result) {
|
||||
destroy(stream);
|
||||
archiveDeferred.resolve(result);
|
||||
});
|
||||
|
||||
//// Attempt to install the package from the archive
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test'
|
||||
}
|
||||
});
|
||||
|
||||
return archiveDeferred.promise
|
||||
.then(function() {
|
||||
return helpers.run(install, [[archivePath]]);
|
||||
})
|
||||
.then(function() {
|
||||
expect(tempDir.read(path.join('bower_components', 'package', mainPackageBaseName, 'test.js'))).to.contain('test');
|
||||
});
|
||||
});
|
||||
|
||||
it('works if the package is an archive containing a file with an identical name', function() {
|
||||
var parentDir = path.dirname(mainPackage.path);
|
||||
|
||||
mainPackage.prepare({
|
||||
'package.tar': 'test'
|
||||
});
|
||||
|
||||
var archiveDeferred = Q.defer();
|
||||
var archivePath = path.join(parentDir, 'package.tar');
|
||||
var stream = tar.pack(mainPackage.path);
|
||||
stream
|
||||
.pipe(fs.createWriteStream(archivePath))
|
||||
.on('finish', function(result) {
|
||||
destroy(stream);
|
||||
archiveDeferred.resolve(result);
|
||||
});
|
||||
|
||||
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test'
|
||||
}
|
||||
});
|
||||
|
||||
return archiveDeferred.promise
|
||||
.then(function() {
|
||||
return helpers.run(install, [[archivePath]]);
|
||||
})
|
||||
.then(function() {
|
||||
expect(tempDir.read(path.join('bower_components', 'package', 'package.tar'))).to.contain('test');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var path = require('path');
|
||||
var expect = require('expect.js');
|
||||
var helpers = require('../helpers');
|
||||
|
||||
@@ -69,6 +70,55 @@ describe('bower link', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('creates inter-link to relative config.directory', function () {
|
||||
return helpers.run(link, [undefined, undefined,
|
||||
{
|
||||
cwd: mainPackage.path,
|
||||
storage: {
|
||||
links: linksDir.path
|
||||
}
|
||||
}
|
||||
]).then(function () {
|
||||
return helpers.run(link, ['package', undefined,
|
||||
{
|
||||
cwd: otherPackage.path,
|
||||
directory: 'valid-extend',
|
||||
storage: {
|
||||
links: linksDir.path
|
||||
}
|
||||
}
|
||||
]);
|
||||
}).then(function() {
|
||||
expect(otherPackage.read('valid-extend/package/index.js'))
|
||||
.to.be('Hello World!');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('creates inter-link to absolute config.directory', function () {
|
||||
return helpers.run(link, [undefined, undefined,
|
||||
{
|
||||
cwd: mainPackage.path,
|
||||
storage: {
|
||||
links: linksDir.path
|
||||
}
|
||||
}
|
||||
]).then(function () {
|
||||
return helpers.run(link, ['package', undefined,
|
||||
{
|
||||
cwd: path.join(otherPackage.path, 'invalid'),
|
||||
directory: path.join(otherPackage.path, 'valid-override'),
|
||||
storage: {
|
||||
links: linksDir.path
|
||||
}
|
||||
}
|
||||
]);
|
||||
}).then(function() {
|
||||
expect(otherPackage.read('valid-override/package/index.js'))
|
||||
.to.be('Hello World!');
|
||||
});
|
||||
});
|
||||
|
||||
it('creates inter-link with custom local name', function () {
|
||||
return helpers.run(link, [undefined, undefined,
|
||||
{
|
||||
|
||||
@@ -27,7 +27,9 @@ describe('bower search', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('lists all repositories if no query given', function () {
|
||||
it('lists all repositories when no query given in non-interactive mode', function () {
|
||||
var nonInteractiveConfig = { interactive: false };
|
||||
|
||||
return Q.Promise(function(resolve) {
|
||||
var search = helpers.command('search', {
|
||||
'bower-registry-client': function() {
|
||||
@@ -37,8 +39,45 @@ describe('bower search', function () {
|
||||
}
|
||||
});
|
||||
|
||||
helpers.run(search, [], {});
|
||||
helpers.run(search, [null, nonInteractiveConfig]);
|
||||
});
|
||||
});
|
||||
|
||||
it('lists all repositories when no query given and config.json is enabled in interactive mode', function () {
|
||||
var interactiveConfig = { interactive: true, json: true };
|
||||
|
||||
var search = helpers.command('search', {
|
||||
'bower-registry-client': function() {
|
||||
return {
|
||||
list: function (cb) { return cb(null, 'foobar'); }
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return helpers.run(search, [null, interactiveConfig])
|
||||
.spread(function(result) {
|
||||
expect(result).to.be('foobar');
|
||||
});
|
||||
});
|
||||
|
||||
it('does not list any repositories in interactive mode if no query given and config.json is disabled', function () {
|
||||
var interactiveConfig = { interactive: true };
|
||||
|
||||
var search = helpers.command('search', {
|
||||
'bower-registry-client': function() {
|
||||
return {
|
||||
list: function() { throw 'list called'; },
|
||||
search: function() { throw 'search called'; }
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return helpers.run(search, [null, interactiveConfig])
|
||||
.then(function(commandResult) {
|
||||
expect().fail('should fail');
|
||||
})
|
||||
.catch(function(e) {
|
||||
expect(e.code).to.be('EREADOPTIONS');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var expect = require('expect.js');
|
||||
var fs = require('../../lib/util/fs');
|
||||
|
||||
@@ -53,4 +54,38 @@ describe('bower uninstall', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('removes dependency from relative config.directory', function () {
|
||||
var targetPath = path.resolve(tempDir.path, 'other_directory/underscore');
|
||||
mkdirp.sync(targetPath);
|
||||
fs.writeFileSync(path.join(targetPath, '.bower.json'), '{ "name": "underscore" }');
|
||||
|
||||
return helpers.run(uninstall, [['underscore'], undefined, {
|
||||
cwd: tempDir.path,
|
||||
directory: 'other_directory',
|
||||
interactive: true
|
||||
}])
|
||||
.then(function() {
|
||||
expect(function() {
|
||||
fs.statSync(targetPath);
|
||||
}).to.throwException(/no such file or directory/);
|
||||
});
|
||||
});
|
||||
|
||||
it('removes dependency from absolute config.directory', function () {
|
||||
var targetPath = path.resolve(tempDir.path, 'other_directory/underscore');
|
||||
mkdirp.sync(targetPath);
|
||||
fs.writeFileSync(path.join(targetPath, '.bower.json'), '{ "name": "underscore" }');
|
||||
|
||||
return helpers.run(uninstall, [['underscore'], undefined, {
|
||||
cwd: tempDir.path,
|
||||
directory: path.resolve(tempDir.path, 'other_directory'),
|
||||
interactive: true
|
||||
}])
|
||||
.then(function() {
|
||||
expect(function() {
|
||||
fs.statSync(targetPath);
|
||||
}).to.throwException(/no such file or directory/);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
var expect = require('expect.js');
|
||||
var object = require('mout').object;
|
||||
var semver = require('semver');
|
||||
|
||||
var helpers = require('../helpers');
|
||||
var updateCmd = helpers.command('update');
|
||||
@@ -8,6 +7,7 @@ var commands = helpers.require('lib/index').commands;
|
||||
|
||||
describe('bower update', function () {
|
||||
this.timeout(10000);
|
||||
|
||||
var tempDir = new helpers.TempDir();
|
||||
|
||||
var subPackage = new helpers.TempDir({
|
||||
@@ -42,14 +42,16 @@ describe('bower update', function () {
|
||||
}
|
||||
}).prepare();
|
||||
|
||||
var update = function(packages, options, config) {
|
||||
var updateLogger = function(packages, options, config) {
|
||||
config = object.merge(config || {}, {
|
||||
cwd: tempDir.path
|
||||
});
|
||||
|
||||
var logger = commands.update(
|
||||
packages, options, config
|
||||
);
|
||||
return commands.update(packages, options, config);
|
||||
};
|
||||
|
||||
var update = function(packages, options, config) {
|
||||
var logger = updateLogger(packages, options, config);
|
||||
|
||||
return helpers.expectEvent(logger, 'end');
|
||||
};
|
||||
@@ -67,16 +69,11 @@ describe('bower update', function () {
|
||||
};
|
||||
|
||||
it('correctly reads arguments', function() {
|
||||
expect(updateCmd.readOptions(['jquery', '-F', '-p', '-S', '-D']))
|
||||
.to.eql([['jquery'], {
|
||||
forceLatest: true,
|
||||
production: true,
|
||||
save: true,
|
||||
saveDev: true
|
||||
}]);
|
||||
expect(updateCmd.readOptions(['jquery', '-F', '-p']))
|
||||
.to.eql([['jquery'], { forceLatest: true, production: true }]);
|
||||
});
|
||||
|
||||
it('install missing packages', function () {
|
||||
it('install missing packages', function() {
|
||||
mainPackage.prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -96,77 +93,76 @@ describe('bower update', function () {
|
||||
|
||||
it('does not install ignored dependencies', function() {
|
||||
var package3 = new helpers.TempDir({
|
||||
'bower.json': {
|
||||
name: 'package3'
|
||||
}
|
||||
}).prepare();
|
||||
'bower.json': {
|
||||
name: 'package3'
|
||||
}
|
||||
}).prepare();
|
||||
|
||||
var package2 = new helpers.TempDir({
|
||||
'bower.json': {
|
||||
name: 'package2',
|
||||
dependencies: {
|
||||
package3: package3.path
|
||||
}
|
||||
}
|
||||
}).prepare();
|
||||
'bower.json': {
|
||||
name: 'package2',
|
||||
dependencies: {
|
||||
package3: package3.path
|
||||
}
|
||||
}
|
||||
}).prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
package2: package2.path
|
||||
}
|
||||
},
|
||||
'.bowerrc': {
|
||||
ignoredDependencies: ['package3']
|
||||
}
|
||||
});
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
package2: package2.path
|
||||
}
|
||||
},
|
||||
'.bowerrc': {
|
||||
ignoredDependencies: ['package3']
|
||||
}
|
||||
});
|
||||
|
||||
return update().then(function() {
|
||||
expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true);
|
||||
expect(tempDir.exists('bower_components/package3')).to.equal(false);
|
||||
});
|
||||
|
||||
expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true);
|
||||
expect(tempDir.exists('bower_components/package3')).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not install ignored dependencies if run multiple times', function() {
|
||||
var package3 = new helpers.TempDir({
|
||||
'bower.json': {
|
||||
name: 'package3'
|
||||
}
|
||||
}).prepare();
|
||||
'bower.json': {
|
||||
name: 'package3'
|
||||
}
|
||||
}).prepare();
|
||||
|
||||
var package2 = new helpers.TempDir({
|
||||
'bower.json': {
|
||||
name: 'package2',
|
||||
dependencies: {
|
||||
package3: package3.path
|
||||
}
|
||||
}
|
||||
}).prepare();
|
||||
'bower.json': {
|
||||
name: 'package2',
|
||||
dependencies: {
|
||||
package3: package3.path
|
||||
}
|
||||
}
|
||||
}).prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
package2: package2.path
|
||||
}
|
||||
},
|
||||
'.bowerrc': {
|
||||
ignoredDependencies: ['package3']
|
||||
}
|
||||
});
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
package2: package2.path
|
||||
}
|
||||
},
|
||||
'.bowerrc': {
|
||||
ignoredDependencies: ['package3']
|
||||
}
|
||||
});
|
||||
|
||||
return update().then(function() {
|
||||
return update().then(function() {
|
||||
expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true);
|
||||
expect(tempDir.exists('bower_components/package3')).to.equal(false);
|
||||
});
|
||||
});
|
||||
return update().then(function() {
|
||||
expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true);
|
||||
expect(tempDir.exists('bower_components/package3')).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('runs preinstall hook when installing missing package', function () {
|
||||
it('runs preinstall hook when installing missing package', function() {
|
||||
mainPackage.prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -188,7 +184,7 @@ describe('bower update', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('runs postinstall hook when installing missing package', function () {
|
||||
it('runs postinstall hook when installing missing package', function() {
|
||||
mainPackage.prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -210,7 +206,7 @@ describe('bower update', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('doesn\'t runs postinstall when no package is update', function () {
|
||||
it('doesn\'t runs postinstall when no package is update', function() {
|
||||
mainPackage.prepare();
|
||||
|
||||
tempDir.prepare({
|
||||
@@ -236,7 +232,7 @@ describe('bower update', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('updates a package', function () {
|
||||
it('updates a package', function() {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
@@ -265,214 +261,9 @@ describe('bower update', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('doesn\'t update extraneous packages', function () {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test'
|
||||
}
|
||||
});
|
||||
|
||||
return install(['underscore#1.5.0']).then(function() {
|
||||
|
||||
expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0');
|
||||
|
||||
return update(null, {save: true}).then(function() {
|
||||
expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0');
|
||||
expect(tempDir.readJson('bower.json')).to.not.have.property('dependencies');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('updates bower.json dep after updating with --save flag', function () {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
underscore: '~1.5.0'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return install().then(function() {
|
||||
|
||||
expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0');
|
||||
|
||||
return update(null, {save: true}).then(function() {
|
||||
expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('updates bower.json dev dep after updating with --save-dev flag', function () {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
devDependencies: {
|
||||
underscore: '~1.5.0'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return install().then(function() {
|
||||
|
||||
expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0');
|
||||
|
||||
return update(null, {saveDev: true}).then(function() {
|
||||
expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('replaces "any" range with latest version', function () {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
underscore: '*'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return install().then(function() {
|
||||
|
||||
expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('*');
|
||||
|
||||
return update(null, {save: true}).then(function() {
|
||||
var version = semver.gte(tempDir.readJson('bower.json').dependencies.underscore.replace('~', ''), '1.8.3');
|
||||
expect(version).to.be.ok();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('updates multiple components in bower.json after updating with --save flag', function () {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
underscore: '~1.5.0',
|
||||
lodash: '~1.0.0'
|
||||
},
|
||||
devDependencies: {
|
||||
neat: '~1.5.0'
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
return install().then(function() {
|
||||
|
||||
expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0');
|
||||
expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.0');
|
||||
expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0');
|
||||
|
||||
return update(null, {save: true}).then(function() {
|
||||
// Normal deps should have changed
|
||||
expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2');
|
||||
expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.2');
|
||||
// Dev deps should not have changed
|
||||
expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('updates multiple components in bower.json after updating with --save-dev flag', function () {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
neat: '~1.5.0'
|
||||
},
|
||||
devDependencies: {
|
||||
underscore: '~1.5.0',
|
||||
lodash: '~1.0.0'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return install().then(function() {
|
||||
|
||||
expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0');
|
||||
expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0');
|
||||
expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.0');
|
||||
|
||||
return update(null, {saveDev: true}).then(function() {
|
||||
// Normal deps should not have changed
|
||||
expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0');
|
||||
// Dev deps should have changed
|
||||
expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2');
|
||||
expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.2');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly interprets semver range specifier pre-1.0', function () {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
underscore: '^0.1.0'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return install().then(function() {
|
||||
|
||||
expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('^0.1.0');
|
||||
|
||||
return update(null, {save: true}).then(function() {
|
||||
expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~0.1.1');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly interprets semver range specifier post-1.0', function () {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
lodash: '^1.0.0'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return install().then(function() {
|
||||
|
||||
expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('^1.0.0');
|
||||
|
||||
return update(null, {save: true}).then(function() {
|
||||
expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.3.1');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('doesn\'t update bower.json if versions are identical', function () {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
dependencies: {
|
||||
underscore: '1.5.0'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return install().then(function() {
|
||||
|
||||
expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0');
|
||||
|
||||
return update(null, {save: true}).then(function() {
|
||||
expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('does not install ignored dependencies when updating a package', function () {
|
||||
this.timeout(15000);
|
||||
|
||||
var package3 = new helpers.TempDir({
|
||||
'bower.json': {
|
||||
name: 'package3'
|
||||
@@ -536,7 +327,7 @@ describe('bower update', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('runs preinstall hook when updating a package', function () {
|
||||
it('runs preinstall hook when updating a package', function() {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
@@ -568,7 +359,7 @@ describe('bower update', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('runs postinstall hook when updating a package', function () {
|
||||
it('runs postinstall hook when updating a package', function() {
|
||||
tempDir.prepare({
|
||||
'bower.json': {
|
||||
name: 'test',
|
||||
|
||||
@@ -15,6 +15,7 @@ var defaultConfig = require('../../../lib/config');
|
||||
describe('GitResolver', function () {
|
||||
var tempDir = path.resolve(__dirname, '../../tmp/tmp');
|
||||
var originalrefs = GitResolver.refs;
|
||||
var originalEnv = process.env;
|
||||
var logger;
|
||||
|
||||
before(function () {
|
||||
@@ -23,6 +24,7 @@ describe('GitResolver', function () {
|
||||
|
||||
afterEach(function () {
|
||||
logger.removeAllListeners();
|
||||
process.env = originalEnv;
|
||||
});
|
||||
|
||||
function clearResolverRuntimeCache() {
|
||||
@@ -41,6 +43,24 @@ describe('GitResolver', function () {
|
||||
describe('misc', function () {
|
||||
it.skip('should error out if git is not installed');
|
||||
it.skip('should setup git template dir to an empty folder');
|
||||
it('should set process.env.GIT_SSL_NO_VERIFY when strictSSL is false', function () {
|
||||
var resolver;
|
||||
var decEndpoint = { source: 'foo'};
|
||||
|
||||
expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY');
|
||||
|
||||
resolver = new GitResolver(decEndpoint, defaultConfig(), logger);
|
||||
expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'false');
|
||||
delete process.env.GIT_SSL_NO_VERIFY;
|
||||
|
||||
resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: false}), logger);
|
||||
expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'true');
|
||||
delete process.env.GIT_SSL_NO_VERIFY;
|
||||
|
||||
resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: true}), logger);
|
||||
expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'false');
|
||||
delete process.env.GIT_SSL_NO_VERIFY;
|
||||
});
|
||||
});
|
||||
|
||||
describe('.hasNew', function () {
|
||||
@@ -869,10 +889,8 @@ describe('GitResolver', function () {
|
||||
var resolver = create('foo');
|
||||
var dst = path.join(tempDir, '.git');
|
||||
|
||||
this.timeout(30000); // Give some time to copy
|
||||
|
||||
// Copy .git folder to the tempDir
|
||||
copy.copyDir(path.resolve(__dirname, '../../../.git'), dst, {
|
||||
copy.copyDir(path.resolve(__dirname, '../../assets/package-a/.git'), dst, {
|
||||
mode: 0777
|
||||
})
|
||||
.then(function () {
|
||||
|
||||
481
test/core/resolvers/pluginResolverFactory.js
Normal file
481
test/core/resolvers/pluginResolverFactory.js
Normal file
@@ -0,0 +1,481 @@
|
||||
var expect = require('expect.js');
|
||||
var path = require('path');
|
||||
var Logger = require('bower-logger');
|
||||
var createError = require('../../../lib/util/createError');
|
||||
var pluginResolverFactory = require('../../../lib/core/resolvers/pluginResolverFactory');
|
||||
var defaultConfig = require('../../../lib/config');
|
||||
var Q = require('q');
|
||||
|
||||
describe('pluginResolverFactory', function () {
|
||||
var testPackage = path.resolve(__dirname, '../../assets/package-a');
|
||||
var logger;
|
||||
|
||||
before(function () {
|
||||
logger = new Logger();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
logger.removeAllListeners();
|
||||
});
|
||||
|
||||
var mockPluginResolver = function resolver (bower) {
|
||||
|
||||
return {
|
||||
|
||||
match: function (source) {
|
||||
return true;
|
||||
},
|
||||
|
||||
locate: function (source) {
|
||||
return source;
|
||||
},
|
||||
|
||||
releases: function (source) {
|
||||
return [
|
||||
{ target: 'v1.0.0', version: '1.0.0' },
|
||||
{ target: 'v1.0.1', version: '1.0.1' }
|
||||
];
|
||||
},
|
||||
|
||||
fetch: function (endpoint, cached) {
|
||||
if (cached && cached.version) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
tempPath: 'some/temp/path',
|
||||
removeIgnores: true
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function create(decEndpoint) {
|
||||
if (typeof decEndpoint === 'string') {
|
||||
decEndpoint = { source: decEndpoint };
|
||||
}
|
||||
var PluginResolver = pluginResolverFactory(mockPluginResolver,
|
||||
defaultConfig());
|
||||
return new PluginResolver(decEndpoint);
|
||||
}
|
||||
|
||||
describe('.constructor', function () {
|
||||
it('should internally add decEndpoint', function () {
|
||||
var resolver;
|
||||
resolver = create('file://' + testPackage);
|
||||
expect(typeof resolver._decEndpoint).to.equal('object');
|
||||
expect(resolver._decEndpoint.source).to.equal('file://' + testPackage);
|
||||
});
|
||||
|
||||
it('should throw when invalid resolverFactory is provided', function () {
|
||||
expect(function () {
|
||||
pluginResolverFactory('not-a-function',
|
||||
defaultConfig());
|
||||
}).to.throwException(createError('Resolver has "string" type instead of "function" type.', 'ERESOLERAPI'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getEndpoint', function () {
|
||||
it('should return endpoint', function () {
|
||||
var resolver, endPoint;
|
||||
resolver = create('file://' + testPackage);
|
||||
endPoint = resolver.getEndpoint();
|
||||
expect(endPoint).to.have.property('source');
|
||||
expect(endPoint.source).to.equal('file://' + testPackage);
|
||||
expect(endPoint).to.have.property('name');
|
||||
expect(endPoint.name).to.equal('package-a');
|
||||
expect(endPoint).to.have.property('target');
|
||||
expect(endPoint.target).to.equal('*');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getSource', function () {
|
||||
it('should return endpoint', function () {
|
||||
var resolver, source;
|
||||
resolver = create('file://' + testPackage);
|
||||
source = resolver.getSource();
|
||||
expect(source).to.equal('file://' + testPackage);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getTarget', function () {
|
||||
it('should return target', function () {
|
||||
var resolver, source;
|
||||
resolver = create({
|
||||
source: 'file://' + testPackage,
|
||||
target: 'some-target'
|
||||
});
|
||||
source = resolver.getTarget();
|
||||
expect(source).to.equal('some-target');
|
||||
});
|
||||
it('should return * when no target is specified', function () {
|
||||
var resolver, source;
|
||||
resolver = create('file://' + testPackage);
|
||||
source = resolver.getTarget();
|
||||
expect(source).to.equal('*');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getName', function () {
|
||||
it('should return target', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getPkgMeta', function () {
|
||||
it('should return package meta', function () {
|
||||
var resolver, pkgMeta;
|
||||
resolver = create('file://' + testPackage);
|
||||
resolver._pkgMeta = { version: 'v1.0.1' };
|
||||
pkgMeta = resolver.getPkgMeta();
|
||||
console.log(pkgMeta);
|
||||
expect(pkgMeta).to.have.property('version');
|
||||
expect(pkgMeta.version).to.equal('v1.0.1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.isCacheable', function () {
|
||||
it('should always return true', function () {
|
||||
var resolver, isCacheable;
|
||||
resolver = create('file://' + testPackage);
|
||||
isCacheable = resolver.isCacheable();
|
||||
expect(isCacheable).to.be.ok();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.hasNew', function () {
|
||||
it('should return existing hasNewPromise if its set', function () {
|
||||
var resolver;
|
||||
resolver = create('file://' + testPackage);
|
||||
resolver.hasNewPromise = Q.fcall(function () {
|
||||
return 'some-dummy-value';
|
||||
});
|
||||
resolver.hasNew().then(function (resolvedtestValue) {
|
||||
expect(resolvedtestValue).to.be('some-dummy-value');
|
||||
});
|
||||
});
|
||||
it('should return target', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('.resolve', function () {
|
||||
it('should throw \'Resolver did not provide releases of package.\'', function (next) {
|
||||
var mockPluginResolverWithEmptyReleases = function resolver (bower) {
|
||||
return {
|
||||
|
||||
match: function (source) {
|
||||
return true;
|
||||
},
|
||||
|
||||
releases: function (source) {
|
||||
return null;
|
||||
},
|
||||
|
||||
fetch: function (endpoint, cached) {
|
||||
if (cached && cached.version) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
tempPath: '/temp/path',
|
||||
removeIgnores: true
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var PluginResolver = pluginResolverFactory(mockPluginResolverWithEmptyReleases,
|
||||
defaultConfig());
|
||||
var path = 'file://' + testPackage;
|
||||
var resolver = new PluginResolver(path);
|
||||
resolver.resolve()
|
||||
.catch(function (e) {
|
||||
expect(e.message).to
|
||||
.equal('Resolver did not provide releases of package.');
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw \'No version found that was able to satisfy *.\'', function (next) {
|
||||
var mockPluginResolverWithNoMatchingTarget = function resolver (bower) {
|
||||
|
||||
return {
|
||||
|
||||
match: function (source) {
|
||||
return true;
|
||||
},
|
||||
|
||||
releases: function (source) {
|
||||
return [];
|
||||
},
|
||||
|
||||
fetch: function (endpoint, cached) {
|
||||
if (cached && cached.version) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
tempPath: '/temp/path',
|
||||
removeIgnores: true
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var PluginResolver = pluginResolverFactory(
|
||||
mockPluginResolverWithNoMatchingTarget,
|
||||
defaultConfig()
|
||||
);
|
||||
var path = 'file://' + testPackage;
|
||||
var resolver = new PluginResolver(path);
|
||||
resolver.resolve()
|
||||
.catch(function (e) {
|
||||
expect(e.message).to
|
||||
.equal('No version found that was able to satisfy *');
|
||||
expect(e.code).to
|
||||
.equal('ENORESTARGET');
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw \'Resolver does not accept version ranges\'', function (next) {
|
||||
var mockPluginResolverWithInvalidTarget = function resolver (bower) {
|
||||
return {
|
||||
match: function (source) {
|
||||
return true;
|
||||
},
|
||||
releases: null,
|
||||
fetch: function (endpoint, cached) {
|
||||
if (cached && cached.version) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
tempPath: '/temp/path',
|
||||
removeIgnores: true
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var PluginResolver = pluginResolverFactory(
|
||||
mockPluginResolverWithInvalidTarget,
|
||||
defaultConfig()
|
||||
);
|
||||
var path = 'file://' + testPackage;
|
||||
var resolver = new PluginResolver({
|
||||
source: path,
|
||||
target: '2.0.0'
|
||||
});
|
||||
resolver.resolve()
|
||||
.catch(function (e) {
|
||||
expect(e.message).to
|
||||
.equal('Resolver does not accept version ranges (2.0.0)');
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should throw \'Resolver does not implement the "fetch" method.\'', function (next) {
|
||||
var mockPluginResolverWithoutFetch = function resolver (bower) {
|
||||
return {
|
||||
match: function (source) {
|
||||
return true;
|
||||
},
|
||||
releases: function (source) {
|
||||
return [
|
||||
{ target: 'v1.0.0', version: '1.0.0' },
|
||||
{ target: 'v1.0.1', version: '1.0.1' }
|
||||
];
|
||||
},
|
||||
fetch: null
|
||||
};
|
||||
};
|
||||
var PluginResolver = pluginResolverFactory(
|
||||
mockPluginResolverWithoutFetch,
|
||||
defaultConfig()
|
||||
);
|
||||
var path = 'file://' + testPackage;
|
||||
var resolver = new PluginResolver(path);
|
||||
resolver.resolve()
|
||||
.catch(function (e) {
|
||||
expect(e.message).to
|
||||
.equal('Resolver does not implement the "fetch" method.');
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw \'Resolver did not provide path to extracted contents of package\'',
|
||||
function (next) {
|
||||
var mockPluginResolverWithoutTempPath = function resolver (bower) {
|
||||
return {
|
||||
|
||||
match: function (source) {
|
||||
return true;
|
||||
},
|
||||
|
||||
releases: function (source) {
|
||||
return [
|
||||
{ target: 'v1.0.0', version: '1.0.0' },
|
||||
{ target: 'v1.0.1', version: '1.0.1' }
|
||||
];
|
||||
},
|
||||
|
||||
fetch: function (endpoint, cached) {
|
||||
if (cached && cached.version) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
tempPath: null,
|
||||
removeIgnores: true
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
var PluginResolver = pluginResolverFactory(
|
||||
mockPluginResolverWithoutTempPath,
|
||||
defaultConfig()
|
||||
);
|
||||
var path = 'file://' + testPackage;
|
||||
var resolver = new PluginResolver(path);
|
||||
resolver.resolve()
|
||||
.catch(function (e) {
|
||||
expect(e.message).to
|
||||
.equal('Resolver did not provide path to extracted contents of package.');
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('.isTargetable', function () {
|
||||
it('should accept mockPluginResolverWithReleasesFn', function () {
|
||||
var PluginResolver = pluginResolverFactory(mockPluginResolver,
|
||||
defaultConfig());
|
||||
expect(PluginResolver.isTargetable()).to.be.ok();
|
||||
});
|
||||
it('should reject mockPluginResolverWithoutReleasesFn', function () {
|
||||
var mockPluginResolverWithoutReleasesFn = function resolver (bower) {
|
||||
return {
|
||||
match: function (source) {
|
||||
return true;
|
||||
},
|
||||
locate: function (source) {
|
||||
return source;
|
||||
},
|
||||
fetch: function (endpoint, cached) {
|
||||
if (cached && cached.version) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
tempPath: 'some/tmp/path',
|
||||
removeIgnores: true
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
var PluginResolver = pluginResolverFactory(mockPluginResolverWithoutReleasesFn,
|
||||
defaultConfig());
|
||||
expect(PluginResolver.isTargetable()).to.not.be.ok();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.clearRuntimeCache', function () {
|
||||
it('', function () {
|
||||
//Unable to test private variable `resolver`
|
||||
});
|
||||
});
|
||||
|
||||
describe('.match', function () {
|
||||
it('should throw when plugin does not implement .match', function () {
|
||||
var mockPluginResolverWithoutMatch = function resolver (bower) {
|
||||
|
||||
return {
|
||||
|
||||
releases: function (source) {
|
||||
return [
|
||||
{ target: 'v1.0.0', version: '1.0.0' },
|
||||
{ target: 'v1.0.1', version: '1.0.1' }
|
||||
];
|
||||
},
|
||||
|
||||
fetch: function (endpoint, cached) {
|
||||
if (cached && cached.version) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
tempPath: 'some/temp/path',
|
||||
removeIgnores: true
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var PluginResolver = pluginResolverFactory(mockPluginResolverWithoutMatch,
|
||||
defaultConfig());
|
||||
var source = 'git://github.com/jquery/jquery.git';
|
||||
expect(function () {
|
||||
PluginResolver.match(source);
|
||||
}).to.throwException(createError('Resolver is missing "match"' +
|
||||
'method.',
|
||||
'ERESOLVERAPI'));
|
||||
});
|
||||
|
||||
it('should match given source', function () {
|
||||
var PluginResolver = pluginResolverFactory(mockPluginResolver,
|
||||
defaultConfig());
|
||||
var source = 'git://github.com/jquery/jquery.git';
|
||||
PluginResolver.match(source).then(function (result) {
|
||||
expect(result).to.be.ok();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.locate', function () {
|
||||
it('should return source when plugin does not implement .locate', function () {
|
||||
|
||||
var mockPluginResolverWithoutLocate = function resolver (bower) {
|
||||
|
||||
return {
|
||||
|
||||
match: function (source) {
|
||||
return true;
|
||||
},
|
||||
|
||||
releases: function (source) {
|
||||
return [
|
||||
{ target: 'v1.0.0', version: '1.0.0' },
|
||||
{ target: 'v1.0.1', version: '1.0.1' }
|
||||
];
|
||||
},
|
||||
|
||||
fetch: function (endpoint, cached) {
|
||||
if (cached && cached.version) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
tempPath: '/temp/path',
|
||||
removeIgnores: true
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var PluginResolver = pluginResolverFactory(mockPluginResolverWithoutLocate,
|
||||
defaultConfig());
|
||||
var path = 'file://' + testPackage;
|
||||
expect(PluginResolver.locate(path)).to.be(path);
|
||||
});
|
||||
|
||||
it('should locate the source', function () {
|
||||
var PluginResolver = pluginResolverFactory(mockPluginResolver,
|
||||
defaultConfig());
|
||||
var source = 'jquery/jquery';
|
||||
PluginResolver.locate(source).then(function (result) {
|
||||
expect(result).to.be(source);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -220,7 +220,7 @@ exports.command = function (command, stubs) {
|
||||
};
|
||||
|
||||
exports.run = function (command, args) {
|
||||
var logger = command.apply(command, args || []);
|
||||
var logger = command.apply(null, args || []);
|
||||
|
||||
// Hack so we can intercept prompring for data
|
||||
logger.prompt = function(data) {
|
||||
@@ -310,4 +310,4 @@ exports.runBin = function (args) {
|
||||
|
||||
afterEach(function () {
|
||||
nock.cleanAll();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -613,7 +613,11 @@ describe('StandardRenderer', function () {
|
||||
versions: [
|
||||
'1.2.0',
|
||||
'1.2.1',
|
||||
'1.2.2'
|
||||
'1.2.2',
|
||||
'1.2.3+build-1234',
|
||||
'1.2.8-build.2098+sha.cb9c0f2',
|
||||
'1.3.0-rc.5',
|
||||
'1.3.0-beta.18'
|
||||
]
|
||||
});
|
||||
}).spread(function(stdout, stderr) {
|
||||
@@ -627,6 +631,48 @@ describe('StandardRenderer', function () {
|
||||
- 1.2.0
|
||||
- 1.2.1
|
||||
- 1.2.2
|
||||
|
||||
Show 4 additional prereleases with ‘bower info foo --verbose’
|
||||
You can request info for a specific version with 'bower info foo#<version>'
|
||||
|
||||
*/}));
|
||||
});
|
||||
});
|
||||
|
||||
it('outputs full info command log with prereleases', function() {
|
||||
return helpers.capture(function() {
|
||||
var renderer = new StandardRenderer('info', { verbose: true });
|
||||
renderer.end({
|
||||
name: 'foo',
|
||||
latest: {
|
||||
version: '1.2.3'
|
||||
},
|
||||
versions: [
|
||||
'1.2.0',
|
||||
'1.2.1',
|
||||
'1.2.2',
|
||||
'1.2.3+build-1234',
|
||||
'1.2.8-build.2098+sha.cb9c0f2',
|
||||
'1.3.0-rc.5',
|
||||
'1.3.0-beta.18'
|
||||
]
|
||||
});
|
||||
}).spread(function(stdout, stderr) {
|
||||
expect(stdout).to.equal(multiline(function() {/*
|
||||
|
||||
{
|
||||
version: '1.2.3'
|
||||
}
|
||||
|
||||
Available versions:
|
||||
- 1.2.0
|
||||
- 1.2.1
|
||||
- 1.2.2
|
||||
- 1.2.3+build-1234
|
||||
- 1.2.8-build.2098+sha.cb9c0f2
|
||||
- 1.3.0-rc.5
|
||||
- 1.3.0-beta.18
|
||||
|
||||
You can request info for a specific version with 'bower info foo#<version>'
|
||||
|
||||
*/}));
|
||||
@@ -784,6 +830,7 @@ describe('StandardRenderer', function () {
|
||||
Usage:
|
||||
|
||||
bower uninstall <name> [<name> ..] [<options>]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help Show this help message
|
||||
@@ -795,6 +842,7 @@ describe('StandardRenderer', function () {
|
||||
|
||||
Uninstalls a package locally from your bower_components directory
|
||||
|
||||
|
||||
*/}));
|
||||
});
|
||||
});
|
||||
|
||||
49
test/sample/bower.json
Normal file
49
test/sample/bower.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "platform",
|
||||
"version": "0.0.1",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components"
|
||||
],
|
||||
"dependencies": {
|
||||
"angular": "~1.2.14",
|
||||
"bootstrap": "~3.1.1",
|
||||
"ace-builds": "~1.1.3",
|
||||
"font-awesome": "~4.2.0",
|
||||
"slimScroll": "~1.3.1",
|
||||
"slimScrollHorizontal": "https://github.com/rochal/jQuery-slimScroll.git",
|
||||
"requirejs": "~2.1.11",
|
||||
"lodash": "~2.4.1",
|
||||
"angular-sanitize": "~1.2.14",
|
||||
"asEvented": "https://github.com/mkuklis/asEvented.git#0.4.3",
|
||||
"restangular": "~1.3.1",
|
||||
"angular-animate": "~1.2.16",
|
||||
"angular-ui-sortable": "~0.12.6",
|
||||
"howler": "~1.1.20",
|
||||
"es6-shim": "~0.10.1",
|
||||
"venturocket-angular-slider": "~0.3.2",
|
||||
"almond": "~0.2.9",
|
||||
"peerjs": "~0.3.8",
|
||||
"angular-gravatar": "~0.1.5",
|
||||
"angular-deckgrid": "~0.4.4",
|
||||
"angular-ui-router": "~0.2.10",
|
||||
"angular-moment": "~0.7.1",
|
||||
"lz-string": "https://github.com/pieroxy/lz-string.git#4cc031b68e3a6db202c467396a01429629666122",
|
||||
"angular-local-storage": "~0.0.5",
|
||||
"angular-hotkeys": "chieffancypants/angular-hotkeys#~1.4.0",
|
||||
"coffee-script": "~1.7.1",
|
||||
"jquery-ui": "~1.11.0",
|
||||
"angular-contenteditable": "~0.3.7",
|
||||
"angulartics": "~0.16.4",
|
||||
"angular-marked": "Hypercubed/angular-marked#~0.0.12",
|
||||
"angular-bootstrap": "~0.11.0",
|
||||
"angular-charts": "~0.2.6",
|
||||
"ng-file-upload": "~1.6.12",
|
||||
"js-beautify": "~1.5.4",
|
||||
"angular-fullscreen": "~1.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"angular": ">= 1.3.0"
|
||||
}
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
var expect = require('expect.js');
|
||||
var proxyquire = require('proxyquire');
|
||||
var object = require('mout').object;
|
||||
|
||||
describe('analytics', function () {
|
||||
|
||||
var mockAnalytics = function(stubs, promptResponse) {
|
||||
return proxyquire('../../lib/util/analytics', {
|
||||
insight: function () {
|
||||
return object.merge(stubs || {}, {
|
||||
askPermission: function (message, callback) {
|
||||
callback(undefined, promptResponse);
|
||||
},
|
||||
config: {
|
||||
clear: function () {}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
describe('#setup', function () {
|
||||
// Reset process.env.CI after tests are done
|
||||
var oldCI;
|
||||
beforeEach(function () {
|
||||
oldCI = process.env.CI;
|
||||
});
|
||||
afterEach(function () {
|
||||
process.env.CI = oldCI;
|
||||
});
|
||||
|
||||
it('leaves analytics enabled if provided', function () {
|
||||
return mockAnalytics()
|
||||
.setup({ analytics: true })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('leaves analytics disabled if provided', function () {
|
||||
return mockAnalytics()
|
||||
.setup({ analytics: false })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('disables analytics for non-interactive mode', function () {
|
||||
return mockAnalytics()
|
||||
.setup({ interactive: false })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('disables if insight.optOut is true and interactive', function () {
|
||||
return mockAnalytics({ optOut: true })
|
||||
.setup({ interactive: true })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('enables if insight.optOut is false and interactive', function () {
|
||||
return mockAnalytics({ optOut: false })
|
||||
.setup({ interactive: true })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('disables if insight.optOut is false and non-interactive', function () {
|
||||
return mockAnalytics({ optOut: false })
|
||||
.setup({ interactive: false })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('enables if interactive insights return true from prompt', function () {
|
||||
return mockAnalytics({ optOut: undefined }, true)
|
||||
.setup({ interactive: true })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('disables if interactive insights return false from prompt', function () {
|
||||
return mockAnalytics({ optOut: undefined }, false)
|
||||
.setup({ interactive: true })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('disables if process.env.CI is true', function () {
|
||||
process.env.CI = true;
|
||||
|
||||
// Clear cache set by proxyquire
|
||||
delete require.cache[require.resolve('../../lib/util/analytics')];
|
||||
|
||||
var analytics = require('../../lib/util/analytics');
|
||||
return analytics.setup({ interactive: true })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('disables if prompt times out', function () {
|
||||
// Create mock insight with very low permission timeout
|
||||
var Insight = require('insight');
|
||||
var mockInsight = new Insight({
|
||||
trackingCode: 'mock',
|
||||
pkg: require('../../package.json')
|
||||
});
|
||||
mockInsight._permissionTimeout = 0.1;
|
||||
var mockAnalyticsWithInsight = proxyquire('../../lib/util/analytics', {
|
||||
insight: function () {
|
||||
return mockInsight;
|
||||
}
|
||||
});
|
||||
|
||||
return mockAnalyticsWithInsight
|
||||
.setup({ interactive: true })
|
||||
.then(function (enabled) {
|
||||
expect(enabled).to.be(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Tracker', function (next) {
|
||||
it('tracks if analytics = true', function(next) {
|
||||
var analytics = mockAnalytics({
|
||||
track: function (arg) {
|
||||
expect(arg).to.be('foo');
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
new analytics.Tracker({ analytics: true }).track('foo');
|
||||
});
|
||||
|
||||
it('does not track if analytics = false', function () {
|
||||
var analytics = mockAnalytics({
|
||||
track: function (arg) {
|
||||
throw new Error();
|
||||
}
|
||||
});
|
||||
|
||||
expect(function () {
|
||||
new analytics.Tracker({ analytics: false }).track('foo');
|
||||
}).to.not.throwError();
|
||||
});
|
||||
|
||||
it('tracks if analytics = undefined and setup returns true', function(next) {
|
||||
var analytics = mockAnalytics({
|
||||
track: function (arg) {
|
||||
expect(arg).to.be('foo');
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
analytics
|
||||
.setup({ analytics: true })
|
||||
.then(function () {
|
||||
new analytics.Tracker({}).track('foo');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
57
test/util/createLink.js
Normal file
57
test/util/createLink.js
Normal file
@@ -0,0 +1,57 @@
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
var fs = require('fs');
|
||||
var expect = require('expect.js');
|
||||
var helpers = require('../helpers');
|
||||
var createLink = require('../../lib/util/createLink');
|
||||
|
||||
describe('createLink', function () {
|
||||
|
||||
var srcDir = new helpers.TempDir({
|
||||
someFile: 'Hello World',
|
||||
someDirectory: {
|
||||
otherFile: 'Hello World'
|
||||
}
|
||||
});
|
||||
|
||||
var dstDir = new helpers.TempDir();
|
||||
|
||||
beforeEach(function() {
|
||||
srcDir.prepare();
|
||||
dstDir.prepare();
|
||||
});
|
||||
|
||||
it('creates a symlink to a file', function() {
|
||||
|
||||
var src = path.join(srcDir.path, 'someFile'),
|
||||
dst = path.join(dstDir.path, 'someFile');
|
||||
|
||||
return createLink(src, dst)
|
||||
.then(function() {
|
||||
return Q.nfcall(fs.readlink, dst)
|
||||
.then(function(linkString) {
|
||||
expect(linkString).to.be.equal(src);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('throws an error when destination already exists', function() {
|
||||
|
||||
var src = path.join(srcDir.path, 'someFile'),
|
||||
dst = path.join(dstDir.path);
|
||||
|
||||
var deferred = Q.defer();
|
||||
|
||||
createLink(src, dst)
|
||||
.catch(function(err) {
|
||||
expect(err.code).to.be.equal('EEXIST');
|
||||
deferred.resolve();
|
||||
})
|
||||
.then(function() {
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
});
|
||||
|
||||
});
|
||||
@@ -22,7 +22,7 @@ describe('download', function () {
|
||||
nock('http://bower.io', opts.nockOpts)
|
||||
);
|
||||
|
||||
download('http://bower.io/package.tar.gz', destination, opts.downloadOpts)
|
||||
download(opts.sourceUrl || 'http://bower.io/package.tar.gz', opts.destinationPath || destination, opts.downloadOpts)
|
||||
.then(function (result) {
|
||||
if (opts.expect) {
|
||||
opts.expect(result);
|
||||
@@ -174,4 +174,36 @@ describe('download', function () {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('gzipped files', function () {
|
||||
|
||||
function testGzip(sourceFilename) {
|
||||
var sourceFile = path.resolve(__dirname, '../assets/' + sourceFilename);
|
||||
var destinationPath = tempDir.getPath(sourceFilename);
|
||||
|
||||
return downloadTest({
|
||||
response: function(nock) {
|
||||
nock
|
||||
.get('/' + sourceFilename)
|
||||
.replyWithFile(200, sourceFile, {
|
||||
'Content-Encoding' : 'gzip'
|
||||
});
|
||||
},
|
||||
expect: function() {
|
||||
expect(fs.readFileSync(destinationPath, 'ascii'))
|
||||
.to.be('Hello World!\n');
|
||||
},
|
||||
sourceUrl: 'http://bower.io/' + sourceFilename,
|
||||
destinationPath: destinationPath
|
||||
});
|
||||
}
|
||||
|
||||
it('correctly decodes gzipped files without gz extension', function () {
|
||||
return testGzip('test-gz.txt');
|
||||
});
|
||||
|
||||
it('correctly decodes gzipped files with gz extension', function () {
|
||||
return testGzip('test-gz.txt.gz');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
describe('util', function () {
|
||||
require('./removeIgnores');
|
||||
require('./analytics');
|
||||
require('./download');
|
||||
require('./isPathAbsolute');
|
||||
require('./relativeToBaseDir');
|
||||
require('./createLink');
|
||||
});
|
||||
|
||||
14
test/util/isPathAbsolute.js
Normal file
14
test/util/isPathAbsolute.js
Normal file
@@ -0,0 +1,14 @@
|
||||
var expect = require('expect.js');
|
||||
var isPathAbsolute = require('../../lib/util/isPathAbsolute');
|
||||
|
||||
describe('isPathAbsolute', function () {
|
||||
|
||||
it('returns true when a path begins with /', function() {
|
||||
expect(isPathAbsolute('/tmp/foo')).to.be.ok();
|
||||
});
|
||||
|
||||
it('returns false when a path does not begin with /', function() {
|
||||
expect(isPathAbsolute('./tmp/foo')).to.not.be.ok();
|
||||
});
|
||||
|
||||
});
|
||||
18
test/util/relativeToBaseDir.js
Normal file
18
test/util/relativeToBaseDir.js
Normal file
@@ -0,0 +1,18 @@
|
||||
var path = require('path');
|
||||
var expect = require('expect.js');
|
||||
var relativeToBaseDir = require('../../lib/util/relativeToBaseDir');
|
||||
|
||||
describe('relativeToBaseDir', function () {
|
||||
|
||||
var joinOrReturnAbsolutePath = relativeToBaseDir('/tmp');
|
||||
|
||||
it('returns a partial function that joins paths of the partials first arguments', function() {
|
||||
expect(joinOrReturnAbsolutePath('foo')).to.be.equal(path.resolve('/tmp/foo'));
|
||||
expect(joinOrReturnAbsolutePath('./foo')).to.be.equal(path.resolve('/tmp/foo'));
|
||||
});
|
||||
|
||||
it('returns a partial function that returns it\'s first argument when it begins with /', function() {
|
||||
expect(joinOrReturnAbsolutePath('/foo')).to.be.equal(path.resolve('/foo'));
|
||||
expect(joinOrReturnAbsolutePath('/foo/bar')).to.be.equal(path.resolve('/foo/bar'));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user