mirror of
https://github.com/bower/bower.git
synced 2026-04-24 03:00:19 -04:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c50d11b04f |
52
.eslintrc
52
.eslintrc
@@ -1,52 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"node": true,
|
||||
"mocha": true
|
||||
},
|
||||
"rules": {
|
||||
"no-bitwise": 0,
|
||||
"curly": 0,
|
||||
"eqeqeq": 0,
|
||||
"guard-for-in": 0,
|
||||
"no-use-before-define": 0,
|
||||
"no-caller": 2,
|
||||
"no-new": 2,
|
||||
"no-plusplus": 0,
|
||||
"no-undef": 2,
|
||||
"no-unused-vars": 0,
|
||||
"strict": 0,
|
||||
"semi": 0,
|
||||
"comma-spacing": 2,
|
||||
"quote-props": [2, "consistent", { "keywords": true }],
|
||||
"quotes": [2, "single", "avoid-escape"],
|
||||
"indent": [2, 4],
|
||||
"no-cond-assign": [ 2, "except-parens" ],
|
||||
"no-debugger": 2,
|
||||
"no-dupe-args": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-unreachable": 2,
|
||||
"valid-typeof": 2,
|
||||
"no-fallthrough": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-eq-null": 0,
|
||||
"no-eval": 0,
|
||||
"no-unused-expressions": 0,
|
||||
"block-scoped-var": 0,
|
||||
"no-iterator": 0,
|
||||
"no-loop-func": 2,
|
||||
"no-script-url": 0,
|
||||
"no-shadow": 0,
|
||||
"no-new-func": 2,
|
||||
"no-new-wrappers": 2,
|
||||
"no-invalid-this": 0,
|
||||
"space-before-blocks": [2, "always"],
|
||||
"space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
|
||||
"space-infix-ops": 2,
|
||||
"keyword-spacing": 2,
|
||||
"new-parens": 2,
|
||||
"no-multiple-empty-lines": [2, { max: 2}],
|
||||
"eol-last": 2,
|
||||
"no-trailing-spaces": 2
|
||||
}
|
||||
}
|
||||
44
.github/ISSUE_TEMPLATE.md
vendored
44
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,44 +0,0 @@
|
||||
<!--
|
||||
|
||||
If you are reporting a new issue, make sure that we do not have any duplicates.
|
||||
You can ensure this by searching the issue list for this repository.
|
||||
|
||||
You are welcome to open issues to discuss important general topics concerning Bower.
|
||||
However for support questions, please consider using http://stackoverflow.com or
|
||||
asking for help in our Discord channel: https://discordapp.com/invite/0fFM7QF0KpZaDeN9
|
||||
|
||||
# BUG REPORT
|
||||
|
||||
Use the commands below to provide key information to reproduce:
|
||||
You do NOT have to include this information if this is a FEATURE REQUEST OR DISCUSSION
|
||||
|
||||
For more information about reporting bugs, see:
|
||||
https://github.com/bower/bower/wiki/Report-a-Bug
|
||||
|
||||
-->
|
||||
|
||||
**Output of `bower -v && npm -v && node -v`:**
|
||||
|
||||
```
|
||||
(paste your output here)
|
||||
```
|
||||
|
||||
**Additional environment details (proxy, private registry, etc.):**
|
||||
|
||||
|
||||
|
||||
**Steps to reproduce the issue:**
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
**Describe the results you received:**
|
||||
|
||||
|
||||
|
||||
**Describe the results you expected:**
|
||||
|
||||
|
||||
|
||||
**Additional information:**
|
||||
13
.gitignore
vendored
13
.gitignore
vendored
@@ -1,2 +1,11 @@
|
||||
npm-debug.log*
|
||||
lerna-debug.log*
|
||||
/node_modules
|
||||
/npm-debug.log
|
||||
|
||||
/test/assets/package-*/
|
||||
/test/assets/temp-*/
|
||||
/test/reports
|
||||
/test/tmp/
|
||||
|
||||
/bower.json
|
||||
/component.json
|
||||
/bower_components
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"plusplus": false,
|
||||
"regexp": false,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"unused": "vars",
|
||||
"quotmark": "single",
|
||||
"strict": false,
|
||||
"trailing": true,
|
||||
22
.travis.yml
22
.travis.yml
@@ -1,22 +1,15 @@
|
||||
sudo: false
|
||||
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.11"
|
||||
- "0.12"
|
||||
- "4.0"
|
||||
- "4.1"
|
||||
- "4.2"
|
||||
- "5"
|
||||
- "6"
|
||||
env:
|
||||
- NODE_VERSION=0.10
|
||||
- NODE_VERSION=0.11
|
||||
|
||||
install:
|
||||
- test $TRAVIS_OS_NAME = "osx" && brew install nvm && source $(brew --prefix nvm)/nvm.sh || test $TRAVIS_OS_NAME = "linux"
|
||||
- nvm install $NODE_VERSION
|
||||
- node --version
|
||||
- npm --version
|
||||
- git --version
|
||||
- svn --version | head -n 1
|
||||
- npm install -g grunt-cli
|
||||
- npm install
|
||||
|
||||
os:
|
||||
@@ -24,10 +17,9 @@ os:
|
||||
- linux
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- os: osx
|
||||
- env: "NODE_VERSION=0.11"
|
||||
|
||||
script:
|
||||
- npm test
|
||||
- grunt travis
|
||||
|
||||
154
CHANGELOG.md
154
CHANGELOG.md
@@ -1,153 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## 1.7.9 - 2016-04-05
|
||||
|
||||
- Show warnings for invalid bower.json fields
|
||||
- Update bower-json
|
||||
- Less strict validation on package name (allow spaces, slashes, and "@")
|
||||
|
||||
## 1.7.8 - 2016-04-04
|
||||
|
||||
- Don't ask for git credentials in non-interactive session, fixes #956 #1009
|
||||
- Prevent swallowing exceptions with programmatic api, fixes #2187
|
||||
- Update graceful-fs to 4.x in all dependences, fixes nodejs/node#5213
|
||||
- Resolve pluggable resolvers using cwd and fallback to global modules, fixes #1919
|
||||
- Upgrade handlebars to 4.0.5, closes #2195
|
||||
- Replace all % chatacters in defined scripts, instead of only first one, fixes #2174
|
||||
- Update opn package to fix issues with "bower open" command on Windows
|
||||
- Update bower-config
|
||||
- Do not interpolate environment variables in script hooks, fixes bower/config#47
|
||||
- Update bower-json
|
||||
- Validate package name more strictly and allow only latin letters, dots, dashes and underscores
|
||||
- Add support for "save" and "save-exact" in .bowerrc, #2161
|
||||
|
||||
## 1.7.7 - 2016-01-27
|
||||
|
||||
Revert locations of all files while still packaging `node_modules`.
|
||||
|
||||
It's because people are depending on internals of bower, like
|
||||
`bower/lib/renderers/StandardRenderer`. We want to preserve this
|
||||
implicit contract, but we discourage it. The only official way
|
||||
to use bower programmatically is through `require('bower')`.
|
||||
|
||||
## 1.7.6 - 2016-01-27
|
||||
|
||||
- Revert location of "bin/bower" as developers are using it directly ([#2157](https://github.com/bower/bower/issues/2157))
|
||||
Note: Correctly, you should use an alias created in `npm bin --global`.
|
||||
|
||||
## 1.7.5 - 2016-01-26
|
||||
|
||||
- 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))
|
||||
- When strictSsl is false, set GIT_SSL_NO_VERIFY=true ([#2129](https://github.com/bower/bower/issues/2129))
|
||||
- Distribute bower with npm@3 for better Windows support ([#2146](https://github.com/bower/bower/issues/2146))
|
||||
- Update request to 2.67.0 and fs-write-stream-atomic to 1.0.8
|
||||
- Documentation improvements
|
||||
|
||||
## 1.7.4 - 2016-01-21
|
||||
|
||||
Unpublished because of issue with npm distribution:
|
||||
https://github.com/npm/npm/issues/11227
|
||||
|
||||
## 1.7.3 - 2016-01-20
|
||||
|
||||
Unpublished because of issue with npm distribution:
|
||||
https://github.com/npm/npm/issues/11227
|
||||
|
||||
## 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
|
||||
- Improved downloader that properly cleans after itself
|
||||
- Fix shallow host detection ([#2040](https://github.com/bower/bower/pull/2040))
|
||||
- Upgrade to ([bower-config#1.2.3](https://github.com/bower/config/releases/tag/1.2.3))
|
||||
- Properly restore env variables if they are undefined at the beginning
|
||||
- Properly handle `default` setting for config.ca
|
||||
- Display proper error if .bowerrc is a directory instead of file
|
||||
|
||||
## 1.6.7 - 2015-11-26
|
||||
|
||||
- Bundless all the dependencies again
|
||||
|
||||
## 1.6.6 - 2015-11-25
|
||||
|
||||
- Fixes regression with the published npm version
|
||||
|
||||
## 1.6.5 - 2015-10-24
|
||||
|
||||
- Updates to tests and documentation
|
||||
- Fixes passing options when requesting downloads
|
||||
|
||||
## 1.6.4 - 2015-10-24
|
||||
|
||||
- Fix ignoring dependencies on multiple install run ([#1970](https://github.com/bower/bower/pull/1970))
|
||||
- Use --non-interactive when running svn client ([#1969](https://github.com/bower/bower/pull/1969))
|
||||
- Fix downloading of URLs ending with slash ([#1956](https://github.com/bower/bower/pull/1956))
|
||||
- Add user-agent field for downloads by Bower ([#1960](https://github.com/bower/bower/pull/1960))
|
||||
|
||||
## 1.6.3 - 2015-10-16
|
||||
|
||||
Fixes regression issues introduced with 1.6.2, specifically:
|
||||
|
||||
- Allow for bower_components to be a symlink
|
||||
- Allow setting custom registry in .bowerrc
|
||||
|
||||
## 1.6.2 - 2015-10-15
|
||||
|
||||
Fix dependency issues of 1.6.1. First published release of 1.6.x.
|
||||
|
||||
## 1.6.1 - 2015-10-15
|
||||
|
||||
Fix dependency issues of 1.6.0. Reverted release.
|
||||
|
||||
## 1.6.0 - 2015-10-15
|
||||
|
||||
- Shrinkwrap all dependencies and add them to bundledDependencies ([#1948](https://github.com/bower/bower/pull/1948))
|
||||
- Allow for ignoring of child dependencies ([#1394](https://github.com/bower/bower/pull/1394))
|
||||
- Allow passing `--config.resolvers` through CLI ([#1922](https://github.com/bower/bower/pull/1922))
|
||||
- Use defaults values from package.json if it exists (bower init) ([#1731](https://github.com/bower/bower/issues/1731))
|
||||
- Properly use cerificates set in .bowerrc ([#1869](https://github.com/bower/bower/pull/1869))
|
||||
- Include package name when version conflict occurs ([#1917](https://github.com/bower/bower/pull/1917))
|
||||
- Add timeout for permission check ([yeoman/insight#35](https://github.com/yeoman/insight/pull/35))
|
||||
- Close file-handles when possible. Prevents all sorts of permission issues on Windows ([0bb1536](https://github.com/bower/bower/commit/0bb1536c9972e13f3be06bea9a8619632966c664))
|
||||
- Prevent ENOENT error on Windows when in VM environment ([isaacs/chmodr#8](https://github.com/isaacs/chmodr/pull/8))
|
||||
|
||||
Reverted release.
|
||||
|
||||
## 1.5.4 - 2015-11-24
|
||||
|
||||
- [fix] Lock lru-cache dependency to 2.7.0
|
||||
@@ -157,7 +9,7 @@ Reverted release.
|
||||
- Revert auto sorting of bower dependencies, fixes ([#1897](https://github.com/bower/bower/issues/1897))
|
||||
- Fix --save-exact feature for github endpoints, fixes ([#1925](https://github.com/bower/bower/issues/1925))
|
||||
- Fix `bower init` to support private flag again ([#1819](https://github.com/bower/bower/pull/1819))
|
||||
- Bump insight dependency to support prompt timeout ([#1102](https://github.com/bower/bower/issues/1102))
|
||||
- Bump insight dependency to support prompt timeout ([#1102](https://github.com/bower/bower/issues/1102))
|
||||
|
||||
## 1.5.2 - 2015-08-25
|
||||
|
||||
@@ -177,10 +29,6 @@ Reverted release.
|
||||
- Make bower commands work from subdirectories ([#1866](https://github.com/bower/bower/issues/1866))
|
||||
- No longer prefer installing bower as global module ([#1865](https://github.com/bower/bower/issues/1865))
|
||||
|
||||
## 1.4.2 - 2015-11-24
|
||||
|
||||
- [fix] Lock lru-cache dependency to 2.7.0
|
||||
|
||||
## 1.4.1 - 2015-04-01
|
||||
|
||||
- [fix] Reading .bowerrc upwards directory tree ([#1763](https://github.com/bower/bower/issues/1763))
|
||||
|
||||
@@ -1,26 +1,35 @@
|
||||
# Contributing to Bower
|
||||
|
||||
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 a Bower maintainer or supporting in any way, please fill 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)
|
||||
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. (Jan 2014)
|
||||
|
||||
## Casual Involvement
|
||||
|
||||
* Improve the bower.io site ([tickets](https://github.com/bower/bower.github.io/issues))
|
||||
* Move forward [bower.io redesign](https://github.com/bower/bower.github.io/issues/7)
|
||||
* Attend team meetings
|
||||
* Comment on issues and drive to resolution
|
||||
|
||||
## High-impact Involvement
|
||||
|
||||
* Maintaining the bower client.
|
||||
* Maintaining the bower client.
|
||||
* [Authoring client tests](https://github.com/bower/bower/issues/801)
|
||||
* Read [Architecture doc](https://github.com/bower/bower/wiki/Rewrite-architecture)
|
||||
* Triage, close, fix and resolve [issues](https://github.com/bower/bower/issues)
|
||||
* Developing the [new registry server](https://github.com/bower/registry/tree/node_rewrite)
|
||||
* Hooking in to Elastic Search rather than the in-memory search
|
||||
* Getting bower/registry-client to talk to the new server without breaking backwards compatibility
|
||||
* DevOps for the server
|
||||
|
||||
## Team Meetings
|
||||
|
||||
We communicate through a channel on slack: https://gitter.im/bower
|
||||
We meet on Monday at 1:00pm PST, 9:00pm UTC in #bower on Freenode. [The meeting notes](http://goo.gl/NJZ1o2).
|
||||
|
||||
<hr>
|
||||
|
||||
Following these guidelines helps to communicate that you respect the time of
|
||||
the developers managing and developing this open source project. In return,
|
||||
they should reciprocate that respect in addressing your issue, assessing
|
||||
changes, and helping you finalize your pull requests.
|
||||
|
||||
If you'd like to attend the meetings, please fill the [support form](http://goo.gl/forms/P1ndzCNoiG), and you'll get an invite.
|
||||
|
||||
## Using the issue tracker
|
||||
|
||||
@@ -29,8 +38,7 @@ The issue tracker is the preferred channel for [bug reports](#bugs),
|
||||
requests](#pull-requests), but please respect the following restrictions:
|
||||
|
||||
* Please **do not** use the issue tracker for personal support requests. Use
|
||||
[Stack Overflow](http://stackoverflow.com/questions/tagged/bower)
|
||||
[Gitter Channel](https://gitter.im/bower/bower)
|
||||
[Stack Overflow](http://stackoverflow.com/questions/tagged/bower), our
|
||||
[Mailing List](http://groups.google.com/group/twitter-bower)
|
||||
(twitter-bower@googlegroups.com), or
|
||||
[#bower](http://webchat.freenode.net/?channels=bower) on Freenode.
|
||||
@@ -38,6 +46,49 @@ 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
|
||||
|
||||
@@ -121,8 +172,6 @@ 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.
|
||||
|
||||
|
||||
@@ -3,10 +3,24 @@ module.exports = function (grunt) {
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
grunt.initConfig({
|
||||
jshint: {
|
||||
options: {
|
||||
jshintrc: '.jshintrc'
|
||||
},
|
||||
files: [
|
||||
'Gruntfile.js',
|
||||
'bin/*',
|
||||
'lib/**/*.js',
|
||||
'test/**/*.js',
|
||||
'!test/assets/**/*',
|
||||
'!test/reports/**/*',
|
||||
'!test/tmp/**/*'
|
||||
]
|
||||
},
|
||||
simplemocha: {
|
||||
options: {
|
||||
reporter: 'spec',
|
||||
timeout: '10000'
|
||||
timeout: '15000'
|
||||
},
|
||||
full: {
|
||||
src: ['test/test.js']
|
||||
@@ -19,6 +33,12 @@ module.exports = function (grunt) {
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
assets: {
|
||||
command: 'node test/packages.js && node test/packages-svn.js'
|
||||
},
|
||||
'assets-force': {
|
||||
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'
|
||||
},
|
||||
@@ -27,21 +47,14 @@ module.exports = function (grunt) {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
files: [
|
||||
'Gruntfile.js',
|
||||
'bin/*',
|
||||
'lib/**/*.js',
|
||||
'test/**/*.js',
|
||||
'!test/assets/**/*',
|
||||
'!test/reports/**/*',
|
||||
'!test/tmp/**/*'
|
||||
],
|
||||
tasks: ['simplemocha:short']
|
||||
files: ['<%= jshint.files %>'],
|
||||
tasks: ['jshint', 'simplemocha:short']
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('test', ['simplemocha:full']);
|
||||
grunt.registerTask('assets', ['exec:assets-force']);
|
||||
grunt.registerTask('test', ['jshint', 'exec:assets', 'simplemocha:full']);
|
||||
grunt.registerTask('cover', 'exec:cover');
|
||||
grunt.registerTask('travis', ['exec:cover', 'exec:coveralls']);
|
||||
grunt.registerTask('travis', ['jshint', 'exec:assets', 'exec:cover', 'exec:coveralls']);
|
||||
grunt.registerTask('default', 'test');
|
||||
};
|
||||
21
HOOKS.md
Normal file
21
HOOKS.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# 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.
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2012 Twitter and other contributors
|
||||
Copyright (c) 2015 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
|
||||
38
README.md
38
README.md
@@ -1,17 +1,10 @@
|
||||
# Bower - A package manager for the web
|
||||
# Bower
|
||||
|
||||
> Bower needs your help. If you're willing to help, please say hello to team@bower.io or [donate](https://salt.bountysource.com/teams/bower)
|
||||
|
||||
[](https://travis-ci.org/bower/bower)
|
||||
[](https://ci.appveyor.com/project/bower/bower)
|
||||
[](https://coveralls.io/r/bower/bower?branch=master)
|
||||
[](https://discord.gg/0fFM7QF0KpZRh2cY)
|
||||
[](http://issuestats.com/github/bower/bower)
|
||||
[](http://issuestats.com/github/bower/bower)
|
||||
[](https://travis-ci.org/bower/bower) [](https://ci.appveyor.com/project/sheerun/bower/history) [](https://coveralls.io/r/bower/bower?branch=master)
|
||||
|
||||
<img align="right" height="300" src="http://bower.io/img/bower-logo.png">
|
||||
|
||||
---
|
||||
> A package manager for the web
|
||||
|
||||
Bower offers a generic, unopinionated solution to the problem of **front-end package management**, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat.
|
||||
|
||||
@@ -52,7 +45,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 a 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 module loader (like [RequireJS](http://requirejs.org/)).
|
||||
|
||||
### Uninstalling packages
|
||||
|
||||
@@ -66,19 +59,18 @@ $ bower uninstall <package-name>
|
||||
|
||||
On `prezto` or `oh-my-zsh`, do not forget to `alias bower='noglob bower'` or `bower install jquery\#1.9.1`
|
||||
|
||||
### Never run Bower with sudo
|
||||
### Running commands 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.
|
||||
However, if you still want to run commands with sudo, use `--allow-root` option.
|
||||
|
||||
### Windows users
|
||||
|
||||
To use Bower on Windows, you must install
|
||||
[Git for Windows](http://git-for-windows.github.io/) correctly. Be sure to check the
|
||||
options shown below:
|
||||
[msysgit](http://msysgit.github.io/) correctly. Be sure to check the
|
||||
option shown below:
|
||||
|
||||
<img src="https://cloud.githubusercontent.com/assets/10702007/10532690/d2e8991a-7386-11e5-9a57-613c7f92e84e.png" width="534" height="418" alt="Git for Windows" />
|
||||
|
||||
<img src="https://cloud.githubusercontent.com/assets/10702007/10532694/dbe8857a-7386-11e5-9bd0-367e97644403.png" width="534" height="418" alt="Git for Windows" />
|
||||

|
||||
|
||||
Note that if you use TortoiseGit and if Bower keeps asking for your SSH
|
||||
password, you should add the following environment variable: `GIT_SSH -
|
||||
@@ -100,15 +92,17 @@ 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)
|
||||
* [Bug reports](CONTRIBUTING.md#bugs)
|
||||
* [Feature requests](CONTRIBUTING.md#features)
|
||||
* [Pull requests](CONTRIBUTING.md#pull-requests)
|
||||
|
||||
@@ -121,6 +115,6 @@ git config --global core.autocrlf input
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2016 Twitter and [other contributors](https://github.com/bower/bower/graphs/contributors)
|
||||
Copyright (c) 2015 Twitter and [other contributors](https://github.com/bower/bower/graphs/contributors)
|
||||
|
||||
Licensed under the MIT License
|
||||
|
||||
39
appveyor.yml
39
appveyor.yml
@@ -1,7 +1,6 @@
|
||||
# http://www.appveyor.com/docs/appveyor-yml
|
||||
# Thanks for Grunt for template of this file!
|
||||
|
||||
# Set build version format here instead of in the admin panel.
|
||||
version: "{build}"
|
||||
# http://www.appveyor.com/docs/appveyor-yml
|
||||
|
||||
# Fix line endings in Windows. (runs before repo cloning)
|
||||
init:
|
||||
@@ -11,35 +10,31 @@ init:
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "4.0"
|
||||
- nodejs_version: "4.1"
|
||||
- nodejs_version: "4.2"
|
||||
- nodejs_version: "5"
|
||||
- nodejs_version: "6"
|
||||
# - nodejs_version: "0.11"
|
||||
|
||||
# Finish on first failed build
|
||||
# Allow failing jobs for bleeding-edge Node.js versions.
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- nodejs_version: "0.11"
|
||||
|
||||
# Install node, display versions, install dependencies
|
||||
# Install scripts. (runs after repo cloning)
|
||||
install:
|
||||
# Get the latest stable version of Node 0.STABLE.latest
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- node --version && npm --version
|
||||
- git --version && svn --version
|
||||
# Install subversion
|
||||
- choco install svn -y
|
||||
# Install bower
|
||||
- npm install
|
||||
|
||||
# Post-install test scripts.
|
||||
test_script:
|
||||
# Output useful info for debugging.
|
||||
- node --version
|
||||
- npm --version
|
||||
- cmd: npm test
|
||||
|
||||
# Make clone much faster
|
||||
shallow_clone: true
|
||||
|
||||
# Disable Visual Studio build and deploy
|
||||
# Don't actually build.
|
||||
build: off
|
||||
deploy: off
|
||||
|
||||
# Cache node modules, and refresh if package.json changes
|
||||
cache:
|
||||
- node_modules -> package.json
|
||||
# Set build version format here instead of in the admin panel.
|
||||
version: "{build}"
|
||||
|
||||
142
bin/bower
Executable file
142
bin/bower
Executable file
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
process.bin = process.title = 'bower';
|
||||
|
||||
var Q = require('q');
|
||||
var mout = require('mout');
|
||||
var Logger = require('bower-logger');
|
||||
var userHome = require('user-home');
|
||||
var bower = require('../lib');
|
||||
var pkg = require('../package.json');
|
||||
var cli = require('../lib/util/cli');
|
||||
var rootCheck = require('../lib/util/rootCheck');
|
||||
var analytics = require('../lib/util/analytics');
|
||||
|
||||
var options;
|
||||
var renderer;
|
||||
var loglevel;
|
||||
var command;
|
||||
var commandFunc;
|
||||
var logger;
|
||||
var levels = Logger.LEVELS;
|
||||
|
||||
options = cli.readOptions({
|
||||
version: { type: Boolean, shorthand: 'v' },
|
||||
help: { type: Boolean, shorthand: 'h' },
|
||||
'allow-root': { type: Boolean }
|
||||
});
|
||||
|
||||
// Handle print of version
|
||||
if (options.version) {
|
||||
process.stdout.write(pkg.version + '\n');
|
||||
process.exit();
|
||||
}
|
||||
|
||||
// Root check
|
||||
rootCheck(options, bower.config);
|
||||
|
||||
// Set loglevel
|
||||
if (bower.config.silent) {
|
||||
loglevel = levels.error;
|
||||
} else if (bower.config.verbose) {
|
||||
loglevel = -Infinity;
|
||||
Q.longStackSupport = true;
|
||||
} else if (bower.config.quiet) {
|
||||
loglevel = levels.warn;
|
||||
} else {
|
||||
loglevel = levels[bower.config.loglevel] || levels.info;
|
||||
}
|
||||
|
||||
// Get the command to execute
|
||||
while (options.argv.remain.length) {
|
||||
command = options.argv.remain.join(' ');
|
||||
|
||||
// Alias lookup
|
||||
if (bower.abbreviations[command]) {
|
||||
command = bower.abbreviations[command].replace(/\s/g, '.');
|
||||
break;
|
||||
}
|
||||
|
||||
command = command.replace(/\s/g, '.');
|
||||
|
||||
// Direct lookup
|
||||
if (mout.object.has(bower.commands, command)) {
|
||||
break;
|
||||
}
|
||||
|
||||
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, ' ');
|
||||
|
||||
// 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';
|
||||
}
|
||||
}
|
||||
|
||||
// Get the renderer and configure it with the executed command
|
||||
renderer = cli.getRenderer(command, logger.json, bower.config);
|
||||
|
||||
logger
|
||||
.on('end', function (data) {
|
||||
if (!bower.config.silent && !bower.config.quiet) {
|
||||
renderer.end(data);
|
||||
}
|
||||
})
|
||||
.on('error', function (err) {
|
||||
if (levels.error >= loglevel) {
|
||||
renderer.error(err);
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
})
|
||||
.on('log', function (log) {
|
||||
if (levels[log.level] >= loglevel) {
|
||||
renderer.log(log);
|
||||
}
|
||||
})
|
||||
.on('prompt', function (prompt, callback) {
|
||||
renderer.prompt(prompt)
|
||||
.then(function (answer) {
|
||||
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.');
|
||||
}
|
||||
|
||||
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
lerna.json
10
lerna.json
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"lerna": "2.0.0-beta.23",
|
||||
"version": "independent",
|
||||
"publishConfig": {
|
||||
"ignore": [
|
||||
"ignored-file",
|
||||
"*.md"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
var fs = require('../../util/fs');
|
||||
var fs = require('graceful-fs');
|
||||
var path = require('path');
|
||||
var mout = require('mout');
|
||||
var Q = require('q');
|
||||
var rimraf = require('../../util/rimraf');
|
||||
var rimraf = require('rimraf');
|
||||
var endpointParser = require('bower-endpoint-parser');
|
||||
var PackageRepository = require('../../core/PackageRepository');
|
||||
var semver = require('../../util/semver');
|
||||
@@ -1,15 +1,15 @@
|
||||
var Q = require('q');
|
||||
var path = require('path');
|
||||
var fs = require('../util/fs');
|
||||
var fs = require('graceful-fs');
|
||||
var createError = require('../util/createError');
|
||||
|
||||
function help(logger, name, config) {
|
||||
var json;
|
||||
|
||||
if (name) {
|
||||
json = path.resolve(__dirname, '../templates/json/help-' + name.replace(/\s+/g, '/') + '.json');
|
||||
json = path.resolve(__dirname, '../../templates/json/help-' + name.replace(/\s+/g, '/') + '.json');
|
||||
} else {
|
||||
json = path.resolve(__dirname, '../templates/json/help.json');
|
||||
json = path.resolve(__dirname, '../../templates/json/help.json');
|
||||
}
|
||||
|
||||
return Q.promise(function (resolve) {
|
||||
@@ -40,7 +40,7 @@ function home(logger, name, config) {
|
||||
throw createError('No homepage set for ' + pkgMeta.name, 'ENOHOME');
|
||||
}
|
||||
|
||||
open(homepage, { wait: false });
|
||||
open(homepage);
|
||||
return homepage;
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
var Q = require('q');
|
||||
var Logger = require('bower-logger');
|
||||
var config = require('../config');
|
||||
|
||||
/**
|
||||
* Require commands only when called.
|
||||
@@ -10,24 +9,24 @@ var config = require('../config');
|
||||
* return as soon as possible and load and execute the command asynchronously.
|
||||
*/
|
||||
function commandFactory(id) {
|
||||
function runApi() {
|
||||
var command = require(id);
|
||||
if (process.env.STRICT_REQUIRE) {
|
||||
require(id);
|
||||
}
|
||||
|
||||
function command() {
|
||||
var commandArgs = [].slice.call(arguments);
|
||||
|
||||
return withLogger(function (logger) {
|
||||
commandArgs.unshift(logger);
|
||||
|
||||
return command.apply(undefined, commandArgs);
|
||||
return require(id).apply(undefined, commandArgs);
|
||||
});
|
||||
}
|
||||
|
||||
function runFromArgv(argv) {
|
||||
var commandArgs;
|
||||
var command = require(id);
|
||||
|
||||
commandArgs = command.readOptions(argv);
|
||||
|
||||
return withLogger(function (logger) {
|
||||
var command = require(id);
|
||||
|
||||
var commandArgs = command.readOptions(argv);
|
||||
commandArgs.unshift(logger);
|
||||
|
||||
return command.apply(undefined, commandArgs);
|
||||
@@ -39,21 +38,19 @@ function commandFactory(id) {
|
||||
|
||||
Q.try(func, logger)
|
||||
.done(function () {
|
||||
config.restore();
|
||||
var args = [].slice.call(arguments);
|
||||
args.unshift('end');
|
||||
logger.emit.apply(logger, args);
|
||||
}, function (error) {
|
||||
config.restore();
|
||||
logger.emit('error', error);
|
||||
});
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
runApi.line = runFromArgv;
|
||||
command.line = runFromArgv;
|
||||
|
||||
return runApi;
|
||||
return command;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ 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) {
|
||||
@@ -11,11 +12,14 @@ 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,11 +1,12 @@
|
||||
var mout = require('mout');
|
||||
var fs = require('../util/fs');
|
||||
var fs = require('graceful-fs');
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
var endpointParser = require('bower-endpoint-parser');
|
||||
var Project = require('../core/Project');
|
||||
var defaultConfig = require('../config');
|
||||
var GitHubResolver = require('../core/resolvers/GitHubResolver');
|
||||
var GitFsResolver = require('../core/resolvers/GitFsResolver');
|
||||
var cmd = require('../util/cmd');
|
||||
var createError = require('../util/createError');
|
||||
|
||||
@@ -101,6 +102,19 @@ function setDefaults(config, json) {
|
||||
json.name = path.basename(config.cwd);
|
||||
}
|
||||
|
||||
// Version
|
||||
if (!json.version) {
|
||||
// Assume latest semver tag if it's a git repo
|
||||
promise = promise.then(function () {
|
||||
return GitFsResolver.versions(config.cwd)
|
||||
.then(function (versions) {
|
||||
json.version = versions[0] || '0.0.0';
|
||||
}, function () {
|
||||
json.version = '0.0.0';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Main
|
||||
if (!json.main) {
|
||||
// Remove '.js' from the end of the package name if it is there
|
||||
@@ -174,6 +188,12 @@ function promptUser(logger, json) {
|
||||
'default': json.name,
|
||||
'type': 'input'
|
||||
},
|
||||
{
|
||||
'name': 'version',
|
||||
'message': 'version',
|
||||
'default': json.version,
|
||||
'type': 'input'
|
||||
},
|
||||
{
|
||||
'name': 'description',
|
||||
'message': 'description',
|
||||
@@ -186,6 +206,12 @@ function promptUser(logger, json) {
|
||||
'default': json.main,
|
||||
'type': 'input'
|
||||
},
|
||||
{
|
||||
'name': 'moduleType',
|
||||
'message': 'what types of modules does this package expose?',
|
||||
'type': 'checkbox',
|
||||
'choices': ['amd', 'es6', 'globals', 'node', 'yui']
|
||||
},
|
||||
{
|
||||
'name': 'keywords',
|
||||
'message': 'keywords',
|
||||
@@ -233,8 +259,10 @@ function promptUser(logger, json) {
|
||||
return Q.nfcall(logger.prompt.bind(logger), questions)
|
||||
.then(function (answers) {
|
||||
json.name = answers.name;
|
||||
json.version = answers.version;
|
||||
json.description = answers.description;
|
||||
json.main = answers.main;
|
||||
json.moduleType = answers.moduleType;
|
||||
json.keywords = toArray(answers.keywords);
|
||||
json.authors = toArray(answers.authors, ',');
|
||||
json.license = answers.license;
|
||||
@@ -1,10 +1,12 @@
|
||||
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);
|
||||
@@ -12,12 +14,14 @@ 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);
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
var path = require('path');
|
||||
var rimraf = require('../util/rimraf');
|
||||
var rimraf = require('rimraf');
|
||||
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) {
|
||||
@@ -50,7 +49,7 @@ function linkTo(logger, name, localName, config) {
|
||||
|
||||
localName = localName || name;
|
||||
src = path.join(config.storage.links, name);
|
||||
dst = path.join(relativeToBaseDir(config.cwd)(config.directory), localName);
|
||||
dst = path.join(config.cwd, config.directory, localName);
|
||||
|
||||
// Delete destination folder if any
|
||||
return Q.nfcall(rimraf, dst)
|
||||
@@ -63,7 +63,6 @@ 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) {
|
||||
@@ -96,7 +95,6 @@ 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,5 +1,5 @@
|
||||
var Q = require('q');
|
||||
var PackageRepository = require('../core/PackageRepository');
|
||||
var RegistryClient = require('bower-registry-client');
|
||||
var defaultConfig = require('../config');
|
||||
|
||||
function lookup(logger, name, config) {
|
||||
@@ -7,13 +7,17 @@ function lookup(logger, name, config) {
|
||||
return new Q(null);
|
||||
}
|
||||
|
||||
config = defaultConfig(config);
|
||||
var registryClient;
|
||||
|
||||
var repository = new PackageRepository(config, logger);
|
||||
var registryClient = repository.getRegistryClient();
|
||||
config = defaultConfig(config);
|
||||
config.cache = config.storage.registry;
|
||||
|
||||
registryClient = new RegistryClient(config, logger);
|
||||
|
||||
return Q.nfcall(registryClient.lookup.bind(registryClient), name)
|
||||
.then(function (entry) {
|
||||
// TODO: Handle entry.type.. for now it's only 'alias'
|
||||
// When we got published packages, this needs to be adjusted
|
||||
return !entry ? null : {
|
||||
name: name,
|
||||
url: entry && entry.url
|
||||
@@ -1,26 +1,25 @@
|
||||
var mout = require('mout');
|
||||
var Q = require('q');
|
||||
var chalk = require('chalk');
|
||||
var PackageRepository = require('../core/PackageRepository');
|
||||
var Config = require('bower-config');
|
||||
var Tracker = require('../util/analytics').Tracker;
|
||||
var createError = require('../util/createError');
|
||||
var defaultConfig = require('../config');
|
||||
var GitHubResolver = require('../core/resolvers/GitHubResolver');
|
||||
|
||||
function register(logger, name, source, config) {
|
||||
function register(logger, name, url, config) {
|
||||
var repository;
|
||||
var registryClient;
|
||||
var tracker;
|
||||
var force;
|
||||
var url;
|
||||
var githubSourceRegex = /^\w[\w-]*\/\w[\w-]*$/;
|
||||
var getGithubUrl = function (source) {
|
||||
return 'git@github.com:' + source + '.git';
|
||||
};
|
||||
|
||||
config = defaultConfig(config);
|
||||
force = config.force;
|
||||
tracker = new Tracker(config);
|
||||
|
||||
name = (name || '').trim();
|
||||
source = (source || '').trim();
|
||||
|
||||
url = source.match(githubSourceRegex) ? getGithubUrl(source) : source;
|
||||
url = (url || '').trim();
|
||||
|
||||
// Bypass any cache
|
||||
config.offline = false;
|
||||
@@ -32,6 +31,18 @@ function register(logger, name, source, config) {
|
||||
throw createError('Usage: bower register <name> <url>', 'EINVFORMAT');
|
||||
}
|
||||
|
||||
// The public registry only allows git:// endpoints
|
||||
// As such, we attempt to convert URLs as necessary
|
||||
if (config.registry.register === Config.DEFAULT_REGISTRY) {
|
||||
url = convertUrl(url, logger);
|
||||
|
||||
if (!mout.string.startsWith(url, 'git://')) {
|
||||
throw createError('The registry only accepts URLs starting with git://', '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);
|
||||
@@ -73,6 +84,22 @@ function register(logger, name, source, config) {
|
||||
});
|
||||
}
|
||||
|
||||
function convertUrl(url, logger) {
|
||||
var pair;
|
||||
var newUrl;
|
||||
|
||||
if (!mout.string.startsWith(url, 'git://')) {
|
||||
// Convert GitHub ssh & https to git://
|
||||
pair = GitHubResolver.getOrgRepoPair(url);
|
||||
if (pair) {
|
||||
newUrl = 'git://github.com/' + pair.org + '/' + pair.repo + '.git';
|
||||
logger.warn('convert', 'Converted ' + url + ' to ' + newUrl);
|
||||
}
|
||||
}
|
||||
|
||||
return newUrl || url;
|
||||
}
|
||||
|
||||
// -------------------
|
||||
|
||||
register.readOptions = function (argv) {
|
||||
36
lib/commands/search.js
Normal file
36
lib/commands/search.js
Normal file
@@ -0,0 +1,36 @@
|
||||
var Q = require('q');
|
||||
var RegistryClient = require('bower-registry-client');
|
||||
var Tracker = require('../util/analytics').Tracker;
|
||||
var defaultConfig = require('../config');
|
||||
|
||||
function search(logger, name, config) {
|
||||
var registryClient;
|
||||
var tracker;
|
||||
|
||||
config = defaultConfig(config);
|
||||
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 {
|
||||
return Q.nfcall(registryClient.search.bind(registryClient), name);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------
|
||||
|
||||
search.readOptions = function (argv) {
|
||||
var cli = require('../util/cli');
|
||||
var options = cli.readOptions(argv);
|
||||
var name = options.argv.remain.slice(1).join(' ');
|
||||
|
||||
return [name];
|
||||
};
|
||||
|
||||
module.exports = search;
|
||||
@@ -1,6 +1,7 @@
|
||||
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) {
|
||||
@@ -9,10 +10,14 @@ 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,6 +3,7 @@ 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) {
|
||||
@@ -13,10 +14,12 @@ 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;
|
||||
@@ -27,6 +30,8 @@ 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')
|
||||
@@ -59,6 +64,7 @@ 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;
|
||||
128
lib/commands/version.js
Normal file
128
lib/commands/version.js
Normal file
@@ -0,0 +1,128 @@
|
||||
var semver = require('semver');
|
||||
var which = require('which');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
var execFile = require('child_process').execFile;
|
||||
var Project = require('../core/Project');
|
||||
var defaultConfig = require('../config');
|
||||
var createError = require('../util/createError');
|
||||
|
||||
function version(logger, versionArg, options, config) {
|
||||
var project;
|
||||
|
||||
options = options || {};
|
||||
config = defaultConfig(config);
|
||||
project = new Project(config, logger);
|
||||
|
||||
return bump(project, versionArg, options.message);
|
||||
}
|
||||
|
||||
function bump(project, versionArg, message) {
|
||||
var cwd = project._config.cwd || process.cwd();
|
||||
var newVersion;
|
||||
var doGitCommit = false;
|
||||
|
||||
return checkGit(cwd)
|
||||
.then(function (hasGit) {
|
||||
doGitCommit = hasGit;
|
||||
})
|
||||
.then(project.getJson.bind(project))
|
||||
.then(function (json) {
|
||||
newVersion = getNewVersion(json.version, versionArg);
|
||||
json.version = newVersion;
|
||||
})
|
||||
.then(project.saveJson.bind(project))
|
||||
.then(function () {
|
||||
if (doGitCommit) {
|
||||
return gitCommitAndTag(cwd, newVersion, message);
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
console.log('v' + newVersion);
|
||||
return newVersion;
|
||||
});
|
||||
}
|
||||
|
||||
function getNewVersion(currentVersion, versionArg) {
|
||||
var newVersion = semver.valid(versionArg);
|
||||
if (!newVersion) {
|
||||
newVersion = semver.inc(currentVersion, versionArg);
|
||||
}
|
||||
if (!newVersion) {
|
||||
throw createError('Invalid version argument: `' + versionArg + '`. Usage: `bower version [<newversion> | major | minor | patch]`', 'EINVALIDVERSION');
|
||||
}
|
||||
if (currentVersion === newVersion) {
|
||||
throw createError('Version not changed', 'EVERSIONNOTCHANGED');
|
||||
}
|
||||
return newVersion;
|
||||
}
|
||||
|
||||
function checkGit(cwd) {
|
||||
var gitDir = path.join(cwd, '.git');
|
||||
return Q.nfcall(fs.stat, gitDir)
|
||||
.then(function (stat) {
|
||||
if (stat.isDirectory()) {
|
||||
return checkGitStatus(cwd);
|
||||
}
|
||||
return false;
|
||||
}, function () {
|
||||
//Ignore not found .git directory
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function checkGitStatus(cwd) {
|
||||
return Q.nfcall(which, 'git')
|
||||
.fail(function (err) {
|
||||
err.code = 'ENOGIT';
|
||||
throw err;
|
||||
})
|
||||
.then(function () {
|
||||
return Q.nfcall(execFile, 'git', ['status', '--porcelain'], {env: process.env, cwd: cwd});
|
||||
})
|
||||
.then(function (value) {
|
||||
var stdout = value[0];
|
||||
var lines = filterModifiedStatusLines(stdout);
|
||||
if (lines.length) {
|
||||
throw createError('Git working directory not clean.\n' + lines.join('\n'), 'EWORKINGDIRECTORYDIRTY');
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
function filterModifiedStatusLines(stdout) {
|
||||
return stdout.trim().split('\n')
|
||||
.filter(function (line) {
|
||||
return line.trim() && !line.match(/^\?\? /);
|
||||
}).map(function (line) {
|
||||
return line.trim();
|
||||
});
|
||||
}
|
||||
|
||||
function gitCommitAndTag(cwd, newVersion, message) {
|
||||
var tag = 'v' + newVersion;
|
||||
message = message || tag;
|
||||
message = message.replace(/%s/g, newVersion);
|
||||
return Q.nfcall(execFile, 'git', ['add', 'bower.json'], {env: process.env, cwd: cwd})
|
||||
.then(function () {
|
||||
return Q.nfcall(execFile, 'git', ['commit', '-m', message], {env: process.env, cwd: cwd});
|
||||
})
|
||||
.then(function () {
|
||||
return Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], {env: process.env, cwd: cwd});
|
||||
});
|
||||
}
|
||||
|
||||
// -------------------
|
||||
|
||||
version.readOptions = function (argv) {
|
||||
var cli = require('../util/cli');
|
||||
|
||||
var options = cli.readOptions({
|
||||
'message': { type: String, shorthand: 'm'}
|
||||
}, argv);
|
||||
|
||||
return [options.argv.remain[1], options];
|
||||
};
|
||||
|
||||
module.exports = version;
|
||||
@@ -3,23 +3,30 @@ var object = require('mout').object;
|
||||
var bowerConfig = require('bower-config');
|
||||
var Configstore = require('configstore');
|
||||
|
||||
var current;
|
||||
var cachedConfigs = {};
|
||||
|
||||
function defaultConfig(config) {
|
||||
config = config || {};
|
||||
|
||||
return readCachedConfig(config.cwd || process.cwd(), config);
|
||||
var cachedConfig = readCachedConfig(config.cwd || process.cwd());
|
||||
|
||||
return object.merge(cachedConfig, config);
|
||||
}
|
||||
|
||||
function readCachedConfig(cwd, overwrites) {
|
||||
current = bowerConfig.create(cwd).load(overwrites);
|
||||
|
||||
var config = current.toObject();
|
||||
function readCachedConfig(cwd) {
|
||||
if (cachedConfigs[cwd]) {
|
||||
return cachedConfigs[cwd];
|
||||
}
|
||||
|
||||
var config = cachedConfigs[cwd] = bowerConfig.read(cwd);
|
||||
var configstore = new Configstore('bower-github').all;
|
||||
|
||||
object.mixIn(config, configstore);
|
||||
|
||||
// Delete the json attribute because it is no longer supported
|
||||
// and conflicts with --json
|
||||
delete config.json;
|
||||
|
||||
// If interactive is auto (null), guess its value
|
||||
if (config.interactive == null) {
|
||||
config.interactive = (
|
||||
@@ -47,17 +54,9 @@ function readCachedConfig(cwd, overwrites) {
|
||||
return config;
|
||||
}
|
||||
|
||||
function restoreConfig() {
|
||||
if (current) {
|
||||
current.restore();
|
||||
}
|
||||
}
|
||||
|
||||
function resetCache() {
|
||||
restoreConfig();
|
||||
current = undefined;
|
||||
function resetCache () {
|
||||
cachedConfigs = {};
|
||||
}
|
||||
|
||||
module.exports = defaultConfig;
|
||||
module.exports.restore = restoreConfig;
|
||||
module.exports.reset = resetCache;
|
||||
@@ -2,15 +2,14 @@ var Q = require('q');
|
||||
var mout = require('mout');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var rimraf = require('../util/rimraf');
|
||||
var fs = require('../util/fs');
|
||||
var rimraf = require('rimraf');
|
||||
var fs = require('graceful-fs');
|
||||
var endpointParser = require('bower-endpoint-parser');
|
||||
var PackageRepository = require('./PackageRepository');
|
||||
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;
|
||||
@@ -24,13 +23,11 @@ function Manager(config, logger) {
|
||||
|
||||
Manager.prototype.configure = function (setup) {
|
||||
var targetsHash = {};
|
||||
|
||||
this._conflicted = {};
|
||||
|
||||
// Targets - ignore those specified in ignoredDependencies
|
||||
this._targets = mout.array.reject(setup.targets || [], function (target) {
|
||||
return mout.array.contains(this._config.ignoredDependencies, target.name );
|
||||
}, this);
|
||||
|
||||
// Targets
|
||||
this._targets = setup.targets || [];
|
||||
this._targets.forEach(function (decEndpoint) {
|
||||
decEndpoint.initialName = decEndpoint.name;
|
||||
decEndpoint.dependants = mout.object.values(decEndpoint.dependants);
|
||||
@@ -125,7 +122,7 @@ Manager.prototype.resolve = function () {
|
||||
|
||||
Manager.prototype.preinstall = function (json) {
|
||||
var that = this;
|
||||
var componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
var componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
|
||||
// If nothing to install, skip the code bellow
|
||||
if (mout.lang.isEmpty(that._dissected)) {
|
||||
@@ -142,7 +139,7 @@ Manager.prototype.preinstall = function (json) {
|
||||
|
||||
Manager.prototype.postinstall = function (json) {
|
||||
var that = this;
|
||||
var componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
var componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
|
||||
// If nothing to install, skip the code bellow
|
||||
if (mout.lang.isEmpty(that._dissected)) {
|
||||
@@ -159,7 +156,6 @@ Manager.prototype.postinstall = function (json) {
|
||||
|
||||
Manager.prototype.install = function (json) {
|
||||
var componentsDir;
|
||||
var componentsDirContents;
|
||||
var that = this;
|
||||
|
||||
// If already resolving, error out
|
||||
@@ -172,29 +168,20 @@ Manager.prototype.install = function (json) {
|
||||
return Q.resolve({});
|
||||
}
|
||||
|
||||
componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
return Q.nfcall(mkdirp, componentsDir)
|
||||
.then(function () {
|
||||
var promises = [];
|
||||
componentsDirContents = fs.readdirSync(componentsDir);
|
||||
|
||||
mout.object.forOwn(that._dissected, function (decEndpoint, name) {
|
||||
var promise;
|
||||
var dst;
|
||||
var release = decEndpoint.pkgMeta._release;
|
||||
var exists = mout.array.contains(componentsDirContents, name);
|
||||
|
||||
that._logger.action('install', name + (release ? '#' + release : ''), that.toData(decEndpoint));
|
||||
|
||||
dst = path.join(componentsDir, name);
|
||||
|
||||
if (exists && !that._installed[name] && !that._config.force) {
|
||||
// There is a folder in the components directory that has
|
||||
// this name, but it was not installed by bower.
|
||||
that._logger.warn('skipped', name + ' was not installed because there is already a non-bower directory with that name in the components directory (' + path.relative(that._config.cwd, dst) + '). You can force installation with --force.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove existent and copy canonical dir
|
||||
promise = Q.nfcall(rimraf, dst)
|
||||
.then(copy.copyDir.bind(copy, decEndpoint.canonicalDir, dst))
|
||||
@@ -386,7 +373,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;
|
||||
}
|
||||
@@ -458,12 +445,6 @@ Manager.prototype._parseDependencies = function (decEndpoint, pkgMeta) {
|
||||
var compatible;
|
||||
var childDecEndpoint = endpointParser.json2decomposed(key, value);
|
||||
|
||||
// Check if this depdendency should be skipped.
|
||||
if (mout.array.contains(this._config.ignoredDependencies, childDecEndpoint.name)) {
|
||||
this._logger.action('skipped', childDecEndpoint.name, this.toData(decEndpoint));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if a compatible one is already resolved
|
||||
// If there's one, we don't need to resolve it twice
|
||||
resolved = this._resolved[key];
|
||||
@@ -595,7 +576,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 = '*';
|
||||
}
|
||||
});
|
||||
@@ -635,7 +616,7 @@ Manager.prototype._dissect = function () {
|
||||
}, this);
|
||||
|
||||
// Filter only packages that need to be installed
|
||||
componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
componentsDir = path.resolve(that._config.cwd, that._config.directory);
|
||||
this._dissected = mout.object.filter(suitables, function (decEndpoint, name) {
|
||||
var installedMeta = this._installed[name];
|
||||
var dst;
|
||||
@@ -678,8 +659,6 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) {
|
||||
var save;
|
||||
var choices;
|
||||
var picks = [];
|
||||
var versionRegex = /(?:[\d\w]\.){2}[\d\w](?:.)*/;
|
||||
var picksReleases;
|
||||
|
||||
// If there are both semver and non-semver, there's no way
|
||||
// to figure out the suitable one
|
||||
@@ -835,21 +814,14 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) {
|
||||
});
|
||||
|
||||
choices = picks.map(function (pick, index) { return index + 1; });
|
||||
picksReleases = picks.map(function (pick) { return pick.pkgMeta._release; });
|
||||
return Q.nfcall(this._logger.prompt.bind(this._logger), {
|
||||
type: 'input',
|
||||
message: 'Answer',
|
||||
validate: function (choice) {
|
||||
var invalidChoice = 'Invalid choice';
|
||||
|
||||
if (choice.match(versionRegex)) {
|
||||
return picksReleases.indexOf(choice) != -1 ? true : invalidChoice;
|
||||
}
|
||||
|
||||
choice = Number(mout.string.trim(choice.trim(), '!'));
|
||||
|
||||
if (!choice || choice < 1 || choice > picks.length) {
|
||||
return invalidChoice;
|
||||
return 'Invalid choice';
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -861,13 +833,8 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) {
|
||||
// Sanitize choice
|
||||
choice = choice.trim();
|
||||
save = /^!/.test(choice) || /!$/.test(choice); // Save if prefixed or suffixed with !
|
||||
|
||||
if (choice.match(versionRegex)) {
|
||||
pick = picks[picksReleases.indexOf(choice)];
|
||||
} else {
|
||||
choice = Number(mout.string.trim(choice, '!'));
|
||||
pick = picks[choice - 1];
|
||||
}
|
||||
choice = Number(mout.string.trim(choice, '!'));
|
||||
pick = picks[choice - 1];
|
||||
|
||||
// Save resolution
|
||||
if (save) {
|
||||
@@ -1,12 +1,11 @@
|
||||
var mout = require('mout');
|
||||
var Q = require('q');
|
||||
var RegistryClient = require('bower-registry-client');
|
||||
var ResolveCache = require('./ResolveCache');
|
||||
var resolverFactory = require('./resolverFactory');
|
||||
var createError = require('../util/createError');
|
||||
var RegistryClient = require('bower-registry-client');
|
||||
|
||||
function PackageRepository(config, logger) {
|
||||
|
||||
var registryOptions;
|
||||
|
||||
this._config = config;
|
||||
@@ -15,7 +14,6 @@ function PackageRepository(config, logger) {
|
||||
// Instantiate the registry
|
||||
registryOptions = mout.object.deepMixIn({}, this._config);
|
||||
registryOptions.cache = this._config.storage.registry;
|
||||
|
||||
this._registryClient = new RegistryClient(registryOptions, logger);
|
||||
|
||||
// Instantiate the resolve cache
|
||||
@@ -89,7 +87,7 @@ PackageRepository.prototype.fetch = function (decEndpoint) {
|
||||
}
|
||||
|
||||
// Otherwise check for new contents
|
||||
logger.action('validate', (pkgMeta._release ? pkgMeta._release + ' against ' : '') +
|
||||
logger.action('validate', (pkgMeta._release ? pkgMeta._release + ' against ': '') +
|
||||
resolver.getSource() + (resolver.getTarget() ? '#' + resolver.getTarget() : ''));
|
||||
|
||||
return resolver.hasNew(pkgMeta)
|
||||
@@ -1,22 +1,26 @@
|
||||
var glob = require('glob');
|
||||
var path = require('path');
|
||||
var fs = require('../util/fs');
|
||||
var fs = require('graceful-fs');
|
||||
var Q = require('q');
|
||||
var mout = require('mout');
|
||||
var rimraf = require('../util/rimraf');
|
||||
var rimraf = require('rimraf');
|
||||
var endpointParser = require('bower-endpoint-parser');
|
||||
var Logger = require('bower-logger');
|
||||
var md5 = require('md5-hex');
|
||||
var Manager = require('./Manager');
|
||||
var defaultConfig = require('../config');
|
||||
var semver = require('../util/semver');
|
||||
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;
|
||||
// This is the only architecture component that ensures defaults
|
||||
// on config and logger
|
||||
// The reason behind it is that users can likely use this component
|
||||
// directly if commands do not fulfil their needs
|
||||
this._config = defaultConfig(config);
|
||||
this._logger = logger || new Logger();
|
||||
this._manager = new Manager(this._config, this._logger);
|
||||
|
||||
@@ -45,7 +49,7 @@ Project.prototype.install = function (decEndpoints, options, config) {
|
||||
.spread(function (json, tree) {
|
||||
// It shows an error when issuing `bower install`
|
||||
// and no bower.json is present in current directory
|
||||
if (!that._jsonFile && decEndpoints.length === 0 ) {
|
||||
if(!that._jsonFile && decEndpoints.length === 0 ) {
|
||||
throw createError('No bower.json present', 'ENOENT');
|
||||
}
|
||||
|
||||
@@ -82,14 +86,14 @@ Project.prototype.install = function (decEndpoints, options, config) {
|
||||
})
|
||||
.then(function (installed) {
|
||||
// Handle save and saveDev options
|
||||
if (that._options.save || that._options.saveDev || that._options.saveExact || that._config.save || that._config.saveExact) {
|
||||
if (that._options.save || that._options.saveDev || that._options.saveExact) {
|
||||
// Cycle through the specified endpoints
|
||||
decEndpoints.forEach(function (decEndpoint) {
|
||||
var jsonEndpoint;
|
||||
|
||||
jsonEndpoint = endpointParser.decomposed2json(decEndpoint);
|
||||
|
||||
if (that._options.saveExact || that._config.saveExact) {
|
||||
if (that._options.saveExact) {
|
||||
if (decEndpoint.name !== decEndpoint.source) {
|
||||
jsonEndpoint[decEndpoint.name] = decEndpoint.source + '#' + decEndpoint.pkgMeta.version;
|
||||
} else {
|
||||
@@ -557,29 +561,9 @@ Project.prototype._readJson = function () {
|
||||
return Q.resolve(this._json);
|
||||
}
|
||||
|
||||
return Q.fcall(function () {
|
||||
// This will throw if package.json does not exist
|
||||
return fs.readFileSync(path.join(that._config.cwd, 'package.json'));
|
||||
})
|
||||
.then(function (buffer) {
|
||||
// If package.json exists, use it's values as defaults
|
||||
var defaults = {}, npm = JSON.parse(buffer.toString());
|
||||
|
||||
defaults.name = npm.name || path.basename(that._config.cwd) || 'root';
|
||||
defaults.description = npm.description;
|
||||
defaults.main = npm.main;
|
||||
defaults.authors = npm.contributors || npm.author;
|
||||
defaults.license = npm.license;
|
||||
defaults.keywords = npm.keywords;
|
||||
|
||||
return defaults;
|
||||
})
|
||||
.catch(function (err) {
|
||||
// Most likely no package.json so just set default name
|
||||
return { name: path.basename(that._config.cwd) || 'root' };
|
||||
})
|
||||
.then(function (defaults) {
|
||||
return that._json = readJson(that._config.cwd, { assume: defaults, logger: that._logger });
|
||||
// Read local json
|
||||
return this._json = readJson(this._config.cwd, {
|
||||
assume: { name: path.basename(this._config.cwd) || 'root' }
|
||||
})
|
||||
.spread(function (json, deprecated, assumed) {
|
||||
var jsonStr;
|
||||
@@ -608,7 +592,7 @@ Project.prototype._readInstalled = function () {
|
||||
|
||||
// Gather all folders that are actual packages by
|
||||
// looking for the package metadata file
|
||||
componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
return this._installed = Q.nfcall(glob, '*/.bower.json', {
|
||||
cwd: componentsDir,
|
||||
dot: true
|
||||
@@ -649,7 +633,7 @@ Project.prototype._readLinks = function () {
|
||||
var that = this;
|
||||
|
||||
// Read directory, looking for links
|
||||
componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory);
|
||||
componentsDir = path.join(this._config.cwd, this._config.directory);
|
||||
return Q.nfcall(fs.readdir, componentsDir)
|
||||
.then(function (filenames) {
|
||||
var promises;
|
||||
@@ -741,7 +725,7 @@ Project.prototype._removePackages = function (packages) {
|
||||
}
|
||||
|
||||
// Remove from json only if successfully deleted
|
||||
if ((that._options.save || that._config.save) && that._json.dependencies) {
|
||||
if (that._options.save && that._json.dependencies) {
|
||||
promise = promise
|
||||
.then(function () {
|
||||
delete that._json.dependencies[name];
|
||||
@@ -764,9 +748,6 @@ Project.prototype._removePackages = function (packages) {
|
||||
.then(function () {
|
||||
return that.saveJson();
|
||||
})
|
||||
// Run post-uninstall hook before resolving with removed packages.
|
||||
.then(scripts.postuninstall.bind(
|
||||
null, that._config, that._logger, packages, that._installed, that._json))
|
||||
// Resolve with removed packages
|
||||
.then(function () {
|
||||
return mout.object.filter(packages, function (dir) {
|
||||
@@ -1,9 +1,9 @@
|
||||
var fs = require('../util/fs');
|
||||
var fs = require('graceful-fs');
|
||||
var path = require('path');
|
||||
var mout = require('mout');
|
||||
var Q = require('q');
|
||||
var mkdirp = require('mkdirp');
|
||||
var rimraf = require('../util/rimraf');
|
||||
var rimraf = require('rimraf');
|
||||
var LRU = require('lru-cache');
|
||||
var lockFile = require('lockfile');
|
||||
var md5 = require('md5-hex');
|
||||
@@ -1,17 +1,16 @@
|
||||
var Q = require('q');
|
||||
var fs = require('../util/fs');
|
||||
var fs = require('graceful-fs');
|
||||
var path = require('path');
|
||||
var mout = require('mout');
|
||||
var resolvers = require('./resolvers');
|
||||
var createError = require('../util/createError');
|
||||
var resolve = require('../util/resolve');
|
||||
|
||||
var pluginResolverFactory = require('./resolvers/pluginResolverFactory');
|
||||
|
||||
function createInstance(decEndpoint, options, registryClient) {
|
||||
decEndpoint = mout.object.pick(decEndpoint, ['name', 'target', 'source']);
|
||||
|
||||
options.version = require('../version');
|
||||
options.version = require('../../package.json').version;
|
||||
|
||||
return getConstructor(decEndpoint, options, registryClient)
|
||||
.spread(function (ConcreteResolver, decEndpoint) {
|
||||
@@ -25,7 +24,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 constructor of resolver
|
||||
// If a step can guess the resolver, it returns with construcotor of resolver
|
||||
|
||||
var promise = Q.resolve();
|
||||
|
||||
@@ -45,30 +44,12 @@ function getConstructor(decEndpoint, options, registryClient) {
|
||||
// its "match" to check if given resolves supports given decEndpoint
|
||||
addResolver(function () {
|
||||
var selectedResolver;
|
||||
var resolverNames;
|
||||
|
||||
if (Array.isArray(config.resolvers)) {
|
||||
resolverNames = config.resolvers;
|
||||
} else if (!!config.resolvers) {
|
||||
resolverNames = config.resolvers.split(',');
|
||||
} else {
|
||||
resolverNames = [];
|
||||
}
|
||||
var resolverNames = config.resolvers || [];
|
||||
|
||||
var resolverPromises = resolverNames.map(function (resolverName) {
|
||||
|
||||
|
||||
var resolver = resolvers[resolverName];
|
||||
|
||||
if (resolver === undefined) {
|
||||
var resolverPath = resolve(resolverName, { cwd: config.cwd });
|
||||
|
||||
if (resolverPath === undefined) {
|
||||
throw createError('Bower resolver not found: ' + resolverName, 'ENORESOLVER')
|
||||
}
|
||||
|
||||
resolver = pluginResolverFactory(require(resolverPath), options);
|
||||
}
|
||||
var resolver = resolvers[resolverName]
|
||||
|| pluginResolverFactory(require(resolverName), options);
|
||||
|
||||
return function () {
|
||||
if (selectedResolver === undefined) {
|
||||
@@ -103,7 +84,7 @@ function getConstructor(decEndpoint, options, registryClient) {
|
||||
// Git case: git git+ssh, git+http, git+https
|
||||
// .git at the end (probably ssh shorthand)
|
||||
// git@ at the start
|
||||
addResolver(function () {
|
||||
addResolver(function() {
|
||||
if (/^git(\+(ssh|https?))?:\/\//i.test(source) || /\.git\/?$/i.test(source) || /^git@/i.test(source)) {
|
||||
decEndpoint.source = source.replace(/^git\+/, '');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var util = require('util');
|
||||
var fs = require('../../util/fs');
|
||||
var fs = require('graceful-fs');
|
||||
var path = require('path');
|
||||
var mout = require('mout');
|
||||
var Q = require('q');
|
||||
@@ -38,7 +38,7 @@ function GitHubResolver(decEndpoint, config, logger) {
|
||||
}
|
||||
|
||||
// Enable shallow clones for GitHub repos
|
||||
this._shallowClone = function () {
|
||||
this._shallowClone = function() {
|
||||
return Q.resolve(true);
|
||||
};
|
||||
}
|
||||
@@ -72,7 +72,7 @@ GitHubResolver.prototype._checkout = function () {
|
||||
|
||||
// Download tarball
|
||||
return download(tarballUrl, file, {
|
||||
ca: this._config.ca.default,
|
||||
proxy: this._config.httpsProxy,
|
||||
strictSSL: this._config.strictSsl,
|
||||
timeout: this._config.timeout,
|
||||
headers: reqHeaders
|
||||
@@ -119,7 +119,7 @@ GitRemoteResolver.prototype._fastClone = function (resolution) {
|
||||
|
||||
return this._shallowClone().then(function (shallowCloningSupported) {
|
||||
// If the host does not support shallow clones, we don't use --depth=1
|
||||
if (shallowCloningSupported && !GitRemoteResolver._noShallow.get(that._host)) {
|
||||
if (shallowCloningSupported && !GitRemoteResolver._noShallow.get(this._host)) {
|
||||
args.push('--depth', 1);
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ GitRemoteResolver.prototype._supportsShallowCloning = function () {
|
||||
&& !GitRemoteResolver._canShallow.get(this._host)) {
|
||||
// Provide GIT_CURL_VERBOSE=2 environment variable to capture curl output.
|
||||
// Calling ls-remote includes a call to the git-upload-pack service, which returns the content type in the response.
|
||||
var processEnv = mout.object.merge(process.env, { 'GIT_CURL_VERBOSE': '2' });
|
||||
var processEnv = mout.object.merge(process.env, { 'GIT_CURL_VERBOSE': 2 });
|
||||
|
||||
value = cmd('git', ['ls-remote', '--heads', this._source], {
|
||||
env: processEnv
|
||||
@@ -1,7 +1,8 @@
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
var rimraf = require('../../util/rimraf');
|
||||
var chmodr = require('chmodr');
|
||||
var rimraf = require('rimraf');
|
||||
var mkdirp = require('mkdirp');
|
||||
var which = require('which');
|
||||
var LRU = require('lru-cache');
|
||||
@@ -26,8 +27,6 @@ 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();
|
||||
process.env.GIT_TERMINAL_PROMPT = config.interactive ? '1' : '0';
|
||||
|
||||
Resolver.call(this, decEndpoint, config, logger);
|
||||
|
||||
@@ -145,7 +144,7 @@ GitResolver.prototype._findResolution = function (target) {
|
||||
throw createError('No tag found that was able to satisfy ' + target, 'ENORESTARGET', {
|
||||
details: !versions.length ?
|
||||
'No versions found in ' + that._source :
|
||||
'Available versions in ' + that._source + ': ' + versions.map(function (version) { return version.version; }).join(', ')
|
||||
'Available versions: ' + versions.map(function (version) { return version.version; }).join(', ')
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -196,7 +195,23 @@ GitResolver.prototype._findResolution = function (target) {
|
||||
GitResolver.prototype._cleanup = function () {
|
||||
var gitFolder = path.join(this._tempDir, '.git');
|
||||
|
||||
return Q.nfcall(rimraf, gitFolder);
|
||||
// Remove the .git folder
|
||||
// Note that on windows, we need to chmod to 0777 before due to a bug in git
|
||||
// See: https://github.com/isaacs/rimraf/issues/19
|
||||
if (process.platform === 'win32') {
|
||||
return Q.nfcall(chmodr, gitFolder, 0777)
|
||||
.then(function () {
|
||||
return Q.nfcall(rimraf, gitFolder);
|
||||
}, function (err) {
|
||||
// If .git does not exist, chmodr returns ENOENT
|
||||
// so, we ignore that error code
|
||||
if (err.code !== 'ENOENT') {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return Q.nfcall(rimraf, gitFolder);
|
||||
}
|
||||
};
|
||||
|
||||
GitResolver.prototype._savePkgMeta = function (meta) {
|
||||
@@ -1,13 +1,12 @@
|
||||
var fs = require('../../util/fs');
|
||||
var fs = require('graceful-fs');
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
var tmp = require('tmp');
|
||||
var mkdirp = require('mkdirp');
|
||||
var rimraf = require('../../util/rimraf');
|
||||
var rimraf = require('rimraf');
|
||||
var readJson = require('../../util/readJson');
|
||||
var createError = require('../../util/createError');
|
||||
var removeIgnores = require('../../util/removeIgnores');
|
||||
var md5 = require('md5-hex');
|
||||
|
||||
tmp.setGracefulCleanup();
|
||||
|
||||
@@ -108,7 +107,8 @@ Resolver.prototype.isCacheable = function () {
|
||||
// We don't want to cache moving targets like branches
|
||||
if (this._pkgMeta &&
|
||||
this._pkgMeta._resolution &&
|
||||
this._pkgMeta._resolution.type === 'branch') {
|
||||
this._pkgMeta._resolution.type === 'branch')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ Resolver.prototype._createTempDir = function () {
|
||||
return Q.nfcall(mkdirp, this._config.tmp)
|
||||
.then(function () {
|
||||
return Q.nfcall(tmp.dir, {
|
||||
template: path.join(this._config.tmp, md5(this._name) + '-' + process.pid + '-XXXXXX'),
|
||||
template: path.join(this._config.tmp, this._name + '-' + process.pid + '-XXXXXX'),
|
||||
mode: 0777 & ~process.umask(),
|
||||
unsafeCleanup: true
|
||||
});
|
||||
@@ -178,8 +178,7 @@ Resolver.prototype._readJson = function (dir) {
|
||||
|
||||
dir = dir || this._tempDir;
|
||||
return readJson(dir, {
|
||||
assume: { name: this._name },
|
||||
logger: that._logger
|
||||
assume: { name: this._name }
|
||||
})
|
||||
.spread(function (json, deprecated) {
|
||||
if (deprecated) {
|
||||
@@ -218,6 +217,15 @@ Resolver.prototype._savePkgMeta = function (meta) {
|
||||
meta._source = this._source;
|
||||
meta._target = this._target;
|
||||
|
||||
['main', 'ignore'].forEach(function (attr) {
|
||||
if (meta[attr]) return;
|
||||
|
||||
that._logger.log(
|
||||
'warn', 'invalid-meta',
|
||||
(meta.name || 'component') + ' is missing "' + attr + '" entry in bower.json'
|
||||
);
|
||||
});
|
||||
|
||||
// Stringify contents
|
||||
contents = JSON.stringify(meta, null, 2);
|
||||
|
||||
@@ -86,13 +86,13 @@ SvnResolver.prototype._export = function () {
|
||||
});
|
||||
|
||||
if (resolution.type === 'commit') {
|
||||
promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]);
|
||||
promise = cmd('svn', ['export', '--force', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]);
|
||||
} else if (resolution.type === 'branch' && resolution.branch === 'trunk') {
|
||||
promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/trunk', this._tempDir]);
|
||||
promise = cmd('svn', ['export', '--force', this._source + '/trunk', this._tempDir]);
|
||||
} else if (resolution.type === 'branch') {
|
||||
promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/branches/' + resolution.branch, this._tempDir]);
|
||||
promise = cmd('svn', ['export', '--force', this._source + '/branches/' + resolution.branch, this._tempDir]);
|
||||
} else {
|
||||
promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/tags/' + resolution.tag, this._tempDir]);
|
||||
promise = cmd('svn', ['export', '--force', this._source + '/tags/' + resolution.tag, this._tempDir]);
|
||||
}
|
||||
|
||||
// Throttle the progress reporter to 1 time each sec
|
||||
@@ -188,7 +188,7 @@ SvnResolver.prototype._findResolution = function (target) {
|
||||
throw createError('No tag found that was able to satisfy ' + target, 'ENORESTARGET', {
|
||||
details: !versions.length ?
|
||||
'No versions found in ' + that._source :
|
||||
'Available versions in ' + that._source + ': ' + versions.map(function (version) { return version.version; }).join(', ')
|
||||
'Available versions: ' + versions.map(function (version) { return version.version; }).join(', ')
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -324,7 +324,7 @@ SvnResolver.tags = function (source) {
|
||||
return Q.resolve(value);
|
||||
}
|
||||
|
||||
value = cmd('svn', ['list', source + '/tags', '--verbose', '--non-interactive'])
|
||||
value = cmd('svn', ['list', source + '/tags', '--verbose'])
|
||||
.spread(function (stout) {
|
||||
var tags = SvnResolver.parseSubversionListOutput(stout.toString());
|
||||
|
||||
@@ -349,7 +349,7 @@ SvnResolver.branches = function (source) {
|
||||
return Q.resolve(value);
|
||||
}
|
||||
|
||||
value = cmd('svn', ['list', source + '/branches', '--verbose', '--non-interactive'])
|
||||
value = cmd('svn', ['list', source + '/branches', '--verbose'])
|
||||
.spread(function (stout) {
|
||||
var branches = SvnResolver.parseSubversionListOutput(stout.toString());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
var fs = require('../../util/fs');
|
||||
var fs = require('graceful-fs');
|
||||
var url = require('url');
|
||||
var request = require('request');
|
||||
var Q = require('q');
|
||||
@@ -55,7 +55,7 @@ UrlResolver.prototype._hasNew = function (pkgMeta) {
|
||||
|
||||
// Make an HEAD request to the source
|
||||
return Q.nfcall(request.head, this._source, {
|
||||
ca: this._config.ca.default,
|
||||
proxy: this._remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy,
|
||||
strictSSL: this._config.strictSsl,
|
||||
timeout: this._config.timeout,
|
||||
headers: reqHeaders
|
||||
@@ -104,18 +104,8 @@ UrlResolver.prototype._resolve = function () {
|
||||
|
||||
// -----------------
|
||||
|
||||
UrlResolver.prototype._parseSourceURL = function (_url) {
|
||||
return url.parse(path.basename(_url)).pathname;
|
||||
};
|
||||
|
||||
UrlResolver.prototype._download = function () {
|
||||
var fileName = this._parseSourceURL(this._source);
|
||||
|
||||
if (!fileName) {
|
||||
this._source = this._source.replace(/\/(?=\?|#)/, '');
|
||||
fileName = this._parseSourceURL(this._source);
|
||||
}
|
||||
|
||||
var fileName = url.parse(path.basename(this._source)).pathname;
|
||||
var file = path.join(this._tempDir, fileName);
|
||||
var reqHeaders = {};
|
||||
var that = this;
|
||||
@@ -131,7 +121,7 @@ UrlResolver.prototype._download = function () {
|
||||
|
||||
// Download the file
|
||||
return download(this._source, file, {
|
||||
ca: this._config.ca.default,
|
||||
proxy: this._remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy,
|
||||
strictSSL: this._config.strictSsl,
|
||||
timeout: this._config.timeout,
|
||||
headers: reqHeaders
|
||||
@@ -1,6 +1,6 @@
|
||||
var Q = require('q');
|
||||
var path = require('path');
|
||||
var fs = require('../../util/fs');
|
||||
var fs = require('fs');
|
||||
var object = require('mout/object');
|
||||
|
||||
var semver = require('../../util/semver');
|
||||
@@ -52,7 +52,7 @@ function pluginResolverFactory(resolverFactory, bower) {
|
||||
return this._decEndpoint.target || '*';
|
||||
};
|
||||
|
||||
PluginResolver.prototype.getName = function () {
|
||||
PluginResolver.prototype.getName = function() {
|
||||
if (!this._decEndpoint.name && typeof resolver.getName === 'function') {
|
||||
return resolver.getName.call(resolver, this.getSource());
|
||||
} else if (!this._decEndpoint.name) {
|
||||
@@ -70,7 +70,7 @@ function pluginResolverFactory(resolverFactory, bower) {
|
||||
|
||||
// Plugin Resolver is always considered potentially cacheable
|
||||
// The "resolve" method decides whether to use cached or fetch new version.
|
||||
PluginResolver.prototype.isCacheable = function () {
|
||||
PluginResolver.prototype.isCacheable = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -95,11 +95,11 @@ function pluginResolverFactory(resolverFactory, bower) {
|
||||
|
||||
var that = this;
|
||||
|
||||
return this.resolvePromise = Q.fcall(function () {
|
||||
return this.resolvePromise = Q.fcall(function() {
|
||||
var target = that.getTarget();
|
||||
|
||||
// It means that we can accept ranges as targets
|
||||
if (that.constructor.isTargetable()) {
|
||||
if(that.constructor.isTargetable()) {
|
||||
that._release = target;
|
||||
|
||||
if (semver.validRange(target)) {
|
||||
@@ -191,8 +191,7 @@ function pluginResolverFactory(resolverFactory, bower) {
|
||||
var that = this;
|
||||
|
||||
return readJson(dir, {
|
||||
assume: { name: that.getName() },
|
||||
logger: bower.logger
|
||||
assume: { name: that.getName() }
|
||||
})
|
||||
.spread(function (json, deprecated) {
|
||||
if (deprecated) {
|
||||
@@ -276,7 +275,7 @@ function pluginResolverFactory(resolverFactory, bower) {
|
||||
});
|
||||
};
|
||||
|
||||
PluginResolver.isTargetable = function () {
|
||||
PluginResolver.isTargetable = function() {
|
||||
// If resolver doesn't define versions function, it's not targetable..
|
||||
return typeof resolver.releases === 'function';
|
||||
};
|
||||
@@ -78,18 +78,17 @@ var run = function (cmdString, action, logger, config) {
|
||||
|
||||
var hook = function (action, ordered, config, logger, packages, installed, json) {
|
||||
if (mout.object.keys(packages).length === 0 || !config.scripts || !config.scripts[action]) {
|
||||
/*jshint newcap: false */
|
||||
return Q();
|
||||
}
|
||||
|
||||
var orderedPackages = ordered ? orderByDependencies(packages, installed, json) : mout.object.keys(packages);
|
||||
var placeholder = new RegExp('%', 'g');
|
||||
var cmdString = mout.string.replace(config.scripts[action], placeholder, orderedPackages.join(' '));
|
||||
var cmdString = mout.string.replace(config.scripts[action], '%', orderedPackages.join(' '));
|
||||
return run(cmdString, action, logger, config);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
preuninstall: mout.function.partial(hook, 'preuninstall', false),
|
||||
postuninstall: mout.function.partial(hook, 'postuninstall', false),
|
||||
preinstall: mout.function.partial(hook, 'preinstall', true),
|
||||
postinstall: mout.function.partial(hook, 'postinstall', true),
|
||||
//only exposed for test
|
||||
43
lib/index.js
Normal file
43
lib/index.js
Normal file
@@ -0,0 +1,43 @@
|
||||
var abbrev = require('abbrev');
|
||||
var mout = require('mout');
|
||||
var commands = require('./commands');
|
||||
var pkg = require('../package.json');
|
||||
|
||||
var abbreviations = abbrev(expandNames(commands));
|
||||
abbreviations.i = 'install';
|
||||
abbreviations.rm = 'uninstall';
|
||||
abbreviations.unlink = 'uninstall';
|
||||
abbreviations.ls = 'list';
|
||||
|
||||
function expandNames(obj, prefix, stack) {
|
||||
prefix = prefix || '';
|
||||
stack = stack || [];
|
||||
|
||||
mout.object.forOwn(obj, function (value, name) {
|
||||
name = prefix + name;
|
||||
|
||||
stack.push(name);
|
||||
|
||||
if (typeof value === 'object' && !value.line) {
|
||||
expandNames(value, name + ' ', stack);
|
||||
}
|
||||
});
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
function clearRuntimeCache() {
|
||||
// Note that in edge cases, some architecture components instance's
|
||||
// in-memory cache might be skipped.
|
||||
// If that's a problem, you should create and fresh instances instead.
|
||||
var PackageRepository = require('./core/PackageRepository');
|
||||
PackageRepository.clearRuntimeCache();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
version: pkg.version,
|
||||
commands: commands,
|
||||
config: require('./config')(),
|
||||
abbreviations: abbreviations,
|
||||
reset: clearRuntimeCache
|
||||
};
|
||||
@@ -31,8 +31,10 @@ JsonRenderer.prototype.error = function (err) {
|
||||
err.message = message;
|
||||
|
||||
// Stack
|
||||
/*jshint camelcase:false*/
|
||||
stack = err.fstream_stack || err.stack || 'N/A';
|
||||
err.stacktrace = (Array.isArray(stack) ? stack.join('\n') : stack);
|
||||
/*jshint camelcase:true*/
|
||||
|
||||
this.log(err);
|
||||
this.end();
|
||||
@@ -5,8 +5,7 @@ var archy = require('archy');
|
||||
var Q = require('q');
|
||||
var stringifyObject = require('stringify-object');
|
||||
var os = require('os');
|
||||
var semverUtils = require('semver-utils');
|
||||
var version = require('../version');
|
||||
var pkg = require(path.join(__dirname, '../..', 'package.json'));
|
||||
var template = require('../util/template');
|
||||
|
||||
function StandardRenderer(command, config) {
|
||||
@@ -72,17 +71,19 @@ StandardRenderer.prototype.error = function (err) {
|
||||
// Print trace if verbose, the error has no code
|
||||
// or if the error is a node error
|
||||
if (this._config.verbose || !err.code || err.errno) {
|
||||
/*jshint camelcase:false*/
|
||||
stack = err.fstream_stack || err.stack || 'N/A';
|
||||
str = chalk.yellow('\nStack trace:\n');
|
||||
str += (Array.isArray(stack) ? stack.join('\n') : stack) + '\n';
|
||||
str += chalk.yellow('\nConsole trace:\n');
|
||||
/*jshint camelcase:true*/
|
||||
|
||||
this._write(process.stderr, str);
|
||||
this._write(process.stderr, new Error().stack);
|
||||
|
||||
// Print bower version, node version and system info.
|
||||
this._write(process.stderr, chalk.yellow('\nSystem info:\n'));
|
||||
this._write(process.stderr, 'Bower version: ' + version + '\n');
|
||||
this._write(process.stderr, 'Bower version: ' + pkg.version + '\n');
|
||||
this._write(process.stderr, 'Node version: ' + process.versions.node + '\n');
|
||||
this._write(process.stderr, 'OS: ' + os.type() + ' ' + os.release() + ' ' + os.arch() + '\n');
|
||||
}
|
||||
@@ -208,19 +209,6 @@ 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);
|
||||
}
|
||||
|
||||
113
lib/util/analytics.js
Normal file
113
lib/util/analytics.js
Normal file
@@ -0,0 +1,113 @@
|
||||
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');
|
||||
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,6 @@
|
||||
var fstream = require('fstream');
|
||||
var fstreamIgnore = require('fstream-ignore');
|
||||
var fs = require('./fs');
|
||||
var fs = require('graceful-fs');
|
||||
var Q = require('q');
|
||||
|
||||
function copy(reader, writer) {
|
||||
@@ -1,4 +1,4 @@
|
||||
var fs = require('./fs');
|
||||
var fs = require('graceful-fs');
|
||||
var path = require('path');
|
||||
var Q = require('q');
|
||||
var mkdirp = require('mkdirp');
|
||||
109
lib/util/download.js
Normal file
109
lib/util/download.js
Normal file
@@ -0,0 +1,109 @@
|
||||
var progress = require('request-progress');
|
||||
var request = require('request');
|
||||
var Q = require('q');
|
||||
var mout = require('mout');
|
||||
var retry = require('retry');
|
||||
var fs = require('graceful-fs');
|
||||
var createError = require('./createError');
|
||||
|
||||
var errorCodes = [
|
||||
'EADDRINFO',
|
||||
'ETIMEDOUT',
|
||||
'ECONNRESET',
|
||||
'ESOCKETTIMEDOUT'
|
||||
];
|
||||
|
||||
function download(url, file, options) {
|
||||
var operation;
|
||||
var response;
|
||||
var deferred = Q.defer();
|
||||
var progressDelay = 8000;
|
||||
|
||||
options = mout.object.mixIn({
|
||||
retries: 5,
|
||||
factor: 2,
|
||||
minTimeout: 1000,
|
||||
maxTimeout: 35000,
|
||||
randomize: true
|
||||
}, options || {});
|
||||
|
||||
// Retry on network errors
|
||||
operation = retry.operation(options);
|
||||
operation.attempt(function () {
|
||||
var req;
|
||||
var writeStream;
|
||||
var contentLength;
|
||||
var bytesDownloaded = 0;
|
||||
|
||||
req = progress(request(url, options), {
|
||||
delay: progressDelay
|
||||
})
|
||||
.on('response', function (res) {
|
||||
var status = res.statusCode;
|
||||
|
||||
if (status < 200 || status >= 300) {
|
||||
return deferred.reject(createError('Status code of ' + status, 'EHTTP'));
|
||||
}
|
||||
|
||||
response = res;
|
||||
contentLength = Number(res.headers['content-length']);
|
||||
})
|
||||
.on('data', function (data) {
|
||||
bytesDownloaded += data.length;
|
||||
})
|
||||
.on('progress', function (state) {
|
||||
deferred.notify(state);
|
||||
})
|
||||
.on('end', function () {
|
||||
// Check if the whole file was downloaded
|
||||
// In some unstable connections the ACK/FIN packet might be sent in the
|
||||
// middle of the download
|
||||
// See: https://github.com/joyent/node/issues/6143
|
||||
if (contentLength && bytesDownloaded < contentLength) {
|
||||
req.emit('error', createError('Transfer closed with ' + (contentLength - bytesDownloaded) + ' bytes remaining to read', 'EINCOMPLETE'));
|
||||
}
|
||||
})
|
||||
.on('error', function (error) {
|
||||
var timeout = operation._timeouts[0];
|
||||
|
||||
// Reject if error is not a network error
|
||||
if (errorCodes.indexOf(error.code) === -1) {
|
||||
return deferred.reject(error);
|
||||
}
|
||||
|
||||
// Next attempt will start reporting download progress immediately
|
||||
progressDelay = 0;
|
||||
|
||||
// Check if there are more retries
|
||||
if (operation.retry(error)) {
|
||||
// Ensure that there are no more events from this request
|
||||
req.removeAllListeners();
|
||||
req.on('error', function () {});
|
||||
// Ensure that there are no more events from the write stream
|
||||
writeStream.removeAllListeners();
|
||||
writeStream.on('error', function () {});
|
||||
|
||||
return deferred.notify({
|
||||
retry: true,
|
||||
delay: timeout,
|
||||
error: error
|
||||
});
|
||||
}
|
||||
|
||||
// No more retries, reject!
|
||||
deferred.reject(error);
|
||||
});
|
||||
|
||||
// Pipe read stream to write stream
|
||||
writeStream = req
|
||||
.pipe(fs.createWriteStream(file))
|
||||
.on('error', deferred.reject)
|
||||
.on('close', function () {
|
||||
deferred.resolve(response);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
module.exports = download;
|
||||
@@ -1,5 +1,5 @@
|
||||
var path = require('path');
|
||||
var fs = require('./fs');
|
||||
var fs = require('graceful-fs');
|
||||
var zlib = require('zlib');
|
||||
var DecompressZip = require('decompress-zip');
|
||||
var tar = require('tar-fs');
|
||||
@@ -7,9 +7,6 @@ var Q = require('q');
|
||||
var mout = require('mout');
|
||||
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
|
||||
@@ -52,24 +49,15 @@ function extractZip(archive, dst) {
|
||||
function extractTar(archive, dst) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
var stream = fs.createReadStream(archive);
|
||||
|
||||
var reject = function (error) {
|
||||
destroy(stream);
|
||||
deferred.reject(error);
|
||||
};
|
||||
|
||||
stream.on('error', reject)
|
||||
fs.createReadStream(archive)
|
||||
.on('error', deferred.reject)
|
||||
.pipe(tar.extract(dst, {
|
||||
ignore: isSymlink, // Filter symlink files
|
||||
dmode: 0555, // Ensure dirs are readable
|
||||
fmode: 0444 // Ensure files are readable
|
||||
}))
|
||||
.on('error', reject)
|
||||
.on('finish', function (result) {
|
||||
destroy(stream);
|
||||
deferred.resolve(dst);
|
||||
});
|
||||
.on('error', deferred.reject)
|
||||
.on('finish', deferred.resolve.bind(deferred, dst));
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
@@ -77,26 +65,17 @@ function extractTar(archive, dst) {
|
||||
function extractTarGz(archive, dst) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
var stream = fs.createReadStream(archive);
|
||||
|
||||
var reject = function (error) {
|
||||
destroy(stream);
|
||||
deferred.reject(error);
|
||||
};
|
||||
|
||||
stream.on('error', reject)
|
||||
fs.createReadStream(archive)
|
||||
.on('error', deferred.reject)
|
||||
.pipe(zlib.createGunzip())
|
||||
.on('error', reject)
|
||||
.on('error', deferred.reject)
|
||||
.pipe(tar.extract(dst, {
|
||||
ignore: isSymlink, // Filter symlink files
|
||||
dmode: 0555, // Ensure dirs are readable
|
||||
fmode: 0444 // Ensure files are readable
|
||||
}))
|
||||
.on('error', reject)
|
||||
.on('finish', function (result) {
|
||||
destroy(stream);
|
||||
deferred.resolve(dst);
|
||||
});
|
||||
.on('error', deferred.reject)
|
||||
.on('finish', deferred.resolve.bind(deferred, dst));
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
@@ -104,21 +83,13 @@ function extractTarGz(archive, dst) {
|
||||
function extractGz(archive, dst) {
|
||||
var deferred = Q.defer();
|
||||
|
||||
var stream = fs.createReadStream(archive);
|
||||
|
||||
var reject = function (error) {
|
||||
destroy(stream);
|
||||
deferred.reject(error);
|
||||
};
|
||||
stream.on('error', reject)
|
||||
fs.createReadStream(archive)
|
||||
.on('error', deferred.reject)
|
||||
.pipe(zlib.createGunzip())
|
||||
.on('error', reject)
|
||||
.pipe(createWriteStream(dst))
|
||||
.on('error', reject)
|
||||
.on('finish', function (result) {
|
||||
destroy(stream);
|
||||
deferred.resolve(dst);
|
||||
});
|
||||
.on('error', deferred.reject)
|
||||
.pipe(fs.createWriteStream(dst))
|
||||
.on('error', deferred.reject)
|
||||
.on('close', deferred.resolve.bind(deferred, dst));
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
@@ -165,11 +136,15 @@ function isSingleDir(dir) {
|
||||
});
|
||||
}
|
||||
|
||||
function moveDirectory(srcDir, destDir) {
|
||||
return Q.nfcall(fs.readdir, srcDir)
|
||||
function moveSingleDirContents(dir) {
|
||||
var destDir = path.dirname(dir);
|
||||
|
||||
return Q.nfcall(fs.readdir, dir)
|
||||
.then(function (files) {
|
||||
var promises = files.map(function (file) {
|
||||
var src = path.join(srcDir, file);
|
||||
var promises;
|
||||
|
||||
promises = files.map(function (file) {
|
||||
var src = path.join(dir, file);
|
||||
var dst = path.join(destDir, file);
|
||||
|
||||
return Q.nfcall(fs.rename, src, dst);
|
||||
@@ -178,7 +153,7 @@ function moveDirectory(srcDir, destDir) {
|
||||
return Q.all(promises);
|
||||
})
|
||||
.then(function () {
|
||||
return Q.nfcall(fs.rmdir, srcDir);
|
||||
return Q.nfcall(fs.rmdir, dir);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -212,53 +187,44 @@ function extract(src, dst, opts) {
|
||||
return Q.reject(createError('File ' + src + ' is not a known 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);
|
||||
});
|
||||
// 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');
|
||||
}
|
||||
|
||||
// Move contents from the temporary directory
|
||||
// If the contents are a single directory (and we're not preserving structure),
|
||||
// move its contents directly instead.
|
||||
// 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) {
|
||||
promise = promise
|
||||
.then(function () {
|
||||
return isSingleDir(tempDir);
|
||||
return Q.nfcall(fs.unlink, src);
|
||||
});
|
||||
}
|
||||
|
||||
// Move contents if a single directory was extracted
|
||||
if (!opts.keepStructure) {
|
||||
promise = promise
|
||||
.then(function () {
|
||||
return isSingleDir(dst);
|
||||
})
|
||||
.then(function (singleDir) {
|
||||
if (singleDir && !opts.keepStructure) {
|
||||
return moveDirectory(singleDir, dst);
|
||||
} else {
|
||||
return moveDirectory(tempDir, dst);
|
||||
}
|
||||
return singleDir ? moveSingleDirContents(singleDir) : null;
|
||||
});
|
||||
}
|
||||
|
||||
// Resolve promise to the dst dir
|
||||
return promise.then(function () {
|
||||
return dst;
|
||||
});
|
||||
// Resolve promise to the dst dir
|
||||
return promise.then(function () {
|
||||
return dst;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,14 +17,6 @@ function readJson(file, options) {
|
||||
.spread(function (json, jsonFile) {
|
||||
var deprecated;
|
||||
|
||||
if (options.logger) {
|
||||
var issues = bowerJson.getIssues(json);
|
||||
|
||||
issues.warnings.forEach(function (warning) {
|
||||
options.logger.warn('invalid-meta', warning);
|
||||
});
|
||||
}
|
||||
|
||||
jsonFile = path.basename(jsonFile);
|
||||
deprecated = jsonFile === 'component.json' ? jsonFile : false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var path = require('path');
|
||||
var rimraf = require('../util/rimraf');
|
||||
var rimraf = require('rimraf');
|
||||
var fstreamIgnore = require('fstream-ignore');
|
||||
var mout = require('mout');
|
||||
var Q = require('q');
|
||||
@@ -1,3 +1,4 @@
|
||||
/*jshint multistr:true*/
|
||||
'use strict';
|
||||
var isRoot = require('is-root');
|
||||
var createError = require('./createError');
|
||||
@@ -1,10 +1,10 @@
|
||||
var path = require('path');
|
||||
var fs = require('./fs');
|
||||
var fs = require('graceful-fs');
|
||||
var Handlebars = require('handlebars');
|
||||
var mout = require('mout');
|
||||
var helpers = require('../templates/helpers');
|
||||
var helpers = require('../../templates/helpers');
|
||||
|
||||
var templatesDir = path.resolve(__dirname, '../templates');
|
||||
var templatesDir = path.resolve(__dirname, '../../templates');
|
||||
var cache = {};
|
||||
|
||||
// Register helpers
|
||||
@@ -1,5 +1,5 @@
|
||||
var Q = require('q');
|
||||
var fs = require('./fs');
|
||||
var fs = require('graceful-fs');
|
||||
|
||||
function validLink(file) {
|
||||
// Ensures that a file is a symlink that points
|
||||
87
package.json
87
package.json
@@ -1,10 +1,87 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "bower",
|
||||
"version": "1.5.4",
|
||||
"description": "The browser package manager",
|
||||
"author": "Twitter",
|
||||
"license": "MIT",
|
||||
"repository": "bower/bower",
|
||||
"main": "lib",
|
||||
"homepage": "http://bower.io",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"abbrev": "^1.0.5",
|
||||
"archy": "1.0.0",
|
||||
"bower-config": "^0.6.1",
|
||||
"bower-endpoint-parser": "^0.2.2",
|
||||
"bower-json": "^0.4.0",
|
||||
"bower-logger": "^0.2.2",
|
||||
"bower-registry-client": "^0.3.0",
|
||||
"cardinal": "0.4.4",
|
||||
"chalk": "^1.0.0",
|
||||
"chmodr": "0.1.0",
|
||||
"configstore": "^0.3.2",
|
||||
"decompress-zip": "^0.1.0",
|
||||
"fstream": "^1.0.3",
|
||||
"fstream-ignore": "^1.0.2",
|
||||
"github": "^0.2.3",
|
||||
"glob": "^4.3.2",
|
||||
"graceful-fs": "^3.0.5",
|
||||
"handlebars": "^2.0.0",
|
||||
"inquirer": "0.8.0",
|
||||
"insight": "^0.7.0",
|
||||
"is-root": "^1.0.0",
|
||||
"junk": "^1.0.0",
|
||||
"lockfile": "^1.0.0",
|
||||
"lru-cache": "2.7.0",
|
||||
"md5-hex": "^1.0.2",
|
||||
"mkdirp": "0.5.0",
|
||||
"mout": "^0.11.0",
|
||||
"nopt": "^3.0.1",
|
||||
"opn": "^1.0.1",
|
||||
"p-throttler": "0.1.1",
|
||||
"promptly": "0.2.0",
|
||||
"q": "^1.1.2",
|
||||
"request": "2.53.0",
|
||||
"request-progress": "0.3.1",
|
||||
"retry": "0.6.1",
|
||||
"rimraf": "^2.2.8",
|
||||
"semver": "^2.3.0",
|
||||
"shell-quote": "^1.4.2",
|
||||
"stringify-object": "^1.0.0",
|
||||
"tar-fs": "^1.4.1",
|
||||
"tmp": "0.0.24",
|
||||
"update-notifier": "^0.3.0",
|
||||
"user-home": "^1.1.0",
|
||||
"which": "^1.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"lerna": "2.0.0-beta.23"
|
||||
"chai": "^1.10.0",
|
||||
"coveralls": "^2.11.2",
|
||||
"expect.js": "^0.3.1",
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-cli": "^0.1.13",
|
||||
"grunt-contrib-jshint": "^0.10.0",
|
||||
"grunt-contrib-watch": "^0.6.1",
|
||||
"grunt-exec": "^0.4.6",
|
||||
"grunt-simple-mocha": "^0.4.0",
|
||||
"istanbul": "^0.3.5",
|
||||
"load-grunt-tasks": "^2.0.0",
|
||||
"mocha": "^2.1.0",
|
||||
"multiline": "^1.0.2",
|
||||
"nock": "^0.56.0",
|
||||
"node-uuid": "^1.4.2",
|
||||
"proxyquire": "^1.3.0",
|
||||
"spawn-sync": "^1.0.5"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "lerna bootstrap",
|
||||
"test": "lerna run test"
|
||||
}
|
||||
"test": "grunt test"
|
||||
},
|
||||
"bin": "bin/bower",
|
||||
"files": [
|
||||
"bin",
|
||||
"lib",
|
||||
"templates"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
7
packages/bower-config/.gitignore
vendored
7
packages/bower-config/.gitignore
vendored
@@ -1,7 +0,0 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
|
||||
test/assets/github-test-package
|
||||
test/assets/github-test-package-copy
|
||||
test/assets/temp
|
||||
test/reports
|
||||
@@ -1,61 +0,0 @@
|
||||
{
|
||||
"predef": [
|
||||
"console",
|
||||
"describe",
|
||||
"it",
|
||||
"after",
|
||||
"afterEach",
|
||||
"before",
|
||||
"beforeEach"
|
||||
],
|
||||
|
||||
"indent": 4,
|
||||
"node": true,
|
||||
"devel": true,
|
||||
|
||||
"bitwise": false,
|
||||
"curly": false,
|
||||
"eqeqeq": true,
|
||||
"forin": false,
|
||||
"immed": true,
|
||||
"latedef": false,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": false,
|
||||
"nonew": true,
|
||||
"plusplus": false,
|
||||
"regexp": false,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"quotmark": "single",
|
||||
"strict": false,
|
||||
"trailing": true,
|
||||
|
||||
"asi": false,
|
||||
"boss": true,
|
||||
"debug": false,
|
||||
"eqnull": true,
|
||||
"es5": false,
|
||||
"esnext": false,
|
||||
"evil": false,
|
||||
"expr": false,
|
||||
"funcscope": false,
|
||||
"globalstrict": false,
|
||||
"iterator": false,
|
||||
"lastsemic": false,
|
||||
"laxbreak": true,
|
||||
"laxcomma": false,
|
||||
"loopfunc": true,
|
||||
"multistr": false,
|
||||
"onecase": true,
|
||||
"regexdash": false,
|
||||
"scripturl": false,
|
||||
"smarttabs": false,
|
||||
"shadow": false,
|
||||
"sub": false,
|
||||
"supernew": true,
|
||||
"validthis": false,
|
||||
|
||||
"nomen": false,
|
||||
"white": true
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
sudo: false
|
||||
language: node_js
|
||||
node_js:
|
||||
- '5'
|
||||
- '4'
|
||||
- '0.12'
|
||||
- '0.10'
|
||||
script:
|
||||
- grunt travis
|
||||
@@ -1,103 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
## 1.4.0
|
||||
|
||||
- Change default shorthand resolver from git:// to https://
|
||||
|
||||
## 1.3.1
|
||||
|
||||
- Ignore hook scripts for environment variable expansion
|
||||
|
||||
## 1.3.0 - 2015-12-07
|
||||
|
||||
- Allow the use of environment variables in .bowerrc. Fixes [#41](https://github.com/bower/config/issues/41)
|
||||
- Loads the .bowerrc file from the cwd specified on the command line. Fixes [bower/bower#1993](https://github.com/bower/bower/issues/1993)
|
||||
- Allwow for array notation in ENV variables [#44](https://github.com/bower/config/issues/44)
|
||||
|
||||
## 1.2.3 - 2015-11-27
|
||||
|
||||
- Restores env variables if they are undefined at the beginning
|
||||
- Handles default setting for config.ca. Together with [bower/bower PR #1972](https://github.com/bower/bower/pull/1972), fixes downloading with `strict-ssl` using custom CA
|
||||
- Displays an error message if .bowerrc is a directory instead of file. Fixes [bower/bower#2022](https://github.com/bower/bower/issues/2022)
|
||||
|
||||
## 1.2.2 - 2015-10-16
|
||||
- Fixes registry configurartion expanding [bower/bower#1950](https://github.com/bower/bower/issues/1950)
|
||||
|
||||
## 1.2.1 - 2015-10-15
|
||||
- Fixes case insenstivity HTTP_PROXY setting issue on Windows
|
||||
|
||||
## 1.2.0 - 2015-09-28
|
||||
- Prevent defaulting cwd to process.cwd()
|
||||
|
||||
## 1.1.2 - 2015-09-27
|
||||
- Performs only camel case normalisation before merging
|
||||
|
||||
## 1.1.1 - 2015-09-27
|
||||
- Fix: Merge extra options after camel-case normalisation, instead of before it
|
||||
|
||||
## 1.1.0 - 2015-09-27
|
||||
- Allow for overwriting options with .load(overwrites) / .read(cwd, overwrites)
|
||||
|
||||
## 1.0.1 - 2015-09-27
|
||||
- Update dependencies and relax "mout" version range
|
||||
- Most significant changes:
|
||||
- graceful-fs updated from 2.x version to 4.x
|
||||
- osenv updated to from 0.0.x to 0.1.x, [tmp location changed](https://github.com/npm/osenv/commit/d6eddbc026538b09026b1dbd60fbc081a8c67e03)
|
||||
|
||||
## 1.0.0 - 2015-09-27
|
||||
- Support for no-proxy configuration variable
|
||||
- Overwrite HTTP_PROXY, HTTPS_PROXY, and NO_PROXY env variables in load method
|
||||
- Normalise paths to certificates with contents of them, [#28](https://github.com/bower/config/pull/28)
|
||||
|
||||
## 0.6.1 - 2015-04-1
|
||||
- Fixes merging .bowerrc files upward directory tree. [#25](https://github.com/bower/config/issues/25)
|
||||
|
||||
## 0.6.0 - 2015-03-30
|
||||
- Merge .bowerrc files upward directory tree (fixes [bower/bower#1689](https://github.com/bower/bower/issues/1689)) [#24](https://github.com/bower/config/pull/24)
|
||||
- Allow NPM config variables (resolves [bower/bower#1711](https://github.com/bower/bower/issues/1711)) [#23](https://github.com/bower/config/pull/23)
|
||||
|
||||
## 0.5.2 - 2014-06-09
|
||||
- Fixes downloading of bower modules with ignores when .bowerrc is overridden with a relative tmp path. [#17](https://github.com/bower/config/issues/17) [bower/bower#1299](https://github.com/bower/bower/issues/1299)
|
||||
|
||||
## 0.5.1 - 2014-05-21
|
||||
- [perf] Uses the same mout version as bower
|
||||
- [perf] Uses only relevant parts of mout. Related [bower/bower#1134](https://github.com/bower/bower/pull/1134)
|
||||
|
||||
## 0.5.0 - 2013-08-30
|
||||
- Adds a DEFAULT_REGISTRY key to the Config class that exposes the bower registry UR. [#6](https://github.com/bower/config/issues/6)
|
||||
|
||||
## 0.4.5 - 2013-08-28
|
||||
- Fixes crashing when home is not set
|
||||
|
||||
## 0.4.4 - 2013-08-21
|
||||
- Supports nested environment variables [#8](https://github.com/bower/config/issues/8)
|
||||
|
||||
## 0.4.3 - 2013-08-19
|
||||
- Improvement in argv.config parsing
|
||||
|
||||
## 0.4.2 - 2013-08-18
|
||||
- Sets interative to auto
|
||||
|
||||
## 0.4.1 - 2013-08-18
|
||||
- Generates a fake user instead of using 'unknown'
|
||||
|
||||
## 0.4.0 - 2013-08-16
|
||||
- Suffixes temp folder with the user and 'bower'
|
||||
|
||||
## 0.3.5 - 2013-08-14
|
||||
- Casts buffer to string
|
||||
|
||||
## 0.3.4 - 2013-08-11
|
||||
- Empty .bowerrc files no longer throw an error.
|
||||
|
||||
## 0.3.3 - 2013-08-11
|
||||
- Changes git folder to empty (was not being used anyway)
|
||||
|
||||
## 0.3.2 - 2013-08-07
|
||||
- Uses a known user agent by default when a proxy.
|
||||
|
||||
## 0.3.1 - 2013-08-06
|
||||
- Fixes Typo
|
||||
|
||||
## 0.3.0 - 2013-08-06
|
||||
- Appends the username when using the temporary folder.
|
||||
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2012 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
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,76 +0,0 @@
|
||||
# bower-config [](http://travis-ci.org/bower/config)[](https://coveralls.io/github/bower/config?branch=master)
|
||||
|
||||
> The Bower config (`.bowerrc`) reader and writer.
|
||||
|
||||
[Bower](http://bower.io/) can be configured using JSON in a `.bowerrc` file. For example:
|
||||
|
||||
{
|
||||
"directory": "app/components/",
|
||||
"timeout": 120000,
|
||||
"registry": {
|
||||
"search": [
|
||||
"http://localhost:8000",
|
||||
"https://bower.herokuapp.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
View the complete [.bowerrc specification](http://bower.io/docs/config/#bowerrc-specification) on the website for more details. Both the `bower.json` and `.bowerrc` specifications are maintained at [github.com/bower/spec](https://github.com/bower/spec).
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save bower-config
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
#### .load(overwrites)
|
||||
|
||||
Loads the bower configuration from the configuration files.
|
||||
|
||||
Configuration is overwritten (after camelcase normalisation) with `overwrites` argument.
|
||||
|
||||
This method overwrites following environment variables:
|
||||
|
||||
- `HTTP_PROXY` with `proxy` configuration variable
|
||||
- `HTTPS_PROXY` with `https-proxy` configuration variable
|
||||
- `NO_PROXY` with `no-proxy` configuration variable
|
||||
|
||||
It also clears `http_proxy`, `https_proxy`, and `no_proxy` environment variables.
|
||||
|
||||
To restore those variables you can use `restore` method.
|
||||
|
||||
#### restore()
|
||||
|
||||
Restores environment variables overwritten by `.load` method.
|
||||
|
||||
#### .toObject()
|
||||
|
||||
Returns a deep copy of the underlying configuration object.
|
||||
The returned configuration is normalised.
|
||||
The object keys will be camelCase.
|
||||
|
||||
|
||||
#### #create(cwd)
|
||||
|
||||
Obtains a instance where `cwd` is the current working directory (defaults to `process.cwd`);
|
||||
|
||||
```js
|
||||
var config = require('bower-config').create();
|
||||
// You can also specify a working directory
|
||||
var config2 = require('bower-config').create('./some/path');
|
||||
```
|
||||
|
||||
#### #read(cwd, overrides)
|
||||
|
||||
Alias for:
|
||||
|
||||
```js
|
||||
var configObject = (new Config(cwd)).load(overrides).toJson();
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
|
||||
@@ -1,109 +0,0 @@
|
||||
var lang = require('mout/lang');
|
||||
var object = require('mout/object');
|
||||
var rc = require('./util/rc');
|
||||
var expand = require('./util/expand');
|
||||
var EnvProxy = require('./util/proxy');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
function Config(cwd) {
|
||||
this._cwd = cwd;
|
||||
this._proxy = new EnvProxy();
|
||||
this._config = {};
|
||||
}
|
||||
|
||||
Config.prototype.load = function (overwrites) {
|
||||
this._config = rc('bower', this._cwd);
|
||||
|
||||
this._config = object.merge(
|
||||
expand(this._config || {}),
|
||||
expand(overwrites || {})
|
||||
);
|
||||
|
||||
this._config = normalise(this._config);
|
||||
|
||||
this._proxy.set(this._config);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Config.prototype.restore = function () {
|
||||
this._proxy.restore();
|
||||
};
|
||||
|
||||
function readCertFile(path) {
|
||||
path = path || '';
|
||||
|
||||
var sep = '-----END CERTIFICATE-----';
|
||||
|
||||
var certificates;
|
||||
|
||||
if (path.indexOf(sep) === -1) {
|
||||
certificates = fs.readFileSync(path, { encoding: 'utf8' });
|
||||
} else {
|
||||
certificates = path;
|
||||
}
|
||||
|
||||
return certificates.
|
||||
split(sep).
|
||||
filter(function(s) { return !s.match(/^\s*$/); }).
|
||||
map(function(s) { return s + sep; });
|
||||
}
|
||||
|
||||
function loadCAs(caConfig) {
|
||||
// If a ca file path has been specified, expand that here to the file's
|
||||
// contents. As a user can specify these individually, we must load them
|
||||
// one by one.
|
||||
for (var p in caConfig) {
|
||||
if (caConfig.hasOwnProperty(p)) {
|
||||
var prop = caConfig[p];
|
||||
if (Array.isArray(prop)) {
|
||||
caConfig[p] = prop.map(function(s) {
|
||||
return readCertFile(s);
|
||||
});
|
||||
} else if (prop) {
|
||||
caConfig[p] = readCertFile(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Config.prototype.toObject = function () {
|
||||
return lang.deepClone(this._config);
|
||||
};
|
||||
|
||||
Config.create = function (cwd) {
|
||||
return new Config(cwd);
|
||||
};
|
||||
|
||||
Config.read = function (cwd, overrides) {
|
||||
var config = Config.create(cwd);
|
||||
return config.load(overrides).toObject();
|
||||
};
|
||||
|
||||
function normalise(config) {
|
||||
config = expand(config);
|
||||
|
||||
// Some backwards compatible things..
|
||||
if (config.shorthandResolver) {
|
||||
config.shorthandResolver = config.shorthandResolver
|
||||
.replace(/\{\{\{/g, '{{')
|
||||
.replace(/\}\}\}/g, '}}');
|
||||
}
|
||||
|
||||
// Ensure that every registry endpoint does not end with /
|
||||
config.registry.search = config.registry.search.map(function (url) {
|
||||
return url.replace(/\/+$/, '');
|
||||
});
|
||||
config.registry.register = config.registry.register.replace(/\/+$/, '');
|
||||
config.registry.publish = config.registry.publish.replace(/\/+$/, '');
|
||||
config.tmp = path.resolve(config.tmp);
|
||||
|
||||
loadCAs(config.ca);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
Config.DEFAULT_REGISTRY = require('./util/defaults').registry;
|
||||
|
||||
module.exports = Config;
|
||||
@@ -1,45 +0,0 @@
|
||||
var path = require('path');
|
||||
var paths = require('./paths');
|
||||
|
||||
// Guess proxy defined in the env
|
||||
var proxy = process.env.HTTP_PROXY
|
||||
|| process.env.http_proxy
|
||||
|| null;
|
||||
|
||||
var httpsProxy = process.env.HTTPS_PROXY
|
||||
|| process.env.https_proxy
|
||||
|| proxy;
|
||||
|
||||
var noProxy = process.env.NO_PROXY
|
||||
|| process.env.no_proxy;
|
||||
|
||||
// Use a well known user agent (in this case, curl) when using a proxy,
|
||||
// to avoid potential filtering on many corporate proxies with blank or unknown agents
|
||||
var userAgent = !proxy && !httpsProxy
|
||||
? 'node/' + process.version + ' ' + process.platform + ' ' + process.arch
|
||||
: 'curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5';
|
||||
|
||||
var defaults = {
|
||||
'directory': 'bower_components',
|
||||
'registry': 'https://bower.herokuapp.com',
|
||||
'shorthand-resolver': 'https://github.com/{{owner}}/{{package}}.git',
|
||||
'tmp': paths.tmp,
|
||||
'proxy': proxy,
|
||||
'https-proxy': httpsProxy,
|
||||
'no-proxy': noProxy,
|
||||
'timeout': 30000,
|
||||
'ca': { search: [] },
|
||||
'strict-ssl': true,
|
||||
'user-agent': userAgent,
|
||||
'color': true,
|
||||
'interactive': null,
|
||||
'storage': {
|
||||
packages: path.join(paths.cache, 'packages'),
|
||||
links: path.join(paths.data, 'links'),
|
||||
completion: path.join(paths.data, 'completion'),
|
||||
registry: path.join(paths.cache, 'registry'),
|
||||
empty: path.join(paths.data, 'empty') // Empty dir, used in GIT_TEMPLATE_DIR among others
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = defaults;
|
||||
@@ -1,126 +0,0 @@
|
||||
var object = require('mout/object');
|
||||
var lang = require('mout/lang');
|
||||
var string = require('mout/string');
|
||||
|
||||
function camelCase(config) {
|
||||
var camelCased = {};
|
||||
|
||||
// Camel case
|
||||
object.forOwn(config, function (value, key) {
|
||||
// Ignore null values
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
key = string.camelCase(key.replace(/_/g, '-'));
|
||||
camelCased[key] = lang.isPlainObject(value) ? camelCase(value) : value;
|
||||
});
|
||||
|
||||
return camelCased;
|
||||
}
|
||||
|
||||
// Function to replace ${VAR} - style variables
|
||||
// with values set in the environment
|
||||
// This function expects to be passed a string
|
||||
function doEnvReplaceStr (f) {
|
||||
|
||||
// Un-tildify
|
||||
var untildify = require('untildify');
|
||||
f = untildify(f);
|
||||
|
||||
// replace any ${ENV} values with the appropriate environ.
|
||||
var envExpr = /(\\*)\$\{([^}]+)\}/g;
|
||||
return f.replace(envExpr, function (orig, esc, name) {
|
||||
esc = esc.length && esc.length % 2;
|
||||
if (esc) return orig;
|
||||
if (undefined === process.env[name]) {
|
||||
throw new Error('Environment variable used in .bowerrc is not defined: ' + orig);
|
||||
}
|
||||
|
||||
return process.env[name];
|
||||
});
|
||||
}
|
||||
|
||||
function envReplace(config) {
|
||||
var envReplaced = {};
|
||||
|
||||
object.forOwn(config, function (value, key) {
|
||||
|
||||
// Ignore null values
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore 'scripts'
|
||||
// These hooks run within the shell
|
||||
// environment variable expansion is not required
|
||||
if ( key === 'scripts' && lang.isPlainObject(value) ){
|
||||
envReplaced[key] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform variable replacements based on var type
|
||||
if ( lang.isPlainObject(value) ) {
|
||||
envReplaced[key] = envReplace(value);
|
||||
}
|
||||
else if ( lang.isString(value) ) {
|
||||
envReplaced[key] = doEnvReplaceStr(value);
|
||||
}
|
||||
else {
|
||||
envReplaced[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
return envReplaced;
|
||||
}
|
||||
|
||||
function expand(config) {
|
||||
config = camelCase(config);
|
||||
config = envReplace(config);
|
||||
|
||||
if (typeof config.registry === 'string') {
|
||||
config.registry = {
|
||||
default: config.registry,
|
||||
search: [config.registry],
|
||||
register: config.registry,
|
||||
publish: config.registry
|
||||
};
|
||||
} else if (typeof config.registry === 'object') {
|
||||
config.registry.default = config.registry.default || 'https://bower.herokuapp.com';
|
||||
|
||||
config.registry = {
|
||||
default: config.registry.default,
|
||||
search: config.registry.search || config.registry.default,
|
||||
register: config.registry.register || config.registry.default,
|
||||
publish: config.registry.publish || config.registry.default
|
||||
};
|
||||
|
||||
if (config.registry.search && !Array.isArray(config.registry.search)) {
|
||||
config.registry.search = [config.registry.search];
|
||||
}
|
||||
}
|
||||
|
||||
// CA
|
||||
if (typeof config.ca === 'string') {
|
||||
config.ca = {
|
||||
default: config.ca,
|
||||
search: [config.ca],
|
||||
register: config.ca,
|
||||
publish: config.ca
|
||||
};
|
||||
} else if (typeof config.ca === 'object') {
|
||||
if (config.ca.search && !Array.isArray(config.ca.search)) {
|
||||
config.ca.search = [config.ca.search];
|
||||
}
|
||||
|
||||
if (config.ca.default) {
|
||||
config.ca.search = config.ca.search || config.ca.default;
|
||||
config.ca.register = config.ca.register || config.ca.default;
|
||||
config.ca.publish = config.ca.publish || config.ca.default;
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
module.exports = expand;
|
||||
@@ -1,44 +0,0 @@
|
||||
var os = require('os');
|
||||
var path = require('path');
|
||||
var osenv = require('osenv');
|
||||
var crypto = require('crypto');
|
||||
|
||||
function generateFakeUser() {
|
||||
var uid = process.pid + '-' + Date.now() + '-' + Math.floor(Math.random() * 1000000);
|
||||
return crypto.createHash('md5').update(uid).digest('hex');
|
||||
}
|
||||
|
||||
// Assume XDG defaults
|
||||
// See: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
var paths = {
|
||||
config: process.env.XDG_CONFIG_HOME,
|
||||
data: process.env.XDG_DATA_HOME,
|
||||
cache: process.env.XDG_CACHE_HOME
|
||||
};
|
||||
|
||||
// Guess some needed properties based on the user OS
|
||||
var user = (osenv.user() || generateFakeUser()).replace(/\\/g, '-');
|
||||
var tmp = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), user);
|
||||
var home = osenv.home();
|
||||
var base;
|
||||
|
||||
// Fallbacks for windows
|
||||
if (process.platform === 'win32') {
|
||||
base = path.resolve(process.env.LOCALAPPDATA || home || tmp);
|
||||
base = path.join(base, 'bower');
|
||||
|
||||
paths.config = paths.config || path.join(base, 'config');
|
||||
paths.data = paths.data || path.join(base, 'data');
|
||||
paths.cache = paths.cache || path.join(base, 'cache');
|
||||
// Fallbacks for other operating systems
|
||||
} else {
|
||||
base = path.resolve(home || tmp);
|
||||
|
||||
paths.config = paths.config || path.join(base, '.config/bower');
|
||||
paths.data = paths.data || path.join(base, '.local/share/bower');
|
||||
paths.cache = paths.cache || path.join(base, '.cache/bower');
|
||||
}
|
||||
|
||||
paths.tmp = path.resolve(path.join(tmp, 'bower'));
|
||||
|
||||
module.exports = paths;
|
||||
@@ -1,79 +0,0 @@
|
||||
// EnvProxy uses the proxy vaiables passed to it in set and sets the
|
||||
// process.env uppercase proxy variables to them with the ability
|
||||
// to restore the original values later
|
||||
var EnvProxy = function() {
|
||||
this.restoreFrom = {};
|
||||
};
|
||||
|
||||
EnvProxy.prototype.set = function (config) {
|
||||
this.config = config;
|
||||
|
||||
// Override environment defaults if proxy config options are set
|
||||
// This will make requests.js follow the proxies in config
|
||||
if (Object.prototype.hasOwnProperty.call(config, 'noProxy')) {
|
||||
this.restoreFrom.NO_PROXY = process.env.NO_PROXY;
|
||||
this.restoreFrom.no_proxy = process.env.no_proxy;
|
||||
delete process.env.no_proxy;
|
||||
process.env.NO_PROXY = config.noProxy;
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(config, 'proxy')) {
|
||||
this.restoreFrom.HTTP_PROXY = process.env.HTTP_PROXY;
|
||||
this.restoreFrom.http_proxy = process.env.http_proxy;
|
||||
delete process.env.http_proxy;
|
||||
process.env.HTTP_PROXY = config.proxy;
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(config, 'httpsProxy')) {
|
||||
this.restoreFrom.HTTPS_PROXY = process.env.HTTPS_PROXY;
|
||||
this.restoreFrom.https_proxy = process.env.https_proxy;
|
||||
delete process.env.https_proxy;
|
||||
process.env.HTTPS_PROXY = config.httpsProxy;
|
||||
}
|
||||
};
|
||||
|
||||
EnvProxy.prototype.restore = function () {
|
||||
if (Object.prototype.hasOwnProperty.call(this.config, 'noProxy')) {
|
||||
if (this.restoreFrom.NO_PROXY !== undefined) {
|
||||
process.env.NO_PROXY = this.restoreFrom.NO_PROXY;
|
||||
} else {
|
||||
delete process.env.NO_PROXY;
|
||||
}
|
||||
|
||||
if (this.restoreFrom.no_proxy !== undefined) {
|
||||
process.env.no_proxy = this.restoreFrom.no_proxy;
|
||||
} else {
|
||||
delete process.env.no_proxy;
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(this.config, 'proxy')) {
|
||||
if (this.restoreFrom.HTTP_PROXY !== undefined) {
|
||||
process.env.HTTP_PROXY = this.restoreFrom.HTTP_PROXY;
|
||||
} else {
|
||||
delete process.env.HTTP_PROXY;
|
||||
}
|
||||
|
||||
if (this.restoreFrom.http_proxy !== undefined) {
|
||||
process.env.http_proxy = this.restoreFrom.http_proxy;
|
||||
} else {
|
||||
delete process.env.http_proxy;
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(this.config, 'httpsProxy')) {
|
||||
if (this.restoreFrom.HTTPS_PROXY !== undefined) {
|
||||
process.env.HTTPS_PROXY = this.restoreFrom.HTTPS_PROXY;
|
||||
} else {
|
||||
delete process.env.HTTPS_PROXY;
|
||||
}
|
||||
|
||||
if (this.restoreFrom.https_proxy !== undefined) {
|
||||
process.env.https_proxy = this.restoreFrom.https_proxy;
|
||||
} else {
|
||||
delete process.env.https_proxy;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = EnvProxy;
|
||||
@@ -1,158 +0,0 @@
|
||||
var path = require('path');
|
||||
var fs = require('graceful-fs');
|
||||
var optimist = require('optimist');
|
||||
var osenv = require('osenv');
|
||||
var object = require('mout/object');
|
||||
var string = require('mout/string');
|
||||
var paths = require('./paths');
|
||||
var defaults = require('./defaults');
|
||||
|
||||
var win = process.platform === 'win32';
|
||||
var home = osenv.home();
|
||||
|
||||
function rc(name, cwd, argv) {
|
||||
var argvConfig;
|
||||
|
||||
argv = argv || optimist.argv;
|
||||
|
||||
// Parse --config.foo=false
|
||||
argvConfig = object.map(argv.config || {}, function (value) {
|
||||
return value === 'false' ? false : value;
|
||||
});
|
||||
|
||||
// If we have specified a cwd then use this as the base for getting config.
|
||||
cwd = argvConfig.cwd ? argvConfig.cwd : cwd;
|
||||
|
||||
if (cwd) {
|
||||
return object.deepMixIn.apply(null, [
|
||||
{},
|
||||
defaults,
|
||||
{ cwd: cwd },
|
||||
win ? {} : json(path.join('/etc', name + 'rc')),
|
||||
!home ? {} : json(path.join(home, '.' + name + 'rc')),
|
||||
json(path.join(paths.config, name + 'rc')),
|
||||
json(find('.' + name + 'rc', cwd)),
|
||||
env('npm_package_config_' + name + '_'),
|
||||
env(name + '_'),
|
||||
argvConfig
|
||||
]);
|
||||
} else {
|
||||
return object.deepMixIn.apply(null, [
|
||||
{},
|
||||
defaults,
|
||||
win ? {} : json(path.join('/etc', name + 'rc')),
|
||||
!home ? {} : json(path.join(home, '.' + name + 'rc')),
|
||||
json(path.join(paths.config, name + 'rc')),
|
||||
env('npm_package_config_' + name + '_'),
|
||||
env(name + '_'),
|
||||
argvConfig
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function parse(content, file) {
|
||||
var error;
|
||||
|
||||
if (!content.trim().length) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
} catch (e) {
|
||||
if (file) {
|
||||
error = new Error('Unable to parse ' + file + ': ' + e.message);
|
||||
} else {
|
||||
error = new Error('Unable to parse rc config: ' + e.message);
|
||||
}
|
||||
|
||||
error.details = content;
|
||||
error.code = 'EMALFORMED';
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function json(file) {
|
||||
var content = {};
|
||||
if (!Array.isArray(file)) {
|
||||
try {
|
||||
content = fs.readFileSync(file).toString();
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parse(content, file);
|
||||
} else {
|
||||
// This is multiple json files
|
||||
file.forEach(function(filename) {
|
||||
if (fs.statSync(filename).isDirectory()) {
|
||||
var error;
|
||||
error = new Error(filename + ' should not be a directory');
|
||||
error.code = 'EFILEISDIR';
|
||||
throw error;
|
||||
}
|
||||
var json = fs.readFileSync(filename).toString();
|
||||
json = parse(json, filename);
|
||||
content = object.merge(content, json);
|
||||
});
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
function env(prefix) {
|
||||
var obj = {};
|
||||
var prefixLength = prefix.length;
|
||||
|
||||
prefix = prefix.toLowerCase();
|
||||
|
||||
object.forOwn(process.env, function (value, key) {
|
||||
key = key.toLowerCase();
|
||||
|
||||
if (string.startsWith(key, prefix)) {
|
||||
var parsedKey = key
|
||||
.substr(prefixLength)
|
||||
.replace(/__/g, '.') // __ is used for nesting
|
||||
.replace(/_/g, '-'); // _ is used as a - separator
|
||||
|
||||
//use a convention patern to accept array from process.env
|
||||
//e.g. export bower_registry__search='["http://abc.com","http://def.com"]'
|
||||
var match = /\[([^\]]*)\]/g.exec(value);
|
||||
var targetValue;
|
||||
if (!match || match.length === 0) {
|
||||
targetValue = value;
|
||||
} else {
|
||||
targetValue = match[1].split(',')
|
||||
.map(function(m) {
|
||||
return m.trim();
|
||||
});
|
||||
}
|
||||
object.set(obj, parsedKey, targetValue);
|
||||
}
|
||||
});
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function find(filename, dir) {
|
||||
var files = [];
|
||||
|
||||
var walk = function (filename, dir) {
|
||||
var file = path.join(dir, filename);
|
||||
var parent = path.dirname(dir);
|
||||
|
||||
if (fs.existsSync(file)) {
|
||||
files.push(file);
|
||||
}
|
||||
|
||||
if (parent !== dir) {
|
||||
walk(filename, parent);
|
||||
}
|
||||
};
|
||||
|
||||
walk(filename, dir);
|
||||
files.reverse();
|
||||
return files;
|
||||
}
|
||||
|
||||
module.exports = rc;
|
||||
@@ -1,45 +0,0 @@
|
||||
{
|
||||
"name": "bower-config",
|
||||
"version": "1.4.0",
|
||||
"description": "The Bower config reader and writer.",
|
||||
"author": "Twitter",
|
||||
"license": "MIT",
|
||||
"repository": "bower/config",
|
||||
"main": "lib/Config",
|
||||
"homepage": "http://bower.io",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.3",
|
||||
"mout": "^1.0.0",
|
||||
"optimist": "^0.6.1",
|
||||
"osenv": "^0.1.3",
|
||||
"untildify": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.4",
|
||||
"expect.js": "^0.3.1",
|
||||
"glob": "^4.5.3",
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-cli": "^0.1.13",
|
||||
"grunt-contrib-jshint": "^0.10.0",
|
||||
"grunt-contrib-watch": "^0.6.1",
|
||||
"grunt-coveralls": "^1.0.0",
|
||||
"grunt-exec": "^0.4.6",
|
||||
"grunt-simple-mocha": "^0.4.0",
|
||||
"istanbul": "^0.4.1",
|
||||
"load-grunt-tasks": "^2.0.0",
|
||||
"mkdirp": "^0.5.0",
|
||||
"mocha": "~1.12.0",
|
||||
"node-uuid": "^1.4.3",
|
||||
"q": "^1.2.0",
|
||||
"rimraf": "^2.3.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "grunt test"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"ca": "Equifax Secure CA\n=================\n-----BEGIN CERTIFICATE-----\nMIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE\nChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5\nMB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT\nB0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB\nnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR\nfM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW\n8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG\nA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE\nCxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG\nA1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS\nspXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB\nAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961\nzgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB\nBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95\n70+sB3c4\n-----END CERTIFICATE-----\n\nGlobalSign Root CA\n==================\n-----BEGIN CERTIFICATE-----\nMIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx\nGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds\nb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV\nBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD\nVQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa\nDuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc\nTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb\nKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP\nc1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX\ngzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF\nAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj\nY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG\nj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH\nhm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC\nX4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n-----END CERTIFICATE-----"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"ca": "test/assets/custom-ca/ca-bundle.crt"
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
Equifax Secure CA
|
||||
=================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE
|
||||
ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
|
||||
MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT
|
||||
B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB
|
||||
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR
|
||||
fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW
|
||||
8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG
|
||||
A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE
|
||||
CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG
|
||||
A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS
|
||||
spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB
|
||||
Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961
|
||||
zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB
|
||||
BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95
|
||||
70+sB3c4
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
GlobalSign Root CA
|
||||
==================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
|
||||
GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
|
||||
b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
|
||||
BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
|
||||
VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
|
||||
DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
|
||||
THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
|
||||
Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
|
||||
c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
|
||||
gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
||||
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
|
||||
AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
|
||||
Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
|
||||
j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
|
||||
hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
|
||||
X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"scripts" : {
|
||||
"postinstall" : "${_myshellvar}"
|
||||
},
|
||||
"storage" : {
|
||||
"packages" : "${_BOWERRC_MY_PACKAGES}",
|
||||
"registry" : "~/.bower-test/registry"
|
||||
},
|
||||
"tmp" : "${_BOWERRC_MY_TMP}"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"proxy": "http://HTTP_PROXY",
|
||||
"https-proxy": "http://HTTPS_PROXY",
|
||||
"no-proxy": "google.com"
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
var Q = require('q');
|
||||
var mkdirp = require('mkdirp');
|
||||
var rimraf = require('rimraf');
|
||||
var uuid = require('node-uuid');
|
||||
var object = require('mout/object');
|
||||
var fs = require('fs');
|
||||
var glob = require('glob');
|
||||
var os = require('os');
|
||||
var path = require('path');
|
||||
|
||||
// For better promise errors
|
||||
Q.longStackSupport = true;
|
||||
|
||||
var tmpLocation = path.join(
|
||||
os.tmpdir ? os.tmpdir() : os.tmpDir(),
|
||||
'bower-config-tests',
|
||||
uuid.v4().slice(0, 8)
|
||||
);
|
||||
|
||||
after(function () {
|
||||
rimraf.sync(tmpLocation);
|
||||
});
|
||||
|
||||
exports.TempDir = (function() {
|
||||
function TempDir (defaults) {
|
||||
this.path = path.join(tmpLocation, uuid.v4());
|
||||
this.defaults = defaults;
|
||||
}
|
||||
|
||||
TempDir.prototype.create = function (files, defaults) {
|
||||
var that = this;
|
||||
|
||||
defaults = defaults || this.defaults || {};
|
||||
files = object.merge(files || {}, defaults);
|
||||
|
||||
this.meta = function(tag) {
|
||||
if (tag) {
|
||||
return files[tag]['bower.json'];
|
||||
} else {
|
||||
return files['bower.json'];
|
||||
}
|
||||
};
|
||||
|
||||
if (files) {
|
||||
object.forOwn(files, function (contents, filepath) {
|
||||
if (typeof contents === 'object') {
|
||||
contents = JSON.stringify(contents, null, ' ') + '\n';
|
||||
}
|
||||
|
||||
var fullPath = path.join(that.path, filepath);
|
||||
mkdirp.sync(path.dirname(fullPath));
|
||||
fs.writeFileSync(fullPath, contents);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
TempDir.prototype.prepare = function (files) {
|
||||
rimraf.sync(this.path);
|
||||
mkdirp.sync(this.path);
|
||||
this.create(files);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// TODO: Rewrite to synchronous form
|
||||
TempDir.prototype.prepareGit = function (revisions) {
|
||||
var that = this;
|
||||
|
||||
revisions = object.merge(revisions || {}, this.defaults);
|
||||
|
||||
rimraf.sync(that.path);
|
||||
|
||||
mkdirp.sync(that.path);
|
||||
|
||||
var promise = new Q();
|
||||
|
||||
object.forOwn(revisions, function (files, tag) {
|
||||
promise = promise.then(function () {
|
||||
return that.git('init');
|
||||
}).then(function () {
|
||||
that.glob('./!(.git)').map(function (removePath) {
|
||||
var fullPath = path.join(that.path, removePath);
|
||||
|
||||
rimraf.sync(fullPath);
|
||||
});
|
||||
|
||||
that.create(files, {});
|
||||
}).then(function () {
|
||||
return that.git('add', '-A');
|
||||
}).then(function () {
|
||||
return that.git('commit', '-m"commit"');
|
||||
}).then(function () {
|
||||
return that.git('tag', tag);
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
TempDir.prototype.glob = function (pattern) {
|
||||
return glob.sync(pattern, {
|
||||
cwd: this.path,
|
||||
dot: true
|
||||
});
|
||||
};
|
||||
|
||||
TempDir.prototype.getPath = function (name) {
|
||||
return path.join(this.path, name);
|
||||
};
|
||||
|
||||
TempDir.prototype.read = function (name) {
|
||||
return fs.readFileSync(this.getPath(name), 'utf8');
|
||||
};
|
||||
|
||||
TempDir.prototype.readJson = function (name) {
|
||||
return JSON.parse(this.read(name));
|
||||
};
|
||||
|
||||
TempDir.prototype.exists = function (name) {
|
||||
return fs.existsSync(path.join(this.path, name));
|
||||
};
|
||||
|
||||
return TempDir;
|
||||
})();
|
||||
@@ -1,245 +0,0 @@
|
||||
var assert = require('assert');
|
||||
var path = require('path');
|
||||
|
||||
describe('NPM Config on package.json', function () {
|
||||
beforeEach(function () {
|
||||
delete process.env.npm_package_config_bower_directory;
|
||||
delete process.env.npm_package_config_bower_colors;
|
||||
delete process.env.npm_package_config_bower_resolvers;
|
||||
});
|
||||
|
||||
it('defaults registry entries to default registry', function () {
|
||||
var config = require('../lib/Config').read(null, {});
|
||||
|
||||
assert.deepEqual(config.registry, {
|
||||
'default': 'https://bower.herokuapp.com',
|
||||
'search': [
|
||||
'https://bower.herokuapp.com'
|
||||
],
|
||||
'register': 'https://bower.herokuapp.com',
|
||||
'publish': 'https://bower.herokuapp.com'
|
||||
});
|
||||
});
|
||||
|
||||
it('can change default registry', function () {
|
||||
var config = require('../lib/Config').read(null, { registry: 'https://foobar' });
|
||||
|
||||
assert.deepEqual(config.registry, {
|
||||
'default': 'https://foobar',
|
||||
'search': [
|
||||
'https://foobar',
|
||||
],
|
||||
'register': 'https://foobar',
|
||||
'publish': 'https://foobar'
|
||||
});
|
||||
});
|
||||
|
||||
it('can override single entries in registry configuration', function () {
|
||||
var config = require('../lib/Config').read(null, { registry: { search: 'https://foobar' } });
|
||||
|
||||
assert.deepEqual(config.registry, {
|
||||
'default': 'https://bower.herokuapp.com',
|
||||
'search': [
|
||||
'https://foobar',
|
||||
],
|
||||
'register': 'https://bower.herokuapp.com',
|
||||
'publish': 'https://bower.herokuapp.com'
|
||||
});
|
||||
});
|
||||
|
||||
it('can override single entries in registry configuration and defaults', function () {
|
||||
var config = require('../lib/Config').read(null, { registry: { default: 'https://fizfuz', search: 'https://foobar' } });
|
||||
|
||||
assert.deepEqual(config.registry, {
|
||||
'default': 'https://fizfuz',
|
||||
'search': [
|
||||
'https://foobar',
|
||||
],
|
||||
'register': 'https://fizfuz',
|
||||
'publish': 'https://fizfuz'
|
||||
});
|
||||
});
|
||||
|
||||
it('allows for not providing cwd', function () {
|
||||
var config = require('../lib/Config').read();
|
||||
|
||||
config.tmp = '/foo/bar';
|
||||
config.userAgent = 'firefox';
|
||||
delete config.storage;
|
||||
|
||||
assert.deepEqual(config, {
|
||||
'directory': 'bower_components',
|
||||
'registry': {
|
||||
'default': 'https://bower.herokuapp.com',
|
||||
'search': [
|
||||
'https://bower.herokuapp.com'
|
||||
],
|
||||
'register': 'https://bower.herokuapp.com',
|
||||
'publish': 'https://bower.herokuapp.com'
|
||||
},
|
||||
'shorthandResolver': 'https://github.com/{{owner}}/{{package}}.git',
|
||||
'tmp': '/foo/bar',
|
||||
'timeout': 30000,
|
||||
'ca': {
|
||||
'search': []
|
||||
},
|
||||
'strictSsl': true,
|
||||
'userAgent': 'firefox',
|
||||
'color': true
|
||||
});
|
||||
});
|
||||
|
||||
function assertCAContents(caData, name) {
|
||||
var r = /-----BEGIN CERTIFICATE-----[a-zA-Z0-9+\/=\n\r]+-----END CERTIFICATE-----/;
|
||||
|
||||
assert(caData, name + ' should be set');
|
||||
assert(Array.isArray(caData), name + ' should be an array');
|
||||
assert.equal(2, caData.length);
|
||||
caData.forEach(function(c, i) {
|
||||
assert(c.match(r),
|
||||
name + '[' + i + '] should contain a certificate. Given: ' + JSON.stringify(c));
|
||||
});
|
||||
}
|
||||
|
||||
describe('Setting process.env.npm_package_config', function () {
|
||||
process.env.npm_package_config_bower_directory = 'npm-path';
|
||||
process.env.npm_package_config_bower_colors = 'false';
|
||||
process.env.npm_package_config_bower_resolvers = '[foo,bar,baz]';
|
||||
|
||||
var config = require('../lib/Config').read();
|
||||
|
||||
it('should return "npm-path" for "bower_directory"', function () {
|
||||
assert.equal('npm-path', config.directory);
|
||||
});
|
||||
it('should return "false" for "bower_colors"', function () {
|
||||
assert.equal('false', config.colors);
|
||||
});
|
||||
it('should expand array "false" for "bower_resolvers"', function () {
|
||||
assert.deepEqual(['foo', 'bar', 'baz'], config.resolvers);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Specifying custom CA', function() {
|
||||
|
||||
it('should read the CA file', function() {
|
||||
var config = require('../lib/Config')
|
||||
.read(path.resolve('test/assets/custom-ca'));
|
||||
|
||||
['register', 'publish', 'default'].forEach(function (p) {
|
||||
assertCAContents(config.ca[p], 'config.ca.' + p);
|
||||
});
|
||||
|
||||
assert(Array.isArray(config.ca.search),
|
||||
'ca property search should be an array');
|
||||
|
||||
config.ca.search.forEach(function(c, i) {
|
||||
assertCAContents(c, 'config.ca.search[' + i + ']');
|
||||
});
|
||||
});
|
||||
|
||||
it('should backward-support certificate inside .bowerrc', function() {
|
||||
var config = require('../lib/Config')
|
||||
.read(path.resolve('test/assets/custom-ca-embed'));
|
||||
|
||||
['register', 'publish', 'default'].forEach(function (p) {
|
||||
assertCAContents(config.ca[p], 'config.ca.' + p);
|
||||
});
|
||||
|
||||
assert(Array.isArray(config.ca.search),
|
||||
'ca property search should be an array');
|
||||
config.ca.search.forEach(function(c, i) {
|
||||
assertCAContents(c, 'config.ca.search[' + i + ']');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setting ENV variables', function () {
|
||||
beforeEach(function () {
|
||||
delete process.env.no_proxy;
|
||||
delete process.env.http_proxy;
|
||||
delete process.env.https_proxy;
|
||||
delete process.env.NO_PROXY;
|
||||
delete process.env.HTTP_PROXY;
|
||||
delete process.env.HTTPS_PROXY;
|
||||
});
|
||||
|
||||
it('sets env variables', function () {
|
||||
require('../lib/Config').read('test/assets/env-variables');
|
||||
|
||||
assert.equal(process.env.HTTP_PROXY, 'http://HTTP_PROXY');
|
||||
assert.equal(process.env.HTTPS_PROXY, 'http://HTTPS_PROXY');
|
||||
assert.equal(process.env.NO_PROXY, 'google.com');
|
||||
|
||||
assert.equal(process.env.http_proxy, undefined);
|
||||
assert.equal(process.env.https_proxy, undefined);
|
||||
assert.equal(process.env.no_proxy, undefined);
|
||||
});
|
||||
|
||||
it('restores env variables', function () {
|
||||
process.env.HTTP_PROXY = 'a';
|
||||
process.env.HTTPS_PROXY = 'b';
|
||||
process.env.NO_PROXY = 'c';
|
||||
process.env.http_proxy = 'd';
|
||||
process.env.https_proxy = 'e';
|
||||
process.env.no_proxy = 'f';
|
||||
|
||||
var config = require('../lib/Config').create('test/assets/env-variables').load();
|
||||
config.restore();
|
||||
|
||||
assert.equal(process.env.HTTP_PROXY, 'a');
|
||||
assert.equal(process.env.HTTPS_PROXY, 'b');
|
||||
assert.equal(process.env.NO_PROXY, 'c');
|
||||
|
||||
assert.equal(process.env.http_proxy, 'd');
|
||||
assert.equal(process.env.https_proxy, 'e');
|
||||
assert.equal(process.env.no_proxy, 'f');
|
||||
});
|
||||
|
||||
it('restores env variables if they are undefined', function () {
|
||||
var config = require('../lib/Config').create('test/assets/env-variables').load();
|
||||
config.restore();
|
||||
|
||||
assert.equal(process.env.HTTP_PROXY, undefined);
|
||||
assert.equal(process.env.HTTPS_PROXY, undefined);
|
||||
assert.equal(process.env.NO_PROXY, undefined);
|
||||
|
||||
assert.equal(process.env.http_proxy, undefined);
|
||||
assert.equal(process.env.https_proxy, undefined);
|
||||
assert.equal(process.env.no_proxy, undefined);
|
||||
});
|
||||
|
||||
it('allows for overriding options', function () {
|
||||
require('../lib/Config').read('test/assets/env-variables', {
|
||||
httpsProxy: 'http://other-proxy.local'
|
||||
});
|
||||
|
||||
assert.equal(process.env.HTTP_PROXY, 'http://HTTP_PROXY');
|
||||
assert.equal(process.env.HTTPS_PROXY, 'http://other-proxy.local');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Allow ${ENV} variables in .bowerrc', function() {
|
||||
|
||||
it('sets values from process.env', function() {
|
||||
process.env._BOWERRC_MY_PACKAGES = 'a';
|
||||
process.env._BOWERRC_MY_TMP = '/tmp/b';
|
||||
|
||||
var config = require('../lib/Config').read('test/assets/env-variables-values');
|
||||
assert.equal('a', config.storage.packages);
|
||||
assert.equal('/tmp/b', config.tmp);
|
||||
assert.equal('${_myshellvar}', config.scripts.postinstall);
|
||||
});
|
||||
});
|
||||
|
||||
describe('untildify paths in .bowerrc', function() {
|
||||
|
||||
it('resolve ~/ in .bowerrc', function() {
|
||||
var config = require('../lib/Config').read('test/assets/env-variables-values');
|
||||
var untildify = require('untildify');
|
||||
|
||||
assert.equal(untildify('~/.bower-test/registry') , config.storage.registry);
|
||||
});
|
||||
});
|
||||
|
||||
require('./util/index');
|
||||
@@ -1,3 +0,0 @@
|
||||
describe('util', function () {
|
||||
require('./rc');
|
||||
});
|
||||
@@ -1,84 +0,0 @@
|
||||
var expect = require('expect.js');
|
||||
var helpers = require('../helpers');
|
||||
|
||||
describe('rc', function() {
|
||||
var tempDir = new helpers.TempDir();
|
||||
var tempDirBowerrc = new helpers.TempDir();
|
||||
|
||||
var rc = require('../../lib/util/rc');
|
||||
|
||||
tempDir.prepare({
|
||||
'.bowerrc': {
|
||||
key: 'value'
|
||||
},
|
||||
'child/.bowerrc': {
|
||||
key2: 'value2'
|
||||
},
|
||||
'child2/.bowerrc': {
|
||||
key: 'valueShouldBeOverwriteParent'
|
||||
},
|
||||
'child3/bower.json': {
|
||||
name: 'without-bowerrc'
|
||||
},
|
||||
'other_dir/.bowerrc': {
|
||||
key: 'othervalue'
|
||||
}
|
||||
});
|
||||
|
||||
tempDirBowerrc.prepare({
|
||||
'.bowerrc/foo': {
|
||||
key: 'bar'
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
it('correctly reads .bowerrc files', function() {
|
||||
var config = rc('bower', tempDir.path);
|
||||
|
||||
expect(config.key).to.eql('value');
|
||||
expect(config.key2).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('correctly reads .bowerrc files from child', function() {
|
||||
var config = rc('bower', tempDir.path + '/child/');
|
||||
|
||||
expect(config.key).to.eql('value');
|
||||
expect(config.key2).to.eql('value2');
|
||||
});
|
||||
|
||||
it('correctly reads .bowerrc files from child2', function() {
|
||||
var config = rc('bower', tempDir.path + '/child2/');
|
||||
|
||||
expect(config.key).to.eql('valueShouldBeOverwriteParent');
|
||||
expect(config.key2).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('correctly reads .bowerrc files from child3', function() {
|
||||
var config = rc('bower', tempDir.path + '/child3/');
|
||||
|
||||
expect(config.key).to.eql('value');
|
||||
expect(config.key2).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('loads the .bowerrc file from the cwd specified on the command line', function(){
|
||||
var argv = {
|
||||
'config': {
|
||||
'cwd': tempDir.path + '/other_dir/'
|
||||
}
|
||||
};
|
||||
|
||||
var config = rc('bower', tempDir.path, argv);
|
||||
|
||||
expect(config.key).to.eql('othervalue');
|
||||
|
||||
});
|
||||
|
||||
it('throws an easy to understand error if .bowerrc is a dir', function() {
|
||||
// Gotta wrap this to catch the error
|
||||
var config = function () {
|
||||
rc('bower', tempDirBowerrc.path);
|
||||
};
|
||||
|
||||
expect(config).to.throwError(/should not be a directory/);
|
||||
});
|
||||
});
|
||||
@@ -1,12 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
2
packages/bower-endpoint-parser/.gitignore
vendored
2
packages/bower-endpoint-parser/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
/node_modules
|
||||
/npm-debug.*
|
||||
@@ -1,61 +0,0 @@
|
||||
{
|
||||
"predef": [
|
||||
"console",
|
||||
"describe",
|
||||
"it",
|
||||
"after",
|
||||
"afterEach",
|
||||
"before",
|
||||
"beforeEach"
|
||||
],
|
||||
|
||||
"indent": 4,
|
||||
"node": true,
|
||||
"devel": true,
|
||||
|
||||
"bitwise": false,
|
||||
"curly": false,
|
||||
"eqeqeq": true,
|
||||
"forin": false,
|
||||
"immed": true,
|
||||
"latedef": false,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": false,
|
||||
"nonew": true,
|
||||
"plusplus": false,
|
||||
"regexp": false,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"quotmark": "single",
|
||||
"strict": false,
|
||||
"trailing": true,
|
||||
"camelcase": true,
|
||||
|
||||
"asi": false,
|
||||
"boss": true,
|
||||
"debug": false,
|
||||
"eqnull": true,
|
||||
"esnext": false,
|
||||
"evil": false,
|
||||
"expr": true,
|
||||
"funcscope": false,
|
||||
"globalstrict": false,
|
||||
"iterator": false,
|
||||
"lastsemic": false,
|
||||
"laxbreak": true,
|
||||
"laxcomma": false,
|
||||
"loopfunc": true,
|
||||
"multistr": false,
|
||||
"onecase": true,
|
||||
"regexdash": false,
|
||||
"scripturl": false,
|
||||
"smarttabs": false,
|
||||
"shadow": false,
|
||||
"sub": false,
|
||||
"supernew": true,
|
||||
"validthis": false,
|
||||
|
||||
"nomen": false,
|
||||
"white": true
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2012 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
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,102 +0,0 @@
|
||||
# endpoint-parser [](http://travis-ci.org/bower/endpoint-parser)
|
||||
|
||||
Little module that helps with endpoints parsing.
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### .decompose(endpoint)
|
||||
|
||||
Decomposes a endpoint into `name`, `source` and `target`.
|
||||
|
||||
```js
|
||||
var endpointParser = require('bower-endpoint-parser');
|
||||
|
||||
endpointParser.decompose('jquery#~2.0.0');
|
||||
// { name: '', source: 'jquery', target: '~2.0.0' }
|
||||
|
||||
endpointParser.decompose('backbone=backbone-amd#~1.0.0');
|
||||
// { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }
|
||||
|
||||
endpointParser.decompose('http://twitter.github.io/bootstrap/assets/bootstrap.zip');
|
||||
// { name: '', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }
|
||||
|
||||
endpointParser.decompose('bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip');
|
||||
// { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }
|
||||
```
|
||||
|
||||
### .compose(decEndpoint)
|
||||
|
||||
Inverse of `decompose()`.
|
||||
Takes a decomposed endpoint and composes it back into a string.
|
||||
|
||||
```js
|
||||
var endpointParser = require('bower-endpoint-parser');
|
||||
|
||||
endpointParser.compose({ name: '', source: 'jquery', target: '~2.0.0' });
|
||||
// jquery#~2.0.0
|
||||
|
||||
endpointParser.compose({ name: 'backbone', source: 'backbone-amd', target: '~1.0.0' });
|
||||
// backbone=backbone-amd#~1.0.0
|
||||
|
||||
endpointParser.compose({ name: '', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' });
|
||||
// http://twitter.github.io/bootstrap/assets/bootstrap.zip
|
||||
|
||||
endpointParser.compose({ name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' });
|
||||
// bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip
|
||||
```
|
||||
|
||||
### .json2decomposed(key, value)
|
||||
|
||||
Similar to `decompose()` but specially designed to be used when parsing `bower.json` dependencies.
|
||||
For instance, in a `bower.json` like this:
|
||||
|
||||
```js
|
||||
{
|
||||
"name": "foo",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"jquery": "~1.9.1",
|
||||
"backbone": "backbone-amd#~1.0.0",
|
||||
"bootstrap": "http://twitter.github.io/bootstrap/assets/bootstrap"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You would call `json2decomposed` like so:
|
||||
|
||||
```js
|
||||
endpointParser.json2decomposed('jquery', '~1.9.1');
|
||||
// { name: 'jquery', source: 'jquery', target: '~1.9.1' }
|
||||
|
||||
endpointParser.json2decomposed('backbone', 'backbone-amd#~1.0.0');
|
||||
// { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }
|
||||
|
||||
endpointParser.json2decomposed('bootstrap', 'http://twitter.github.io/bootstrap/assets/bootstrap');
|
||||
// { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }
|
||||
```
|
||||
|
||||
### .decomposed2json(decEndpoint)
|
||||
|
||||
Inverse of `json2decomposed()`.
|
||||
Takes a decomposed endpoint and composes it to be saved to `bower.json`.
|
||||
|
||||
```js
|
||||
var endpointParser = require('bower-endpoint-parser');
|
||||
|
||||
endpointParser.decomposed2json({ name: 'jquery', source: 'jquery', target: '~2.0.0' });
|
||||
// { jquery: '~2.0.0' }
|
||||
|
||||
endpointParser.decomposed2json({ name: 'backbone', source: 'backbone-amd', target: '~1.0.0' });
|
||||
// { backbone: 'backbone-amd#~2.0.0' }
|
||||
|
||||
endpointParser.decomposed2json({ name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' });
|
||||
// { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }
|
||||
```
|
||||
|
||||
This function throws an exception if the `name` from the decomposed endpoint is empty.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
|
||||
@@ -1,128 +0,0 @@
|
||||
function decompose(endpoint) {
|
||||
// Note that we allow spaces in targets and sources but they are trimmed
|
||||
var regExp = /^(?:([\w\-]|(?:[\w\.\-]+[\w\-])?)=)?([^\|#]+)(?:#(.*))?$/;
|
||||
var matches = endpoint.match(regExp);
|
||||
var target;
|
||||
var error;
|
||||
|
||||
if (!matches) {
|
||||
error = new Error('Invalid endpoint: ' + endpoint);
|
||||
error.code = 'EINVEND';
|
||||
throw error;
|
||||
}
|
||||
|
||||
target = trim(matches[3]);
|
||||
|
||||
return {
|
||||
name: trim(matches[1]),
|
||||
source: trim(matches[2]),
|
||||
target: isWildcard(target) ? '*' : target
|
||||
};
|
||||
}
|
||||
|
||||
function compose(decEndpoint) {
|
||||
var name = trim(decEndpoint.name);
|
||||
var source = trim(decEndpoint.source);
|
||||
var target = trim(decEndpoint.target);
|
||||
var composed = '';
|
||||
|
||||
if (name) {
|
||||
composed += name + '=';
|
||||
}
|
||||
|
||||
composed += source;
|
||||
|
||||
if (!isWildcard(target)) {
|
||||
composed += '#' + target;
|
||||
}
|
||||
|
||||
return composed;
|
||||
}
|
||||
|
||||
function json2decomposed(key, value) {
|
||||
var endpoint;
|
||||
var split;
|
||||
var error;
|
||||
|
||||
key = trim(key);
|
||||
value = trim(value);
|
||||
|
||||
if (!key) {
|
||||
error = new Error('The key must be specified');
|
||||
error.code = 'EINVEND';
|
||||
throw error;
|
||||
}
|
||||
|
||||
endpoint = key + '=';
|
||||
split = value.split('#').map(trim);
|
||||
|
||||
// If # was found, the source was specified
|
||||
if (split.length > 1) {
|
||||
endpoint += (split[0] || key) + '#' + split[1];
|
||||
// Check if value looks like a source
|
||||
} else if (isSource(value)) {
|
||||
endpoint += value + '#*';
|
||||
// Otherwise use the key as the source
|
||||
} else {
|
||||
endpoint += key + '#' + split[0];
|
||||
}
|
||||
|
||||
return decompose(endpoint);
|
||||
}
|
||||
|
||||
function decomposed2json(decEndpoint) {
|
||||
var error;
|
||||
var name = trim(decEndpoint.name);
|
||||
var source = trim(decEndpoint.source);
|
||||
var target = trim(decEndpoint.target);
|
||||
var value = '';
|
||||
var ret = {};
|
||||
|
||||
if (!name) {
|
||||
error = new Error('Decomposed endpoint must have a name');
|
||||
error.code = 'EINVEND';
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Add source only if different than the name
|
||||
if (source !== name) {
|
||||
value += source;
|
||||
}
|
||||
|
||||
// If value is empty, we append the target always
|
||||
if (!value) {
|
||||
if (isWildcard(target)) {
|
||||
value += '*';
|
||||
} else {
|
||||
if (target.indexOf('/') !== -1) {
|
||||
value += '#' + target;
|
||||
} else {
|
||||
value += target;
|
||||
}
|
||||
}
|
||||
// Otherwise append only if not a wildcard or source does not look like a source
|
||||
} else if (!isWildcard(target) || !isSource(source)) {
|
||||
value += '#' + (target || '*');
|
||||
}
|
||||
|
||||
ret[name] = value;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function trim(str) {
|
||||
return str ? str.trim() : '';
|
||||
}
|
||||
|
||||
function isWildcard(target) {
|
||||
return !target || target === '*' || target === 'latest';
|
||||
}
|
||||
|
||||
function isSource(value) {
|
||||
return (/[\/\\@]/).test(value);
|
||||
}
|
||||
|
||||
module.exports.decompose = decompose;
|
||||
module.exports.compose = compose;
|
||||
module.exports.json2decomposed = json2decomposed;
|
||||
module.exports.decomposed2json = decomposed2json;
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "bower-endpoint-parser",
|
||||
"version": "0.2.2",
|
||||
"description": "Little module that helps with endpoints parsing.",
|
||||
"author": "Twitter",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/bower/endpoint-parser/blob/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/bower/endpoint-parser.git"
|
||||
},
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"expect.js": "~0.2.0",
|
||||
"mocha": "~1.12.0",
|
||||
"mout": "~0.9.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user