Compare commits

..

1 Commits

Author SHA1 Message Date
Max Woghiren
5ed2272e51 Added gradle distribution URL updating. 2014-09-22 16:04:24 -04:00
607 changed files with 40509 additions and 29373 deletions

View File

@ -1,46 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
github:
description: Apache Cordova Android
homepage: https://cordova.apache.org/
labels:
- cordova
- cordova-platform
- android
- java
- mobile
- javascript
- nodejs
- hacktoberfest
features:
wiki: false
issues: true
projects: true
enabled_merge_buttons:
squash: true
merge: false
rebase: false
notifications:
commits: commits@cordova.apache.org
issues: issues@cordova.apache.org
pullrequests_status: issues@cordova.apache.org
pullrequests_comment: issues@cordova.apache.org

View File

@ -1,3 +0,0 @@
templates/project/assets/www/cordova.js
test/android/app
test/androidx/app

View File

@ -1,27 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
extends: '@cordova/eslint-config/node'
overrides:
- files: [spec/**/*.js]
extends: '@cordova/eslint-config/node-tests'
rules:
prefer-promise-reject-errors: off
- files: [cordova-js-src/**/*.js]
extends: '@cordova/eslint-config/browser'

94
.gitattributes vendored
View File

@ -1,94 +0,0 @@
* text eol=lf
# source code
*.php text
*.css text
*.sass text
*.scss text
*.less text
*.styl text
*.js text
*.coffee text
*.json text
*.htm text
*.html text
*.xml text
*.svg text
*.txt text
*.ini text
*.inc text
*.pl text
*.rb text
*.py text
*.scm text
*.sql text
*.sh text
*.bat text
# templates
*.ejs text
*.hbt text
*.jade text
*.haml text
*.hbs text
*.dot text
*.tmpl text
*.phtml text
# server config
.htaccess text
# git config
.gitattributes text
.gitignore text
.gitconfig text
# code analysis config
.jshintrc text
.jscsrc text
.jshintignore text
.csslintrc text
# misc config
*.yaml text
*.yml text
.editorconfig text
# build config
*.npmignore text
*.bowerrc text
# Heroku
Procfile text
.slugignore text
# Documentation
*.md text
LICENSE text
AUTHORS text
#
## These files are binary and should be left untouched
#
# (binary is a macro for -text -diff)
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.mov binary
*.mp4 binary
*.mp3 binary
*.flv binary
*.fla binary
*.swf binary
*.gz binary
*.zip binary
*.7z binary
*.ttf binary
*.eot binary
*.woff binary
*.pyc binary
*.pdf binary

View File

@ -1,42 +0,0 @@
<!--
Please have a look at the issue templates you get when you click "New issue" in the GitHub UI.
We very much prefer issues created by using one of these templates.
-->
### Issue Type
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
- [ ] Bug Report
- [ ] Feature Request
- [ ] Support Question
## Description
## Information
<!-- Include all relevant information that might help understand and reproduce the problem -->
### Command or Code
<!-- What command or code is needed to reproduce the problem? -->
### Environment, Platform, Device
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
### Version information
<!--
What are relevant versions you are using?
For example:
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
Other Frameworks: Ionic Framework and CLI version
Operating System, Android Studio, Xcode etc.
-->
## Checklist
<!-- Please check the boxes by putting an `x` in the `[ ]` like so: `[x]` -->
- [ ] I searched for already existing GitHub issues about this
- [ ] I updated all Cordova tooling to their most recent version
- [ ] I included all the necessary information above

View File

@ -1,50 +0,0 @@
---
name: 🐛 Bug Report
about: If something isn't working as expected.
---
# Bug Report
## Problem
### What is expected to happen?
### What does actually happen?
## Information
<!-- Include all relevant information that might help understand and reproduce the problem -->
### Command or Code
<!-- What command or code is needed to reproduce the problem? -->
### Environment, Platform, Device
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
### Version information
<!--
What are relevant versions you are using?
For example:
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
Other Frameworks: Ionic Framework and CLI version
Operating System, Android Studio, Xcode etc.
-->
## Checklist
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
- [ ] I searched for existing GitHub issues
- [ ] I updated all Cordova tooling to most recent version
- [ ] I included all the necessary information above

View File

@ -1,29 +0,0 @@
---
name: 🚀 Feature Request
about: A suggestion for a new functionality
---
# Feature Request
## Motivation Behind Feature
<!-- Why should this feature be implemented? What problem does it solve? -->
## Feature Description
<!--
Describe your feature request in detail
Please provide any code examples or screenshots of what this feature would look like
Are there any drawbacks? Will this break anything for existing users?
-->
## Alternatives or Workarounds
<!--
Describe alternatives or workarounds you are currently using
Are there ways to do this with existing functionality?
-->

View File

@ -1,27 +0,0 @@
---
name: 💬 Support Question
about: If you have a question, please check out our Slack or StackOverflow!
---
<!------------^ Click "Preview" for a nicer view! -->
Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_.
For usage and support questions, please check out the resources below. Thanks!
---
You can get answers to your usage and support questions about **Apache Cordova** on:
* Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/)
* StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova`
---
If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels:
* **Ionic Framework**
* [Ionic Community Forum](https://forum.ionicframework.com/)
* [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/)
* **PhoneGap**
* [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap)

View File

@ -1,35 +0,0 @@
<!--
Please make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick reference, for complete details please see our Contributor Guidelines:
http://cordova.apache.org/contribute/contribute_guidelines.html
Thanks!
-->
### Platforms affected
### Motivation and Context
<!-- Why is this change required? What problem does it solve? -->
<!-- If it fixes an open issue, please link to the issue here. -->
### Description
<!-- Describe your changes in detail -->
### Testing
<!-- Please describe in detail how you tested your changes. -->
### Checklist
- [ ] I've run the tests to see all new and existing tests pass
- [ ] I added automated test coverage as appropriate for this change
- [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`)
- [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/))
- [ ] I've updated the documentation if necessary

View File

@ -1,64 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
name: Node CI
on: [push, pull_request]
jobs:
test:
name: NodeJS ${{ matrix.node-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [16.x, 18.x, 20.x]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: set up JDK 11
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
- name: Environment Information
run: |
node --version
npm --version
gradle --version
- name: npm install and test
run: |
npm i
npm t
env:
CI: true
- name: upload coverage
if: success()
uses: codecov/codecov-action@v3
with:
name: ${{ runner.os }} node.js ${{ matrix.node-version }}

74
.gitignore vendored
View File

@ -1,6 +1,32 @@
.DS_Store
.gradle
default.properties
gen
assets/www/cordova.js
framework/assets/www/.tmp*
local.properties
framework/lib
proguard.cfg
proguard.cfg
proguard-project.txt
framework/bin
framework/test/org/apache/cordova/*.class
framework/assets/www/.DS_Store
framework/assets/www/cordova-*.js
framework/assets/www/phonegap-*.js
framework/libs
framework/javadoc-public
framework/javadoc-private
test/libs
example
./test
test/bin
test/assets/www/.tmp*
test/assets/www/cordova.js
test/cordova/plugins/org.apache.cordova.device/www/device.js
test/cordova/plugins/org.apache.cordova.device/src/android/Device.java
tmp/**
.metadata
tmp/**/*
Thumbs.db
Desktop.ini
*.tmp
@ -8,50 +34,6 @@ Desktop.ini
*.swp
*.class
*.jar
default.properties
gen
assets/www/cordova.js
local.properties
proguard.cfg
proguard-project.txt
example
/coverage
/framework/lib
/framework/build
/framework/bin
/framework/assets/www/.DS_Store
/framework/assets/www/cordova-*.js
/framework/assets/www/phonegap-*.js
/framework/libs
/framework/javadoc-public
/framework/javadoc-private
**/assets/www/cordova.js
/test/.externalNativeBuild
/test/androidx/gradle
/test/androidx/gradlew
/test/androidx/gradlew.bat
/test/androidx/cdv-gradle-config.json
/test/assets/www/.tmp*
/test/assets/www/cordova.js
/test/bin
/test/build
/test/captures
/test/libs
tmp/**
tmp/**/*
!/spec/fixtures/org.test.plugins.dummyplugin/src/android/TestLib.jar
# IntelliJ IDEA files
**/.idea/**/*
*.iml
npm-debug.log
node_modules/
coverage/
.nyc_output/
# Eclipse Buildship files
.project
.settings
.classpath
.idea

View File

@ -1,6 +0,0 @@
.*
coverage
test
spec
framework/build
cordova-js-src

2
.npmrc
View File

@ -1,2 +0,0 @@
registry=https://registry.npmjs.org

View File

@ -1,8 +0,0 @@
*.properties
templates
gen
proguard-project.txt
spec
framework/build
ic_launcher.png
build

View File

@ -4,5 +4,5 @@
GUESS_FIELDS = True
OPEN_BROWSER = True
TARGET_GROUPS = 'cordova'
REVIEWBOARD_URL = 'https://reviews.apache.org'
REVIEWBOARD_URL = 'http://reviews.apache.org'

5
.travis.yml Normal file
View File

@ -0,0 +1,5 @@
language: android
install: npm install
script:
- npm test
- npm run test-build

View File

@ -27,11 +27,11 @@ There are multiple ways to contribute: report bugs, improve the docs, and
contribute code.
For instructions on this, start with the
[contribution overview](http://cordova.apache.org/contribute/).
[contribution overview](http://cordova.apache.org/#contribute).
The details are explained there, but the important items are:
- Check for Github issues that corresponds to your contribution and link or create them if necessary.
- Sign and submit an Apache ICLA (Contributor License Agreement).
- Have a Jira issue open that corresponds to your contribution.
- Run the tests so your patch doesn't break existing functionality.
We look forward to your contributions!

87
LICENSE
View File

@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2015-2020 Apache Cordova
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -200,3 +200,88 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ADDITIONAL LICENSES:
================================================================================
bin/node_modules/q
================================================================================
Copyright 20092012 Kristopher Michael Kowal. All rights reserved.
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.
================================================================================
bin/node_modules/shelljs
================================================================================
Copyright (c) 2012, Artur Adib <aadib@mozilla.com>
All rights reserved.
You may use this project under the terms of the New BSD license as follows:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Artur Adib nor the
names of the contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
bin/node_modules/shelljs
================================================================================
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
All rights reserved.
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.

16
NOTICE
View File

@ -1,5 +1,17 @@
Apache Cordova
Copyright 2015-2020 The Apache Software Foundation
Copyright 2014 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
The Apache Software Foundation (http://www.apache.org)
=========================================================================
== NOTICE file corresponding to the section 4 d of ==
== the Apache License, Version 2.0, ==
== in this case for the Android-specific code. ==
=========================================================================
This product includes software developed as part of
The Android Open Source Project (http://source.android.com).
This software includes software developed at Square, Inc.
Copyright (C) 2013 Square, Inc.

View File

@ -18,54 +18,74 @@
# under the License.
#
-->
Cordova Android
===
# Cordova Android
Cordova Android is an Android application library that allows for Cordova-based
projects to be built for the Android Platform. Cordova based applications are,
at the core, applications written with web technology: HTML, CSS and JavaScript.
[![NPM](https://nodei.co/npm/cordova-android.png)](https://nodei.co/npm/cordova-android/)
[Apache Cordova](http://cordova.io) is a project of The Apache Software Foundation (ASF).
[![Node CI](https://github.com/apache/cordova-android/workflows/Node%20CI/badge.svg?branch=master)](https://github.com/apache/cordova-android/actions?query=branch%3Amaster)
[![codecov.io](https://codecov.io/github/apache/cordova-android/coverage.svg?branch=master)](https://codecov.io/github/apache/cordova-android?branch=master)
Cordova Android is an Android application library that allows for Cordova-based projects to be built for the Android Platform. Cordova based applications are, at the core, applications written with web technology: HTML, CSS and JavaScript.
Requires
---
[Apache Cordova](https://cordova.apache.org/) is a project of [The Apache Software Foundation (ASF)](https://apache.org/).
- Java JDK 1.5 or greater
- Apache Ant 1.8.0 or greater
- Android SDK [http://developer.android.com](http://developer.android.com)
## Requirements
* Java Development Kit (JDK) 11
* [Android SDK](https://developer.android.com/)
* [Node.js](https://nodejs.org)
Cordova Android Developer Tools
---
## Create a Cordova project
The Cordova developer tooling is split between general tooling and project level tooling.
Follow the instructions in the [**Create your first Cordova app**](https://cordova.apache.org/docs/en/latest/guide/cli/index.html) section of [Apache Cordova Docs](https://cordova.apache.org/docs/en/latest/)
General Commands
To use a **shared framework**, for example in development, link the appropriate cordova-android platform folder path:
./bin/create [path package activity] ... creates the ./example app or a cordova android project
./bin/check_reqs ....................... checks that your environment is set up for cordova-android development
./bin/update [path] .................... updates an existing cordova-android project to the version of the framework
```bash
cordova platform add --link /path/to/cordova-android
```
Project Commands
## Updating a Cordova project
These commands live in a generated Cordova Android project. Any interactions with the emulator require you to have an AVD defined.
When you install a new version of the [`Cordova CLI`](https://www.npmjs.com/package/cordova) that pins a new version of the [`Cordova-Android`](https://www.npmjs.com/package/cordova-android) platform, you can follow these simple upgrade steps within your project:
./cordova/clean ........................ cleans the project
./cordova/build ........................ calls `clean` then compiles the project
./cordova/log ........................ streams device or emulator logs to STDOUT
./cordova/run ........................ calls `build` then deploys to a connected Android device. If no Android device is detected, will launch an emulator and deploy to it.
./cordova/version ...................... returns the cordova-android version of the current project
```bash
cordova platform rm android
cordova platform add android
```
Importing a Cordova Android Project into Eclipse
----
## Debugging in Android Studio
1. File > New > Project...
2. Android > Android Project
3. Create project from existing source (point to the generated app found in tmp/android)
4. Right click on libs/cordova.jar and add to build path
5. Right click on the project root: Run as > Run Configurations
6. Click on the Target tab and select Manual (this way you can choose the emulator or device to build to)
Import project in Android Studio through _File > Open_ and targeting `/path/to/your-cdv-project/platforms/android/`.
Building without the Tooling
---
Note: The Developer Tools handle this. This is only to be done if the tooling fails, or if
you are developing directly against the framework.
## How to Test Repo Development
```bash
npm install
npm test
```
To create your `cordova.jar` file, run in the framework directory:
## Further reading
android update project -p . -t android-19
ant jar
* [Apache Cordova](https://cordova.apache.org/)
Running Tests
----
Please see details under test/README.md.
Further Reading
----
- [http://developer.android.com](http://developer.android.com)
- [http://cordova.apache.org/](http://cordova.apache.org)
- [http://wiki.apache.org/cordova/](http://wiki.apache.org/cordova/)

File diff suppressed because it is too large Load Diff

1
VERSION Normal file
View File

@ -0,0 +1 @@
4.0.0-dev

View File

@ -19,9 +19,11 @@
under the License.
*/
const android_sdk = require('cordova-android/lib/android_sdk');
var android_sdk_version = require('./lib/android_sdk_version');
android_sdk.print_newest_available_sdk_target().catch(err => {
console.error(err);
android_sdk_version.run().done(null, function(err) {
console.log(err);
process.exit(2);
});

View File

@ -0,0 +1,26 @@
:: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations
:: under the License.
@ECHO OFF
SET script_path="%~dp0android_sdk_version"
IF EXIST %script_path% (
node "%script_path%" %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'android_sdk_version' script in 'bin' folder, aborting...>&2
EXIT /B 1
)

View File

@ -1,3 +1,5 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@ -17,17 +19,13 @@
under the License.
*/
package org.apache.cordova;
var check_reqs = require('./lib/check_reqs');
public interface ICordovaCookieManager {
public void setCookiesEnabled(boolean accept);
public void setCookie(final String url, final String value);
public String getCookie(final String url);
public void clearCookies();
public void flush();
};
check_reqs.run().done(
function success() {
console.log('Looks like your environment fully supports cordova-android development!');
}, function fail(err) {
console.log(err);
process.exit(2);
}
);

26
bin/check_reqs.bat Normal file
View File

@ -0,0 +1,26 @@
:: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations
:: under the License.
@ECHO OFF
SET script_path="%~dp0check_reqs"
IF EXIST %script_path% (
node "%script_path%" %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'check_reqs' script in 'bin' folder, aborting...>&2
EXIT /B 1
)

36
bin/create Executable file
View File

@ -0,0 +1,36 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var path = require('path');
var create = require('./lib/create');
var args = require('./lib/simpleargs').getArgs(process.argv);
if (args['--help'] || args._.length === 0) {
console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'create')) + ' <path_to_new_project> <package_name> <project_name> [<template_path>] [--shared]');
console.log(' <path_to_new_project>: Path to your new Cordova Android project');
console.log(' <package_name>: Package name, following reverse-domain style convention');
console.log(' <project_name>: Project name');
console.log(' <template_path>: Path to a custom application template to use');
console.log(' --shared will use the CordovaLib project directly instead of making a copy.');
process.exit(1);
}
create.createProject(args._[0], args._[1], args._[2], args._[3], args['--shared'], args['--cli']).done();

26
bin/create.bat Normal file
View File

@ -0,0 +1,26 @@
:: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations
:: under the License.
@ECHO OFF
SET script_path="%~dp0create"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'create' script in 'bin' folder, aborting...>&2
EXIT /B 1
)

65
bin/lib/android_sdk_version.js Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var shell = require('shelljs'),
child_process = require('child_process'),
Q = require('q');
get_highest_sdk = function(results){
var reg = /\d+/;
var apiLevels = [];
for(var i=0;i<results.length;i++){
apiLevels[i] = parseInt(results[i].match(reg)[0]);
}
apiLevels.sort(function(a,b){return b-a});
console.log(apiLevels[0]);
}
get_sdks = function() {
var d = Q.defer();
child_process.exec('android list targets', function(err, stdout, stderr) {
if (err) d.reject(stderr);
else d.resolve(stdout);
});
return d.promise.then(function(output) {
var reg = /android-\d+/gi;
var results = output.match(reg);
if(results.length===0){
return Q.reject(new Error('No android sdks installed.'));
}else{
get_highest_sdk(results);
}
return Q();
}, function(stderr) {
if (stderr.match(/command\snot\sfound/) || stderr.match(/'android' is not recognized/)) {
return Q.reject(new Error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.'));
} else {
return Q.reject(new Error('An error occurred while listing Android targets'));
}
});
}
module.exports.run = function() {
return Q.all([get_sdks()]);
}

229
bin/lib/check_reqs.js Normal file
View File

@ -0,0 +1,229 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var shelljs = require('shelljs'),
child_process = require('child_process'),
Q = require('q'),
path = require('path'),
fs = require('fs'),
which = require('which'),
ROOT = path.join(__dirname, '..', '..');
var isWindows = process.platform == 'win32';
function forgivingWhichSync(cmd) {
try {
return which.sync(cmd);
} catch (e) {
return '';
}
}
function tryCommand(cmd, errMsg) {
var d = Q.defer();
child_process.exec(cmd, function(err, stdout, stderr) {
if (err) d.reject(new Error(errMsg));
else d.resolve(stdout);
});
return d.promise;
}
// Get valid target from framework/project.properties
module.exports.get_target = function() {
function extractFromFile(filePath) {
var target = shelljs.grep(/\btarget=/, filePath);
if (!target) {
throw new Error('Could not find android target within: ' + filePath);
}
return target.split('=')[1].trim();
}
if (fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
return extractFromFile(path.join(ROOT, 'framework', 'project.properties'));
}
if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
// if no target found, we're probably in a project and project.properties is in ROOT.
return extractFromFile(path.join(ROOT, 'project.properties'));
}
throw new Error('Could not find android target. File missing: ' + path.join(ROOT, 'project.properties'));
}
// Returns a promise. Called only by build and clean commands.
module.exports.check_ant = function() {
return tryCommand('ant -version', 'Failed to run "ant -version", make sure you have ant installed and added to your PATH.');
};
// Returns a promise. Called only by build and clean commands.
module.exports.check_gradle = function() {
var sdkDir = process.env['ANDROID_HOME'];
var wrapperDir = path.join(sdkDir, 'tools', 'templates', 'gradle', 'wrapper');
if (!fs.existsSync(wrapperDir)) {
return Q.reject(new Error('Could not find gradle wrapper within android sdk. Might need to update your Android SDK.\n' +
'Looked here: ' + wrapperDir));
}
return Q.when();
};
// Returns a promise.
module.exports.check_java = function() {
var javacPath = forgivingWhichSync('javac');
var hasJavaHome = !!process.env['JAVA_HOME'];
return Q().then(function() {
if (hasJavaHome) {
// Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
if (!javacPath) {
process.env['PATH'] += path.delimiter + path.join(process.env['JAVA_HOME'], 'bin');
}
} else {
if (javacPath) {
// OS X has a command for finding JAVA_HOME.
if (fs.existsSync('/usr/libexec/java_home')) {
return tryCommand('/usr/libexec/java_home', 'Failed to run: /usr/libexec/java_home')
.then(function(stdout) {
process.env['JAVA_HOME'] = stdout.trim();
});
} else {
// See if we can derive it from javac's location.
var maybeJavaHome = path.dirname(path.dirname(javacPath));
if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
process.env['JAVA_HOME'] = maybeJavaHome;
} else {
throw new Error('Could not find JAVA_HOME. Try setting the environment variable manually');
}
}
} else if (isWindows) {
// Try to auto-detect java in the default install paths.
var oldSilent = shelljs.config.silent;
shelljs.config.silent = true;
var firstJdkDir =
shelljs.ls(process.env['ProgramFiles'] + '\\java\\jdk*')[0] ||
shelljs.ls('C:\\Program Files\\java\\jdk*')[0] ||
shelljs.ls('C:\\Program Files (x86)\\java\\jdk*')[0];
shelljs.config.silent = oldSilent;
if (firstJdkDir) {
// shelljs always uses / in paths.
firstJdkDir = firstJdkDir.replace(/\//g, path.sep);
if (!javacPath) {
process.env['PATH'] += path.delimiter + path.join(firstJdkDir, 'bin');
}
process.env['JAVA_HOME'] = firstJdkDir;
}
}
}
}).then(function() {
var msg =
'Failed to run "java -version", make sure that you have a JDK installed.\n' +
'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
if (process.env['JAVA_HOME']) {
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
}
return tryCommand('java -version', msg)
.then(function() {
return tryCommand('javac -version', msg);
});
});
}
// Returns a promise.
module.exports.check_android = function() {
return Q().then(function() {
var androidCmdPath = forgivingWhichSync('android');
var adbInPath = !!forgivingWhichSync('adb');
var hasAndroidHome = !!process.env['ANDROID_HOME'] && fs.existsSync(process.env['ANDROID_HOME']);
function maybeSetAndroidHome(value) {
if (!hasAndroidHome && fs.existsSync(value)) {
hasAndroidHome = true;
process.env['ANDROID_HOME'] = value;
}
}
if (!hasAndroidHome && !androidCmdPath) {
if (isWindows) {
// Android Studio installer.
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-studio', 'sdk'));
maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-studio', 'sdk'));
// Stand-alone installer.
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-sdk'));
maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-sdk'));
} else if (process.platform == 'darwin') {
maybeSetAndroidHome('/Applications/Android Studio.app/sdk');
// Stand-alone zip file that user might think to put under /Applications
maybeSetAndroidHome('/Applications/android-sdk-macosx');
maybeSetAndroidHome('/Applications/android-sdk');
}
if (process.env['HOME']) {
// or their HOME directory.
maybeSetAndroidHome(path.join(process.env['HOME'], 'android-sdk-macosx'));
maybeSetAndroidHome(path.join(process.env['HOME'], 'android-sdk'));
}
}
if (hasAndroidHome && !androidCmdPath) {
process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'tools');
}
if (androidCmdPath && !hasAndroidHome) {
var parentDir = path.dirname(androidCmdPath);
if (path.basename(parentDir) == 'tools') {
process.env['ANDROID_HOME'] = path.dirname(parentDir);
hasAndroidHome = true;
}
}
if (hasAndroidHome && !adbInPath) {
process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'platform-tools');
}
if (!process.env['ANDROID_HOME']) {
throw new Error('ANDROID_HOME is not set and "android" command not in your PATH. You must fulfill at least one of these conditions.');
}
if (!fs.existsSync(process.env['ANDROID_HOME'])) {
throw new Error('ANDROID_HOME is set to a non-existant path: ' + process.env['ANDROID_HOME']);
}
// Check that the target sdk level is installed.
return module.exports.check_android_target(module.exports.get_target());
});
};
module.exports.getAbsoluteAndroidCmd = function() {
return forgivingWhichSync('android').replace(/(\s)/g, '\\$1');
};
module.exports.check_android_target = function(valid_target) {
// valid_target can look like:
// android-19
// android-L
// Google Inc.:Google APIs:20
// Google Inc.:Glass Development Kit Preview:20
var msg = 'Android SDK not found. Make sure that it is installed. If it is not at the default location, set the ANDROID_HOME environment variable.';
return tryCommand('android list targets --compact', msg)
.then(function(output) {
if (output.split('\n').indexOf(valid_target) == -1) {
var androidCmd = module.exports.getAbsoluteAndroidCmd();
throw new Error('Please install Android target: "' + valid_target + '".\n\n' +
'Hint: Open the SDK manager by running: ' + androidCmd + '\n' +
'You will require:\n' +
'1. "SDK Platform" for ' + valid_target + '\n' +
'2. "Android SDK Platform-tools (latest)\n' +
'3. "Android SDK Build-tools" (latest)');
}
});
};
// Returns a promise.
module.exports.run = function() {
return Q.all([this.check_java(), this.check_android()]);
}

321
bin/lib/create.js Executable file
View File

@ -0,0 +1,321 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var shell = require('shelljs'),
child_process = require('child_process'),
Q = require('q'),
path = require('path'),
fs = require('fs'),
check_reqs = require('./check_reqs'),
ROOT = path.join(__dirname, '..', '..');
// Returns a promise.
function exec(command, opt_cwd) {
var d = Q.defer();
console.log('Running: ' + command);
child_process.exec(command, { cwd: opt_cwd }, function(err, stdout, stderr) {
stdout && console.log(stdout);
stderr && console.error(stderr);
if (err) d.reject(err);
else d.resolve(stdout);
});
return d.promise;
}
function setShellFatal(value, func) {
var oldVal = shell.config.fatal;
shell.config.fatal = value;
func();
shell.config.fatal = oldVal;
}
function getFrameworkDir(projectPath, shared) {
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
}
function copyJsAndLibrary(projectPath, shared, projectName) {
var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
shell.cp('-f', path.join(ROOT, 'framework', 'assets', 'www', 'cordova.js'), path.join(projectPath, 'assets', 'www', 'cordova.js'));
// Don't fail if there are no old jars.
setShellFatal(false, function() {
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function(oldJar) {
console.log("Deleting " + oldJar);
shell.rm('-f', oldJar);
});
// Delete old library project if it existed.
if (shared) {
shell.rm('-rf', nestedCordovaLibPath);
} else {
// Delete only the src, since eclipse can't handle its .project file being deleted.
shell.rm('-rf', path.join(nestedCordovaLibPath, 'src'));
}
});
if (!shared) {
shell.mkdir('-p', nestedCordovaLibPath);
shell.cp('-f', path.join(ROOT, 'framework', 'AndroidManifest.xml'), nestedCordovaLibPath);
shell.cp('-f', path.join(ROOT, 'framework', 'project.properties'), nestedCordovaLibPath);
shell.cp('-f', path.join(ROOT, 'framework', 'build.gradle'), nestedCordovaLibPath);
shell.cp('-r', path.join(ROOT, 'framework', 'src'), nestedCordovaLibPath);
// Create an eclipse project file and set the name of it to something unique.
// Without this, you can't import multiple CordovaLib projects into the same workspace.
var eclipseProjectFilePath = path.join(nestedCordovaLibPath, '.project');
if (!fs.existsSync(eclipseProjectFilePath)) {
var data = '<?xml version="1.0" encoding="UTF-8"?><projectDescription><name>' + projectName + '-' + 'CordovaLib</name></projectDescription>';
fs.writeFileSync(eclipseProjectFilePath, data, 'utf8');
}
}
}
function extractSubProjectPaths(data) {
var ret = {};
var r = /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg
var m;
while (m = r.exec(data)) {
ret[m[1]] = 1;
}
return Object.keys(ret);
}
function writeProjectProperties(projectPath, target_api, shared) {
var dstPath = path.join(projectPath, 'project.properties');
var templatePath = path.join(ROOT, 'bin', 'templates', 'project', 'project.properties');
var srcPath = fs.existsSync(dstPath) ? dstPath : templatePath;
var data = fs.readFileSync(srcPath, 'utf8');
data = data.replace(/^target=.*/m, 'target=' + target_api);
var subProjects = extractSubProjectPaths(data);
subProjects = subProjects.filter(function(p) {
return !(/^CordovaLib$/m.exec(p) ||
/[\\\/]cordova-android[\\\/]framework$/m.exec(p) ||
/^(\.\.[\\\/])+framework$/m.exec(p)
);
});
subProjects.unshift(shared ? path.relative(projectPath, path.join(ROOT, 'framework')) : 'CordovaLib');
data = data.replace(/^\s*android\.library\.reference\.\d+=.*\n/mg, '');
if (!/\n$/.exec(data)) {
data += '\n';
}
for (var i = 0; i < subProjects.length; ++i) {
data += 'android.library.reference.' + (i+1) + '=' + subProjects[i] + '\n';
}
fs.writeFileSync(dstPath, data);
}
function copyBuildRules(projectPath) {
var srcDir = path.join(ROOT, 'bin', 'templates', 'project');
shell.cp('-f', path.join(srcDir, 'build.gradle'), projectPath);
shell.cp('-f', path.join(srcDir, 'settings.gradle'), projectPath);
shell.cp('-f', path.join(srcDir, 'cordova.gradle'), projectPath);
}
function copyScripts(projectPath) {
var srcScriptsDir = path.join(ROOT, 'bin', 'templates', 'cordova');
var destScriptsDir = path.join(projectPath, 'cordova');
// Delete old scripts directory if this is an update.
shell.rm('-rf', destScriptsDir);
// Copy in the new ones.
shell.cp('-r', srcScriptsDir, projectPath);
shell.cp('-r', path.join(ROOT, 'bin', 'node_modules'), destScriptsDir);
shell.cp(path.join(ROOT, 'bin', 'check_reqs'), path.join(destScriptsDir, 'check_reqs'));
shell.cp(path.join(ROOT, 'bin', 'lib', 'check_reqs.js'), path.join(projectPath, 'cordova', 'lib', 'check_reqs.js'));
shell.cp(path.join(ROOT, 'bin', 'android_sdk_version'), path.join(destScriptsDir, 'android_sdk_version'));
shell.cp(path.join(ROOT, 'bin', 'lib', 'android_sdk_version.js'), path.join(projectPath, 'cordova', 'lib', 'android_sdk_version.js'));
}
/**
* Test whether a package name is acceptable for use as an android project.
* Returns a promise, fulfilled if the package name is acceptable; rejected
* otherwise.
*/
function validatePackageName(package_name) {
//Make the package conform to Java package types
//Enforce underscore limitation
if (!/^[a-zA-Z]+(\.[a-zA-Z0-9][a-zA-Z0-9_]*)+$/.test(package_name)) {
return Q.reject('Package name must look like: com.company.Name');
}
//Class is a reserved word
if(/\b[Cc]lass\b/.test(package_name)) {
return Q.reject('class is a reserved word');
}
return Q.resolve();
}
/**
* Test whether a project name is acceptable for use as an android class.
* Returns a promise, fulfilled if the project name is acceptable; rejected
* otherwise.
*/
function validateProjectName(project_name) {
//Make sure there's something there
if (project_name === '') {
return Q.reject('Project name cannot be empty');
}
//Enforce stupid name error
if (project_name === 'CordovaActivity') {
return Q.reject('Project name cannot be CordovaActivity');
}
//Classes in Java don't begin with numbers
if (/^[0-9]/.test(project_name)) {
return Q.reject('Project name must not begin with a number');
}
return Q.resolve();
}
/**
* $ create [options]
*
* Creates an android application with the given options.
*
* Options:
*
* - `project_path` {String} Path to the new Cordova android project.
* - `package_name`{String} Package name, following reverse-domain style convention.
* - `project_name` {String} Project name.
* - 'project_template_dir' {String} Path to project template (override).
*
* Returns a promise.
*/
exports.createProject = function(project_path, package_name, project_name, project_template_dir, use_shared_project, use_cli_template) {
var VERSION = fs.readFileSync(path.join(ROOT, 'VERSION'), 'utf-8').trim();
// Set default values for path, package and name
project_path = typeof project_path !== 'undefined' ? project_path : "CordovaExample";
project_path = path.relative(process.cwd(), project_path);
package_name = typeof package_name !== 'undefined' ? package_name : 'my.cordova.project';
project_name = typeof project_name !== 'undefined' ? project_name : 'CordovaExample';
project_template_dir = typeof project_template_dir !== 'undefined' ?
project_template_dir :
path.join(ROOT, 'bin', 'templates', 'project');
var safe_activity_name = project_name.replace(/\W/g, '');
var package_as_path = package_name.replace(/\./g, path.sep);
var activity_dir = path.join(project_path, 'src', package_as_path);
var activity_path = path.join(activity_dir, safe_activity_name + '.java');
var target_api = check_reqs.get_target();
var manifest_path = path.join(project_path, 'AndroidManifest.xml');
// Check if project already exists
if(fs.existsSync(project_path)) {
return Q.reject('Project already exists! Delete and recreate');
}
//Make the package conform to Java package types
return validatePackageName(package_name)
.then(function() {
validateProjectName(project_name);
}).then(function() {
// Log the given values for the project
console.log('Creating Cordova project for the Android platform:');
console.log('\tPath: ' + project_path);
console.log('\tPackage: ' + package_name);
console.log('\tName: ' + project_name);
console.log('\tAndroid target: ' + target_api);
console.log('Copying template files...');
setShellFatal(true, function() {
// copy project template
shell.cp('-r', path.join(project_template_dir, 'assets'), project_path);
shell.cp('-r', path.join(project_template_dir, 'res'), project_path);
shell.cp('-r', path.join(ROOT, 'framework', 'res', 'xml'), path.join(project_path, 'res'));
shell.cp(path.join(project_template_dir, 'gitignore'), path.join(project_path, '.gitignore'));
// Manually create directories that would be empty within the template (since git doesn't track directories).
shell.mkdir(path.join(project_path, 'libs'));
// Add in the proper eclipse project file.
if (use_cli_template) {
var note = 'To show `assets/www` or `res/xml/config.xml`, go to:\n' +
' Project -> Properties -> Resource -> Resource Filters\n' +
'And delete the exclusion filter.\n';
shell.cp(path.join(project_template_dir, 'eclipse-project-CLI'), path.join(project_path, '.project'));
fs.writeFileSync(path.join(project_path, 'assets', '_where-is-www.txt'), note);
} else {
shell.cp(path.join(project_template_dir, 'eclipse-project'), path.join(project_path, '.project'));
}
// copy cordova.js, cordova.jar
copyJsAndLibrary(project_path, use_shared_project, safe_activity_name);
// interpolate the activity name and package
shell.mkdir('-p', activity_dir);
shell.cp('-f', path.join(project_template_dir, 'Activity.java'), activity_path);
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, activity_path);
shell.sed('-i', /__NAME__/, project_name, path.join(project_path, 'res', 'values', 'strings.xml'));
shell.sed('-i', /__NAME__/, project_name, path.join(project_path, '.project'));
shell.sed('-i', /__ID__/, package_name, activity_path);
shell.cp('-f', path.join(project_template_dir, 'AndroidManifest.xml'), manifest_path);
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, manifest_path);
shell.sed('-i', /__PACKAGE__/, package_name, manifest_path);
shell.sed('-i', /__APILEVEL__/, target_api.split('-')[1], manifest_path);
copyScripts(project_path);
copyBuildRules(project_path);
});
// Link it to local android install.
writeProjectProperties(project_path, target_api);
}).then(function() {
console.log('Project successfully created.');
});
}
// Attribute removed in Cordova 4.4 (CB-5447).
function removeDebuggableFromManifest(projectPath) {
var manifestPath = path.join(projectPath, 'AndroidManifest.xml');
shell.sed('-i', /\s*android:debuggable="true"/, '', manifestPath);
}
function extractProjectNameFromManifest(projectPath) {
var manifestPath = path.join(projectPath, 'AndroidManifest.xml');
var manifestData = fs.readFileSync(manifestPath, 'utf8');
var m = /<activity[\s\S]*?android:name\s*=\s*"(.*?)"/i.exec(manifestData);
if (!m) {
throw new Error('Could not find activity name in ' + manifestPath);
}
return m[1];
}
// Returns a promise.
exports.updateProject = function(projectPath, shared) {
var newVersion = fs.readFileSync(path.join(ROOT, 'VERSION'), 'utf-8').trim();
return Q()
.then(function() {
var projectName = extractProjectNameFromManifest(projectPath);
var target_api = check_reqs.get_target();
copyJsAndLibrary(projectPath, shared, projectName);
copyScripts(projectPath);
copyBuildRules(projectPath);
removeDebuggableFromManifest(projectPath);
writeProjectProperties(projectPath, target_api, shared);
console.log('Android project is now at version ' + newVersion);
console.log('If you updated from a pre-3.2.0 version and use an IDE, we now require that you import the "CordovaLib" library project.');
});
};
// For testing
exports.validatePackageName = validatePackageName;
exports.validateProjectName = validateProjectName;

View File

@ -17,11 +17,16 @@
under the License.
*/
var deviceInfo = function() {
document.getElementById("deviceready").innerHTML = "fired";
document.getElementById("cordova").innerHTML = cordova.version;
};
function init() {
document.addEventListener("deviceready", deviceInfo, true);
exports.getArgs = function(argv) {
var ret = {};
var posArgs = [];
for (var i = 2, arg; arg = argv[i] || i < argv.length; ++i) {
if (/^--/.exec(arg)) {
ret[arg] = true;
} else {
posArgs.push(arg);
}
}
ret._ = posArgs;
return ret;
};

1
bin/node_modules/.bin/shjs generated vendored Symbolic link
View File

@ -0,0 +1 @@
../shelljs/bin/shjs

40
bin/node_modules/q/CONTRIBUTING.md generated vendored Normal file
View File

@ -0,0 +1,40 @@
For pull requests:
- Be consistent with prevalent style and design decisions.
- Add a Jasmine spec to `specs/q-spec.js`.
- Use `npm test` to avoid regressions.
- Run tests in `q-spec/run.html` in as many supported browsers as you
can find the will to deal with.
- Do not build minified versions; we do this each release.
- If you would be so kind, add a note to `CHANGES.md` in an
appropriate section:
- `Next Major Version` if it introduces backward incompatibilities
to code in the wild using documented features.
- `Next Minor Version` if it adds a new feature.
- `Next Patch Version` if it fixes a bug.
For releases:
- Run `npm test`.
- Run tests in `q-spec/run.html` in a representative sample of every
browser under the sun.
- Run `npm run cover` and make sure you're happy with the results.
- Run `npm run minify` and be sure to commit the resulting `q.min.js`.
- Note the Gzipped size output by the previous command, and update
`README.md` if it has changed to 1 significant digit.
- Stash any local changes.
- Update `CHANGES.md` to reflect all changes in the differences
between `HEAD` and the previous tagged version. Give credit where
credit is due.
- Update `README.md` to address all new, non-experimental features.
- Update the API reference on the Wiki to reflect all non-experimental
features.
- Use `npm version major|minor|patch` to update `package.json`,
commit, and tag the new version.
- Use `npm publish` to send up a new release.
- Send an email to the q-continuum mailing list announcing the new
release and the notes from the change log. This helps folks
maintaining other package ecosystems.

19
bin/node_modules/q/LICENSE generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright 20092012 Kristopher Michael Kowal. All rights reserved.
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.

813
bin/node_modules/q/README.md generated vendored Normal file
View File

@ -0,0 +1,813 @@
[![Build Status](https://secure.travis-ci.org/kriskowal/q.png?branch=master)](http://travis-ci.org/kriskowal/q)
<a href="http://promises-aplus.github.com/promises-spec">
<img src="http://promises-aplus.github.com/promises-spec/assets/logo-small.png"
align="right" alt="Promises/A+ logo" />
</a>
If a function cannot return a value or throw an exception without
blocking, it can return a promise instead. A promise is an object
that represents the return value or the thrown exception that the
function may eventually provide. A promise can also be used as a
proxy for a [remote object][Q-Connection] to overcome latency.
[Q-Connection]: https://github.com/kriskowal/q-connection
On the first pass, promises can mitigate the “[Pyramid of
Doom][POD]”: the situation where code marches to the right faster
than it marches forward.
[POD]: http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/
```javascript
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// Do something with value4
});
});
});
});
```
With a promise library, you can flatten the pyramid.
```javascript
Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then(function (value4) {
// Do something with value4
})
.catch(function (error) {
// Handle any error from all above steps
})
.done();
```
With this approach, you also get implicit error propagation, just like `try`,
`catch`, and `finally`. An error in `promisedStep1` will flow all the way to
the `catch` function, where its caught and handled. (Here `promisedStepN` is
a version of `stepN` that returns a promise.)
The callback approach is called an “inversion of control”.
A function that accepts a callback instead of a return value
is saying, “Dont call me, Ill call you.”. Promises
[un-invert][IOC] the inversion, cleanly separating the input
arguments from control flow arguments. This simplifies the
use and creation of APIs, particularly variadic,
rest and spread arguments.
[IOC]: http://www.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript
## Getting Started
The Q module can be loaded as:
- A ``<script>`` tag (creating a ``Q`` global variable): ~2.5 KB minified and
gzipped.
- A Node.js and CommonJS module, available in [npm](https://npmjs.org/) as
the [q](https://npmjs.org/package/q) package
- An AMD module
- A [component](https://github.com/component/component) as ``microjs/q``
- Using [bower](http://bower.io/) as ``q``
- Using [NuGet](http://nuget.org/) as [Q](https://nuget.org/packages/q)
Q can exchange promises with jQuery, Dojo, When.js, WinJS, and more.
## Resources
Our [wiki][] contains a number of useful resources, including:
- A method-by-method [Q API reference][reference].
- A growing [examples gallery][examples], showing how Q can be used to make
everything better. From XHR to database access to accessing the Flickr API,
Q is there for you.
- There are many libraries that produce and consume Q promises for everything
from file system/database access or RPC to templating. For a list of some of
the more popular ones, see [Libraries][].
- If you want materials that introduce the promise concept generally, and the
below tutorial isn't doing it for you, check out our collection of
[presentations, blog posts, and podcasts][resources].
- A guide for those [coming from jQuery's `$.Deferred`][jquery].
We'd also love to have you join the Q-Continuum [mailing list][].
[wiki]: https://github.com/kriskowal/q/wiki
[reference]: https://github.com/kriskowal/q/wiki/API-Reference
[examples]: https://github.com/kriskowal/q/wiki/Examples-Gallery
[Libraries]: https://github.com/kriskowal/q/wiki/Libraries
[resources]: https://github.com/kriskowal/q/wiki/General-Promise-Resources
[jquery]: https://github.com/kriskowal/q/wiki/Coming-from-jQuery
[mailing list]: https://groups.google.com/forum/#!forum/q-continuum
## Tutorial
Promises have a ``then`` method, which you can use to get the eventual
return value (fulfillment) or thrown exception (rejection).
```javascript
promiseMeSomething()
.then(function (value) {
}, function (reason) {
});
```
If ``promiseMeSomething`` returns a promise that gets fulfilled later
with a return value, the first function (the fulfillment handler) will be
called with the value. However, if the ``promiseMeSomething`` function
gets rejected later by a thrown exception, the second function (the
rejection handler) will be called with the exception.
Note that resolution of a promise is always asynchronous: that is, the
fulfillment or rejection handler will always be called in the next turn of the
event loop (i.e. `process.nextTick` in Node). This gives you a nice
guarantee when mentally tracing the flow of your code, namely that
``then`` will always return before either handler is executed.
In this tutorial, we begin with how to consume and work with promises. We'll
talk about how to create them, and thus create functions like
`promiseMeSomething` that return promises, [below](#the-beginning).
### Propagation
The ``then`` method returns a promise, which in this example, Im
assigning to ``outputPromise``.
```javascript
var outputPromise = getInputPromise()
.then(function (input) {
}, function (reason) {
});
```
The ``outputPromise`` variable becomes a new promise for the return
value of either handler. Since a function can only either return a
value or throw an exception, only one handler will ever be called and it
will be responsible for resolving ``outputPromise``.
- If you return a value in a handler, ``outputPromise`` will get
fulfilled.
- If you throw an exception in a handler, ``outputPromise`` will get
rejected.
- If you return a **promise** in a handler, ``outputPromise`` will
“become” that promise. Being able to become a new promise is useful
for managing delays, combining results, or recovering from errors.
If the ``getInputPromise()`` promise gets rejected and you omit the
rejection handler, the **error** will go to ``outputPromise``:
```javascript
var outputPromise = getInputPromise()
.then(function (value) {
});
```
If the input promise gets fulfilled and you omit the fulfillment handler, the
**value** will go to ``outputPromise``:
```javascript
var outputPromise = getInputPromise()
.then(null, function (error) {
});
```
Q promises provide a ``fail`` shorthand for ``then`` when you are only
interested in handling the error:
```javascript
var outputPromise = getInputPromise()
.fail(function (error) {
});
```
If you are writing JavaScript for modern engines only or using
CoffeeScript, you may use `catch` instead of `fail`.
Promises also have a ``fin`` function that is like a ``finally`` clause.
The final handler gets called, with no arguments, when the promise
returned by ``getInputPromise()`` either returns a value or throws an
error. The value returned or error thrown by ``getInputPromise()``
passes directly to ``outputPromise`` unless the final handler fails, and
may be delayed if the final handler returns a promise.
```javascript
var outputPromise = getInputPromise()
.fin(function () {
// close files, database connections, stop servers, conclude tests
});
```
- If the handler returns a value, the value is ignored
- If the handler throws an error, the error passes to ``outputPromise``
- If the handler returns a promise, ``outputPromise`` gets postponed. The
eventual value or error has the same effect as an immediate return
value or thrown error: a value would be ignored, an error would be
forwarded.
If you are writing JavaScript for modern engines only or using
CoffeeScript, you may use `finally` instead of `fin`.
### Chaining
There are two ways to chain promises. You can chain promises either
inside or outside handlers. The next two examples are equivalent.
```javascript
return getUsername()
.then(function (username) {
return getUser(username)
.then(function (user) {
// if we get here without an error,
// the value returned here
// or the exception thrown here
// resolves the promise returned
// by the first line
})
});
```
```javascript
return getUsername()
.then(function (username) {
return getUser(username);
})
.then(function (user) {
// if we get here without an error,
// the value returned here
// or the exception thrown here
// resolves the promise returned
// by the first line
});
```
The only difference is nesting. Its useful to nest handlers if you
need to capture multiple input values in your closure.
```javascript
function authenticate() {
return getUsername()
.then(function (username) {
return getUser(username);
})
// chained because we will not need the user name in the next event
.then(function (user) {
return getPassword()
// nested because we need both user and password next
.then(function (password) {
if (user.passwordHash !== hash(password)) {
throw new Error("Can't authenticate");
}
});
});
}
```
### Combination
You can turn an array of promises into a promise for the whole,
fulfilled array using ``all``.
```javascript
return Q.all([
eventualAdd(2, 2),
eventualAdd(10, 20)
]);
```
If you have a promise for an array, you can use ``spread`` as a
replacement for ``then``. The ``spread`` function “spreads” the
values over the arguments of the fulfillment handler. The rejection handler
will get called at the first sign of failure. That is, whichever of
the recived promises fails first gets handled by the rejection handler.
```javascript
function eventualAdd(a, b) {
return Q.spread([a, b], function (a, b) {
return a + b;
})
}
```
But ``spread`` calls ``all`` initially, so you can skip it in chains.
```javascript
return getUsername()
.then(function (username) {
return [username, getUser(username)];
})
.spread(function (username, user) {
});
```
The ``all`` function returns a promise for an array of values. When this
promise is fulfilled, the array contains the fulfillment values of the original
promises, in the same order as those promises. If one of the given promises
is rejected, the returned promise is immediately rejected, not waiting for the
rest of the batch. If you want to wait for all of the promises to either be
fulfilled or rejected, you can use ``allSettled``.
```javascript
Q.allSettled(promises)
.then(function (results) {
results.forEach(function (result) {
if (result.state === "fulfilled") {
var value = result.value;
} else {
var reason = result.reason;
}
});
});
```
### Sequences
If you have a number of promise-producing functions that need
to be run sequentially, you can of course do so manually:
```javascript
return foo(initialVal).then(bar).then(baz).then(qux);
```
However, if you want to run a dynamically constructed sequence of
functions, you'll want something like this:
```javascript
var funcs = [foo, bar, baz, qux];
var result = Q(initialVal);
funcs.forEach(function (f) {
result = result.then(f);
});
return result;
```
You can make this slightly more compact using `reduce`:
```javascript
return funcs.reduce(function (soFar, f) {
return soFar.then(f);
}, Q(initialVal));
```
Or, you could use th ultra-compact version:
```javascript
return funcs.reduce(Q.when, Q());
```
### Handling Errors
One sometimes-unintuive aspect of promises is that if you throw an
exception in the fulfillment handler, it will not be be caught by the error
handler.
```javascript
return foo()
.then(function (value) {
throw new Error("Can't bar.");
}, function (error) {
// We only get here if "foo" fails
});
```
To see why this is, consider the parallel between promises and
``try``/``catch``. We are ``try``-ing to execute ``foo()``: the error
handler represents a ``catch`` for ``foo()``, while the fulfillment handler
represents code that happens *after* the ``try``/``catch`` block.
That code then needs its own ``try``/``catch`` block.
In terms of promises, this means chaining your rejection handler:
```javascript
return foo()
.then(function (value) {
throw new Error("Can't bar.");
})
.fail(function (error) {
// We get here with either foo's error or bar's error
});
```
### Progress Notification
It's possible for promises to report their progress, e.g. for tasks that take a
long time like a file upload. Not all promises will implement progress
notifications, but for those that do, you can consume the progress values using
a third parameter to ``then``:
```javascript
return uploadFile()
.then(function () {
// Success uploading the file
}, function (err) {
// There was an error, and we get the reason for error
}, function (progress) {
// We get notified of the upload's progress as it is executed
});
```
Like `fail`, Q also provides a shorthand for progress callbacks
called `progress`:
```javascript
return uploadFile().progress(function (progress) {
// We get notified of the upload's progress
});
```
### The End
When you get to the end of a chain of promises, you should either
return the last promise or end the chain. Since handlers catch
errors, its an unfortunate pattern that the exceptions can go
unobserved.
So, either return it,
```javascript
return foo()
.then(function () {
return "bar";
});
```
Or, end it.
```javascript
foo()
.then(function () {
return "bar";
})
.done();
```
Ending a promise chain makes sure that, if an error doesnt get
handled before the end, it will get rethrown and reported.
This is a stopgap. We are exploring ways to make unhandled errors
visible without any explicit handling.
### The Beginning
Everything above assumes you get a promise from somewhere else. This
is the common case. Every once in a while, you will need to create a
promise from scratch.
#### Using ``Q.fcall``
You can create a promise from a value using ``Q.fcall``. This returns a
promise for 10.
```javascript
return Q.fcall(function () {
return 10;
});
```
You can also use ``fcall`` to get a promise for an exception.
```javascript
return Q.fcall(function () {
throw new Error("Can't do it");
});
```
As the name implies, ``fcall`` can call functions, or even promised
functions. This uses the ``eventualAdd`` function above to add two
numbers.
```javascript
return Q.fcall(eventualAdd, 2, 2);
```
#### Using Deferreds
If you have to interface with asynchronous functions that are callback-based
instead of promise-based, Q provides a few shortcuts (like ``Q.nfcall`` and
friends). But much of the time, the solution will be to use *deferreds*.
```javascript
var deferred = Q.defer();
FS.readFile("foo.txt", "utf-8", function (error, text) {
if (error) {
deferred.reject(new Error(error));
} else {
deferred.resolve(text);
}
});
return deferred.promise;
```
Note that a deferred can be resolved with a value or a promise. The
``reject`` function is a shorthand for resolving with a rejected
promise.
```javascript
// this:
deferred.reject(new Error("Can't do it"));
// is shorthand for:
var rejection = Q.fcall(function () {
throw new Error("Can't do it");
});
deferred.resolve(rejection);
```
This is a simplified implementation of ``Q.delay``.
```javascript
function delay(ms) {
var deferred = Q.defer();
setTimeout(deferred.resolve, ms);
return deferred.promise;
}
```
This is a simplified implementation of ``Q.timeout``
```javascript
function timeout(promise, ms) {
var deferred = Q.defer();
Q.when(promise, deferred.resolve);
delay(ms).then(function () {
deferred.reject(new Error("Timed out"));
});
return deferred.promise;
}
```
Finally, you can send a progress notification to the promise with
``deferred.notify``.
For illustration, this is a wrapper for XML HTTP requests in the browser. Note
that a more [thorough][XHR] implementation would be in order in practice.
[XHR]: https://github.com/montagejs/mr/blob/71e8df99bb4f0584985accd6f2801ef3015b9763/browser.js#L29-L73
```javascript
function requestOkText(url) {
var request = new XMLHttpRequest();
var deferred = Q.defer();
request.open("GET", url, true);
request.onload = onload;
request.onerror = onerror;
request.onprogress = onprogress;
request.send();
function onload() {
if (request.status === 200) {
deferred.resolve(request.responseText);
} else {
deferred.reject(new Error("Status code was " + request.status));
}
}
function onerror() {
deferred.reject(new Error("Can't XHR " + JSON.stringify(url)));
}
function onprogress(event) {
deferred.notify(event.loaded / event.total);
}
return deferred.promise;
}
```
Below is an example of how to use this ``requestOkText`` function:
```javascript
requestOkText("http://localhost:3000")
.then(function (responseText) {
// If the HTTP response returns 200 OK, log the response text.
console.log(responseText);
}, function (error) {
// If there's an error or a non-200 status code, log the error.
console.error(error);
}, function (progress) {
// Log the progress as it comes in.
console.log("Request progress: " + Math.round(progress * 100) + "%");
});
```
### The Middle
If you are using a function that may return a promise, but just might
return a value if it doesnt need to defer, you can use the “static”
methods of the Q library.
The ``when`` function is the static equivalent for ``then``.
```javascript
return Q.when(valueOrPromise, function (value) {
}, function (error) {
});
```
All of the other methods on a promise have static analogs with the
same name.
The following are equivalent:
```javascript
return Q.all([a, b]);
```
```javascript
return Q.fcall(function () {
return [a, b];
})
.all();
```
When working with promises provided by other libraries, you should
convert it to a Q promise. Not all promise libraries make the same
guarantees as Q and certainly dont provide all of the same methods.
Most libraries only provide a partially functional ``then`` method.
This thankfully is all we need to turn them into vibrant Q promises.
```javascript
return Q($.ajax(...))
.then(function () {
});
```
If there is any chance that the promise you receive is not a Q promise
as provided by your library, you should wrap it using a Q function.
You can even use ``Q.invoke`` as a shorthand.
```javascript
return Q.invoke($, 'ajax', ...)
.then(function () {
});
```
### Over the Wire
A promise can serve as a proxy for another object, even a remote
object. There are methods that allow you to optimistically manipulate
properties or call functions. All of these interactions return
promises, so they can be chained.
```
direct manipulation using a promise as a proxy
-------------------------- -------------------------------
value.foo promise.get("foo")
value.foo = value promise.put("foo", value)
delete value.foo promise.del("foo")
value.foo(...args) promise.post("foo", [args])
value.foo(...args) promise.invoke("foo", ...args)
value(...args) promise.fapply([args])
value(...args) promise.fcall(...args)
```
If the promise is a proxy for a remote object, you can shave
round-trips by using these functions instead of ``then``. To take
advantage of promises for remote objects, check out [Q-Connection][].
[Q-Connection]: https://github.com/kriskowal/q-connection
Even in the case of non-remote objects, these methods can be used as
shorthand for particularly-simple fulfillment handlers. For example, you
can replace
```javascript
return Q.fcall(function () {
return [{ foo: "bar" }, { foo: "baz" }];
})
.then(function (value) {
return value[0].foo;
});
```
with
```javascript
return Q.fcall(function () {
return [{ foo: "bar" }, { foo: "baz" }];
})
.get(0)
.get("foo");
```
### Adapting Node
If you're working with functions that make use of the Node.js callback pattern,
where callbacks are in the form of `function(err, result)`, Q provides a few
useful utility functions for converting between them. The most straightforward
are probably `Q.nfcall` and `Q.nfapply` ("Node function call/apply") for calling
Node.js-style functions and getting back a promise:
```javascript
return Q.nfcall(FS.readFile, "foo.txt", "utf-8");
return Q.nfapply(FS.readFile, ["foo.txt", "utf-8"]);
```
If you are working with methods, instead of simple functions, you can easily
run in to the usual problems where passing a method to another function—like
`Q.nfcall`—"un-binds" the method from its owner. To avoid this, you can either
use `Function.prototype.bind` or some nice shortcut methods we provide:
```javascript
return Q.ninvoke(redisClient, "get", "user:1:id");
return Q.npost(redisClient, "get", ["user:1:id"]);
```
You can also create reusable wrappers with `Q.denodeify` or `Q.nbind`:
```javascript
var readFile = Q.denodeify(FS.readFile);
return readFile("foo.txt", "utf-8");
var redisClientGet = Q.nbind(redisClient.get, redisClient);
return redisClientGet("user:1:id");
```
Finally, if you're working with raw deferred objects, there is a
`makeNodeResolver` method on deferreds that can be handy:
```javascript
var deferred = Q.defer();
FS.readFile("foo.txt", "utf-8", deferred.makeNodeResolver());
return deferred.promise;
```
### Long Stack Traces
Q comes with optional support for “long stack traces,” wherein the `stack`
property of `Error` rejection reasons is rewritten to be traced along
asynchronous jumps instead of stopping at the most recent one. As an example:
```js
function theDepthsOfMyProgram() {
Q.delay(100).done(function explode() {
throw new Error("boo!");
});
}
theDepthsOfMyProgram();
```
usually would give a rather unhelpful stack trace looking something like
```
Error: boo!
at explode (/path/to/test.js:3:11)
at _fulfilled (/path/to/test.js:q:54)
at resolvedValue.promiseDispatch.done (/path/to/q.js:823:30)
at makePromise.promise.promiseDispatch (/path/to/q.js:496:13)
at pending (/path/to/q.js:397:39)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
```
But, if you turn this feature on by setting
```js
Q.longStackSupport = true;
```
then the above code gives a nice stack trace to the tune of
```
Error: boo!
at explode (/path/to/test.js:3:11)
From previous event:
at theDepthsOfMyProgram (/path/to/test.js:2:16)
at Object.<anonymous> (/path/to/test.js:7:1)
```
Note how you can see the the function that triggered the async operation in the
stack trace! This is very helpful for debugging, as otherwise you end up getting
only the first line, plus a bunch of Q internals, with no sign of where the
operation started.
This feature does come with somewhat-serious performance and memory overhead,
however. If you're working with lots of promises, or trying to scale a server
to many users, you should probably keep it off. But in development, go for it!
## Tests
You can view the results of the Q test suite [in your browser][tests]!
[tests]: https://rawgithub.com/kriskowal/q/master/spec/q-spec.html
## License
Copyright 20092013 Kristopher Michael Kowal
MIT License (enclosed)

71
bin/node_modules/q/benchmark/compare-with-callbacks.js generated vendored Normal file
View File

@ -0,0 +1,71 @@
"use strict";
var Q = require("../q");
var fs = require("fs");
suite("A single simple async operation", function () {
bench("with an immediately-fulfilled promise", function (done) {
Q().then(done);
});
bench("with direct setImmediate usage", function (done) {
setImmediate(done);
});
bench("with direct setTimeout(…, 0)", function (done) {
setTimeout(done, 0);
});
});
suite("A fs.readFile", function () {
var denodeified = Q.denodeify(fs.readFile);
set("iterations", 1000);
set("delay", 1000);
bench("directly, with callbacks", function (done) {
fs.readFile(__filename, done);
});
bench("with Q.nfcall", function (done) {
Q.nfcall(fs.readFile, __filename).then(done);
});
bench("with a Q.denodeify'ed version", function (done) {
denodeified(__filename).then(done);
});
bench("with manual usage of deferred.makeNodeResolver", function (done) {
var deferred = Q.defer();
fs.readFile(__filename, deferred.makeNodeResolver());
deferred.promise.then(done);
});
});
suite("1000 operations in parallel", function () {
function makeCounter(desiredCount, ultimateCallback) {
var soFar = 0;
return function () {
if (++soFar === desiredCount) {
ultimateCallback();
}
};
}
var numberOfOps = 1000;
bench("with immediately-fulfilled promises", function (done) {
var counter = makeCounter(numberOfOps, done);
for (var i = 0; i < numberOfOps; ++i) {
Q().then(counter);
}
});
bench("with direct setImmediate usage", function (done) {
var counter = makeCounter(numberOfOps, done);
for (var i = 0; i < numberOfOps; ++i) {
setImmediate(counter);
}
});
});

36
bin/node_modules/q/benchmark/scenarios.js generated vendored Normal file
View File

@ -0,0 +1,36 @@
"use strict";
var Q = require("../q");
suite("Chaining", function () {
var numberToChain = 1000;
bench("Chaining many already-fulfilled promises together", function (done) {
var currentPromise = Q();
for (var i = 0; i < numberToChain; ++i) {
currentPromise = currentPromise.then(function () {
return Q();
});
}
currentPromise.then(done);
});
bench("Chaining and then fulfilling the end of the chain", function (done) {
var deferred = Q.defer();
var currentPromise = deferred.promise;
for (var i = 0; i < numberToChain; ++i) {
(function () {
var promiseToReturn = currentPromise;
currentPromise = Q().then(function () {
return promiseToReturn;
});
}());
}
currentPromise.then(done);
deferred.resolve();
});
});

93
bin/node_modules/q/package.json generated vendored Normal file

File diff suppressed because one or more lines are too long

1937
bin/node_modules/q/q.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

35
bin/node_modules/q/queue.js generated vendored Normal file
View File

@ -0,0 +1,35 @@
var Q = require("./q");
module.exports = Queue;
function Queue() {
var ends = Q.defer();
var closed = Q.defer();
return {
put: function (value) {
var next = Q.defer();
ends.resolve({
head: value,
tail: next.promise
});
ends.resolve = next.resolve;
},
get: function () {
var result = ends.promise.get("head");
ends.promise = ends.promise.get("tail");
return result.fail(function (error) {
closed.resolve(error);
throw error;
});
},
closed: closed.promise,
close: function (error) {
error = error || new Error("Can't get value from closed queue");
var end = {head: Q.reject(error)};
end.tail = end;
ends.resolve(end);
return closed.promise;
}
};
}

6
bin/node_modules/shelljs/.documentup.json generated vendored Normal file
View File

@ -0,0 +1,6 @@
{
"name": "ShellJS",
"twitter": [
"r2r"
]
}

7
bin/node_modules/shelljs/.jshintrc generated vendored Normal file
View File

@ -0,0 +1,7 @@
{
"loopfunc": true,
"sub": true,
"undef": true,
"unused": true,
"node": true
}

2
bin/node_modules/shelljs/.npmignore generated vendored Normal file
View File

@ -0,0 +1,2 @@
test/
tmp/

5
bin/node_modules/shelljs/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,5 @@
language: node_js
node_js:
- "0.8"
- "0.10"
- "0.11"

26
bin/node_modules/shelljs/LICENSE generated vendored Normal file
View File

@ -0,0 +1,26 @@
Copyright (c) 2012, Artur Adib <aadib@mozilla.com>
All rights reserved.
You may use this project under the terms of the New BSD license as follows:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Artur Adib nor the
names of the contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

552
bin/node_modules/shelljs/README.md generated vendored Normal file
View File

@ -0,0 +1,552 @@
# ShellJS - Unix shell commands for Node.js [![Build Status](https://secure.travis-ci.org/arturadib/shelljs.png)](http://travis-ci.org/arturadib/shelljs)
ShellJS is a portable **(Windows/Linux/OS X)** implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script's dependency on Unix while still keeping its familiar and powerful commands. You can also install it globally so you can run it from outside Node projects - say goodbye to those gnarly Bash scripts!
The project is [unit-tested](http://travis-ci.org/arturadib/shelljs) and battled-tested in projects like:
+ [PDF.js](http://github.com/mozilla/pdf.js) - Firefox's next-gen PDF reader
+ [Firebug](http://getfirebug.com/) - Firefox's infamous debugger
+ [JSHint](http://jshint.com) - Most popular JavaScript linter
+ [Zepto](http://zeptojs.com) - jQuery-compatible JavaScript library for modern browsers
+ [Yeoman](http://yeoman.io/) - Web application stack and development tool
+ [Deployd.com](http://deployd.com) - Open source PaaS for quick API backend generation
and [many more](https://npmjs.org/browse/depended/shelljs).
## Installing
Via npm:
```bash
$ npm install [-g] shelljs
```
If the global option `-g` is specified, the binary `shjs` will be installed. This makes it possible to
run ShellJS scripts much like any shell script from the command line, i.e. without requiring a `node_modules` folder:
```bash
$ shjs my_script
```
You can also just copy `shell.js` into your project's directory, and `require()` accordingly.
## Examples
### JavaScript
```javascript
require('shelljs/global');
if (!which('git')) {
echo('Sorry, this script requires git');
exit(1);
}
// Copy files to release dir
mkdir('-p', 'out/Release');
cp('-R', 'stuff/*', 'out/Release');
// Replace macros in each .js file
cd('lib');
ls('*.js').forEach(function(file) {
sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
sed('-i', /.*REMOVE_THIS_LINE.*\n/, '', file);
sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat('macro.js'), file);
});
cd('..');
// Run external tool synchronously
if (exec('git commit -am "Auto-commit"').code !== 0) {
echo('Error: Git commit failed');
exit(1);
}
```
### CoffeeScript
```coffeescript
require 'shelljs/global'
if not which 'git'
echo 'Sorry, this script requires git'
exit 1
# Copy files to release dir
mkdir '-p', 'out/Release'
cp '-R', 'stuff/*', 'out/Release'
# Replace macros in each .js file
cd 'lib'
for file in ls '*.js'
sed '-i', 'BUILD_VERSION', 'v0.1.2', file
sed '-i', /.*REMOVE_THIS_LINE.*\n/, '', file
sed '-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat 'macro.js', file
cd '..'
# Run external tool synchronously
if (exec 'git commit -am "Auto-commit"').code != 0
echo 'Error: Git commit failed'
exit 1
```
## Global vs. Local
The example above uses the convenience script `shelljs/global` to reduce verbosity. If polluting your global namespace is not desirable, simply require `shelljs`.
Example:
```javascript
var shell = require('shelljs');
shell.echo('hello world');
```
## Make tool
A convenience script `shelljs/make` is also provided to mimic the behavior of a Unix Makefile. In this case all shell objects are global, and command line arguments will cause the script to execute only the corresponding function in the global `target` object. To avoid redundant calls, target functions are executed only once per script.
Example (CoffeeScript):
```coffeescript
require 'shelljs/make'
target.all = ->
target.bundle()
target.docs()
target.bundle = ->
cd __dirname
mkdir 'build'
cd 'lib'
(cat '*.js').to '../build/output.js'
target.docs = ->
cd __dirname
mkdir 'docs'
cd 'lib'
for file in ls '*.js'
text = grep '//@', file # extract special comments
text.replace '//@', '' # remove comment tags
text.to 'docs/my_docs.md'
```
To run the target `all`, call the above script without arguments: `$ node make`. To run the target `docs`: `$ node make docs`, and so on.
<!--
DO NOT MODIFY BEYOND THIS POINT - IT'S AUTOMATICALLY GENERATED
-->
## Command reference
All commands run synchronously, unless otherwise stated.
### cd('dir')
Changes to directory `dir` for the duration of the script
### pwd()
Returns the current directory.
### ls([options ,] path [,path ...])
### ls([options ,] path_array)
Available options:
+ `-R`: recursive
+ `-A`: all files (include files beginning with `.`, except for `.` and `..`)
Examples:
```javascript
ls('projs/*.js');
ls('-R', '/users/me', '/tmp');
ls('-R', ['/users/me', '/tmp']); // same as above
```
Returns array of files in the given path, or in current directory if no path provided.
### find(path [,path ...])
### find(path_array)
Examples:
```javascript
find('src', 'lib');
find(['src', 'lib']); // same as above
find('.').filter(function(file) { return file.match(/\.js$/); });
```
Returns array of all files (however deep) in the given paths.
The main difference from `ls('-R', path)` is that the resulting file names
include the base directories, e.g. `lib/resources/file1` instead of just `file1`.
### cp([options ,] source [,source ...], dest)
### cp([options ,] source_array, dest)
Available options:
+ `-f`: force
+ `-r, -R`: recursive
Examples:
```javascript
cp('file1', 'dir1');
cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
```
Copies files. The wildcard `*` is accepted.
### rm([options ,] file [, file ...])
### rm([options ,] file_array)
Available options:
+ `-f`: force
+ `-r, -R`: recursive
Examples:
```javascript
rm('-rf', '/tmp/*');
rm('some_file.txt', 'another_file.txt');
rm(['some_file.txt', 'another_file.txt']); // same as above
```
Removes files. The wildcard `*` is accepted.
### mv(source [, source ...], dest')
### mv(source_array, dest')
Available options:
+ `f`: force
Examples:
```javascript
mv('-f', 'file', 'dir/');
mv('file1', 'file2', 'dir/');
mv(['file1', 'file2'], 'dir/'); // same as above
```
Moves files. The wildcard `*` is accepted.
### mkdir([options ,] dir [, dir ...])
### mkdir([options ,] dir_array)
Available options:
+ `p`: full path (will create intermediate dirs if necessary)
Examples:
```javascript
mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');
mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above
```
Creates directories.
### test(expression)
Available expression primaries:
+ `'-b', 'path'`: true if path is a block device
+ `'-c', 'path'`: true if path is a character device
+ `'-d', 'path'`: true if path is a directory
+ `'-e', 'path'`: true if path exists
+ `'-f', 'path'`: true if path is a regular file
+ `'-L', 'path'`: true if path is a symboilc link
+ `'-p', 'path'`: true if path is a pipe (FIFO)
+ `'-S', 'path'`: true if path is a socket
Examples:
```javascript
if (test('-d', path)) { /* do something with dir */ };
if (!test('-f', path)) continue; // skip if it's a regular file
```
Evaluates expression using the available primaries and returns corresponding value.
### cat(file [, file ...])
### cat(file_array)
Examples:
```javascript
var str = cat('file*.txt');
var str = cat('file1', 'file2');
var str = cat(['file1', 'file2']); // same as above
```
Returns a string containing the given file, or a concatenated string
containing the files if more than one file is given (a new line character is
introduced between each file). Wildcard `*` accepted.
### 'string'.to(file)
Examples:
```javascript
cat('input.txt').to('output.txt');
```
Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as
those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_
### 'string'.toEnd(file)
Examples:
```javascript
cat('input.txt').toEnd('output.txt');
```
Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaScript strings (such as
those returned by `cat`, `grep`, etc).
### sed([options ,] search_regex, replace_str, file)
Available options:
+ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_
Examples:
```javascript
sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
```
Reads an input string from `file` and performs a JavaScript `replace()` on the input
using the given search regex and replacement string. Returns the new string after replacement.
### grep([options ,] regex_filter, file [, file ...])
### grep([options ,] regex_filter, file_array)
Available options:
+ `-v`: Inverse the sense of the regex and print the lines not matching the criteria.
Examples:
```javascript
grep('-v', 'GLOBAL_VARIABLE', '*.js');
grep('GLOBAL_VARIABLE', '*.js');
```
Reads input string from given files and returns a string containing all lines of the
file that match the given `regex_filter`. Wildcard `*` accepted.
### which(command)
Examples:
```javascript
var nodeExec = which('node');
```
Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.
Returns string containing the absolute path to the command.
### echo(string [,string ...])
Examples:
```javascript
echo('hello world');
var str = echo('hello world');
```
Prints string to stdout, and returns string with additional utility methods
like `.to()`.
### pushd([options,] [dir | '-N' | '+N'])
Available options:
+ `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated.
Arguments:
+ `dir`: Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir`.
+ `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
+ `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
Examples:
```javascript
// process.cwd() === '/usr'
pushd('/etc'); // Returns /etc /usr
pushd('+1'); // Returns /usr /etc
```
Save the current directory on the top of the directory stack and then cd to `dir`. With no arguments, pushd exchanges the top two directories. Returns an array of paths in the stack.
### popd([options,] ['-N' | '+N'])
Available options:
+ `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated.
Arguments:
+ `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero.
+ `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero.
Examples:
```javascript
echo(process.cwd()); // '/usr'
pushd('/etc'); // '/etc /usr'
echo(process.cwd()); // '/etc'
popd(); // '/usr'
echo(process.cwd()); // '/usr'
```
When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack.
### dirs([options | '+N' | '-N'])
Available options:
+ `-c`: Clears the directory stack by deleting all of the elements.
Arguments:
+ `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.
+ `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero.
Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified.
See also: pushd, popd
### exit(code)
Exits the current process with the given exit code.
### env['VAR_NAME']
Object containing environment variables (both getter and setter). Shortcut to process.env.
### exec(command [, options] [, callback])
Available options (all `false` by default):
+ `async`: Asynchronous execution. Defaults to true if a callback is provided.
+ `silent`: Do not echo program output to console.
Examples:
```javascript
var version = exec('node --version', {silent:true}).output;
var child = exec('some_long_running_process', {async:true});
child.stdout.on('data', function(data) {
/* ... do something with data ... */
});
exec('some_long_running_process', function(code, output) {
console.log('Exit code:', code);
console.log('Program output:', output);
});
```
Executes the given `command` _synchronously_, unless otherwise specified.
When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's
`output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and
the `callback` gets the arguments `(code, output)`.
**Note:** For long-lived processes, it's best to run `exec()` asynchronously as
the current synchronous implementation uses a lot of CPU. This should be getting
fixed soon.
### chmod(octal_mode || octal_string, file)
### chmod(symbolic_mode, file)
Available options:
+ `-v`: output a diagnostic for every file processed
+ `-c`: like verbose but report only when a change is made
+ `-R`: change files and directories recursively
Examples:
```javascript
chmod(755, '/Users/brandon');
chmod('755', '/Users/brandon'); // same as above
chmod('u+x', '/Users/brandon');
```
Alters the permissions of a file or directory by either specifying the
absolute permissions in octal form or expressing the changes in symbols.
This command tries to mimic the POSIX behavior as much as possible.
Notable exceptions:
+ In symbolic modes, 'a-r' and '-r' are identical. No consideration is
given to the umask.
+ There is no "quiet" option since default behavior is to run silent.
## Non-Unix commands
### tempdir()
Examples:
```javascript
var tmp = tempdir(); // "/tmp" for most *nix platforms
```
Searches and returns string containing a writeable, platform-dependent temporary directory.
Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
### error()
Tests if error occurred in the last command. Returns `null` if no error occurred,
otherwise returns string explaining the error
## Configuration
### config.silent
Example:
```javascript
var silentState = config.silent; // save old silent state
config.silent = true;
/* ... */
config.silent = silentState; // restore old silent state
```
Suppresses all command output if `true`, except for `echo()` calls.
Default is `false`.
### config.fatal
Example:
```javascript
config.fatal = true;
cp('this_file_does_not_exist', '/dev/null'); // dies here
/* more commands... */
```
If `true` the script will die on errors. Default is `false`.

51
bin/node_modules/shelljs/bin/shjs generated vendored Executable file
View File

@ -0,0 +1,51 @@
#!/usr/bin/env node
require('../global');
if (process.argv.length < 3) {
console.log('ShellJS: missing argument (script name)');
console.log();
process.exit(1);
}
var args,
scriptName = process.argv[2];
env['NODE_PATH'] = __dirname + '/../..';
if (!scriptName.match(/\.js/) && !scriptName.match(/\.coffee/)) {
if (test('-f', scriptName + '.js'))
scriptName += '.js';
if (test('-f', scriptName + '.coffee'))
scriptName += '.coffee';
}
if (!test('-f', scriptName)) {
console.log('ShellJS: script not found ('+scriptName+')');
console.log();
process.exit(1);
}
args = process.argv.slice(3);
for (var i = 0, l = args.length; i < l; i++) {
if (args[i][0] !== "-"){
args[i] = '"' + args[i] + '"'; // fixes arguments with multiple words
}
}
if (scriptName.match(/\.coffee$/)) {
//
// CoffeeScript
//
if (which('coffee')) {
exec('coffee ' + scriptName + ' ' + args.join(' '), { async: true });
} else {
console.log('ShellJS: CoffeeScript interpreter not found');
console.log();
process.exit(1);
}
} else {
//
// JavaScript
//
exec('node ' + scriptName + ' ' + args.join(' '), { async: true });
}

3
bin/node_modules/shelljs/global.js generated vendored Normal file
View File

@ -0,0 +1,3 @@
var shell = require('./shell.js');
for (var cmd in shell)
global[cmd] = shell[cmd];

47
bin/node_modules/shelljs/make.js generated vendored Normal file
View File

@ -0,0 +1,47 @@
require('./global');
global.config.fatal = true;
global.target = {};
// This ensures we only execute the script targets after the entire script has
// been evaluated
var args = process.argv.slice(2);
setTimeout(function() {
var t;
if (args.length === 1 && args[0] === '--help') {
console.log('Available targets:');
for (t in global.target)
console.log(' ' + t);
return;
}
// Wrap targets to prevent duplicate execution
for (t in global.target) {
(function(t, oldTarget){
// Wrap it
global.target[t] = function(force) {
if (oldTarget.done && !force)
return;
oldTarget.done = true;
return oldTarget.apply(oldTarget, arguments);
};
})(t, global.target[t]);
}
// Execute desired targets
if (args.length > 0) {
args.forEach(function(arg) {
if (arg in global.target)
global.target[arg]();
else {
console.log('no such target: ' + arg);
}
});
} else if ('all' in global.target) {
global.target.all();
}
}, 0);

48
bin/node_modules/shelljs/package.json generated vendored Normal file

File diff suppressed because one or more lines are too long

21
bin/node_modules/shelljs/scripts/generate-docs.js generated vendored Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/env node
require('../global');
echo('Appending docs to README.md');
cd(__dirname + '/..');
// Extract docs from shell.js
var docs = grep('//@', 'shell.js');
docs = docs.replace(/\/\/\@include (.+)/g, function(match, path) {
var file = path.match('.js$') ? path : path+'.js';
return grep('//@', file);
});
// Remove '//@'
docs = docs.replace(/\/\/\@ ?/g, '');
// Append docs to README
sed('-i', /## Command reference(.|\n)*/, '## Command reference\n\n' + docs, 'README.md');
echo('All done.');

50
bin/node_modules/shelljs/scripts/run-tests.js generated vendored Executable file
View File

@ -0,0 +1,50 @@
#!/usr/bin/env node
require('../global');
var path = require('path');
var failed = false;
//
// Lint
//
JSHINT_BIN = './node_modules/jshint/bin/jshint';
cd(__dirname + '/..');
if (!test('-f', JSHINT_BIN)) {
echo('JSHint not found. Run `npm install` in the root dir first.');
exit(1);
}
if (exec(JSHINT_BIN + ' *.js test/*.js').code !== 0) {
failed = true;
echo('*** JSHINT FAILED! (return code != 0)');
echo();
} else {
echo('All JSHint tests passed');
echo();
}
//
// Unit tests
//
cd(__dirname + '/../test');
ls('*.js').forEach(function(file) {
echo('Running test:', file);
if (exec('node ' + file).code !== 123) { // 123 avoids false positives (e.g. premature exit)
failed = true;
echo('*** TEST FAILED! (missing exit code "123")');
echo();
}
});
if (failed) {
echo();
echo('*******************************************************');
echo('WARNING: Some tests did not pass!');
echo('*******************************************************');
exit(1);
} else {
echo();
echo('All tests passed.');
}

153
bin/node_modules/shelljs/shell.js generated vendored Normal file
View File

@ -0,0 +1,153 @@
//
// ShellJS
// Unix shell commands on top of Node's API
//
// Copyright (c) 2012 Artur Adib
// http://github.com/arturadib/shelljs
//
var common = require('./src/common');
//@
//@ All commands run synchronously, unless otherwise stated.
//@
//@include ./src/cd
var _cd = require('./src/cd');
exports.cd = common.wrap('cd', _cd);
//@include ./src/pwd
var _pwd = require('./src/pwd');
exports.pwd = common.wrap('pwd', _pwd);
//@include ./src/ls
var _ls = require('./src/ls');
exports.ls = common.wrap('ls', _ls);
//@include ./src/find
var _find = require('./src/find');
exports.find = common.wrap('find', _find);
//@include ./src/cp
var _cp = require('./src/cp');
exports.cp = common.wrap('cp', _cp);
//@include ./src/rm
var _rm = require('./src/rm');
exports.rm = common.wrap('rm', _rm);
//@include ./src/mv
var _mv = require('./src/mv');
exports.mv = common.wrap('mv', _mv);
//@include ./src/mkdir
var _mkdir = require('./src/mkdir');
exports.mkdir = common.wrap('mkdir', _mkdir);
//@include ./src/test
var _test = require('./src/test');
exports.test = common.wrap('test', _test);
//@include ./src/cat
var _cat = require('./src/cat');
exports.cat = common.wrap('cat', _cat);
//@include ./src/to
var _to = require('./src/to');
String.prototype.to = common.wrap('to', _to);
//@include ./src/toEnd
var _toEnd = require('./src/toEnd');
String.prototype.toEnd = common.wrap('toEnd', _toEnd);
//@include ./src/sed
var _sed = require('./src/sed');
exports.sed = common.wrap('sed', _sed);
//@include ./src/grep
var _grep = require('./src/grep');
exports.grep = common.wrap('grep', _grep);
//@include ./src/which
var _which = require('./src/which');
exports.which = common.wrap('which', _which);
//@include ./src/echo
var _echo = require('./src/echo');
exports.echo = _echo; // don't common.wrap() as it could parse '-options'
//@include ./src/dirs
var _dirs = require('./src/dirs').dirs;
exports.dirs = common.wrap("dirs", _dirs);
var _pushd = require('./src/dirs').pushd;
exports.pushd = common.wrap('pushd', _pushd);
var _popd = require('./src/dirs').popd;
exports.popd = common.wrap("popd", _popd);
//@
//@ ### exit(code)
//@ Exits the current process with the given exit code.
exports.exit = process.exit;
//@
//@ ### env['VAR_NAME']
//@ Object containing environment variables (both getter and setter). Shortcut to process.env.
exports.env = process.env;
//@include ./src/exec
var _exec = require('./src/exec');
exports.exec = common.wrap('exec', _exec, {notUnix:true});
//@include ./src/chmod
var _chmod = require('./src/chmod');
exports.chmod = common.wrap('chmod', _chmod);
//@
//@ ## Non-Unix commands
//@
//@include ./src/tempdir
var _tempDir = require('./src/tempdir');
exports.tempdir = common.wrap('tempdir', _tempDir);
//@include ./src/error
var _error = require('./src/error');
exports.error = _error;
//@
//@ ## Configuration
//@
exports.config = common.config;
//@
//@ ### config.silent
//@ Example:
//@
//@ ```javascript
//@ var silentState = config.silent; // save old silent state
//@ config.silent = true;
//@ /* ... */
//@ config.silent = silentState; // restore old silent state
//@ ```
//@
//@ Suppresses all command output if `true`, except for `echo()` calls.
//@ Default is `false`.
//@
//@ ### config.fatal
//@ Example:
//@
//@ ```javascript
//@ config.fatal = true;
//@ cp('this_file_does_not_exist', '/dev/null'); // dies here
//@ /* more commands... */
//@ ```
//@
//@ If `true` the script will die on errors. Default is `false`.

43
bin/node_modules/shelljs/src/cat.js generated vendored Normal file
View File

@ -0,0 +1,43 @@
var common = require('./common');
var fs = require('fs');
//@
//@ ### cat(file [, file ...])
//@ ### cat(file_array)
//@
//@ Examples:
//@
//@ ```javascript
//@ var str = cat('file*.txt');
//@ var str = cat('file1', 'file2');
//@ var str = cat(['file1', 'file2']); // same as above
//@ ```
//@
//@ Returns a string containing the given file, or a concatenated string
//@ containing the files if more than one file is given (a new line character is
//@ introduced between each file). Wildcard `*` accepted.
function _cat(options, files) {
var cat = '';
if (!files)
common.error('no paths given');
if (typeof files === 'string')
files = [].slice.call(arguments, 1);
// if it's array leave it as it is
files = common.expand(files);
files.forEach(function(file) {
if (!fs.existsSync(file))
common.error('no such file or directory: ' + file);
cat += fs.readFileSync(file, 'utf8') + '\n';
});
if (cat[cat.length-1] === '\n')
cat = cat.substring(0, cat.length-1);
return common.ShellString(cat);
}
module.exports = _cat;

19
bin/node_modules/shelljs/src/cd.js generated vendored Normal file
View File

@ -0,0 +1,19 @@
var fs = require('fs');
var common = require('./common');
//@
//@ ### cd('dir')
//@ Changes to directory `dir` for the duration of the script
function _cd(options, dir) {
if (!dir)
common.error('directory not specified');
if (!fs.existsSync(dir))
common.error('no such file or directory: ' + dir);
if (!fs.statSync(dir).isDirectory())
common.error('not a directory: ' + dir);
process.chdir(dir);
}
module.exports = _cd;

208
bin/node_modules/shelljs/src/chmod.js generated vendored Normal file
View File

@ -0,0 +1,208 @@
var common = require('./common');
var fs = require('fs');
var path = require('path');
var PERMS = (function (base) {
return {
OTHER_EXEC : base.EXEC,
OTHER_WRITE : base.WRITE,
OTHER_READ : base.READ,
GROUP_EXEC : base.EXEC << 3,
GROUP_WRITE : base.WRITE << 3,
GROUP_READ : base.READ << 3,
OWNER_EXEC : base.EXEC << 6,
OWNER_WRITE : base.WRITE << 6,
OWNER_READ : base.READ << 6,
// Literal octal numbers are apparently not allowed in "strict" javascript. Using parseInt is
// the preferred way, else a jshint warning is thrown.
STICKY : parseInt('01000', 8),
SETGID : parseInt('02000', 8),
SETUID : parseInt('04000', 8),
TYPE_MASK : parseInt('0770000', 8)
};
})({
EXEC : 1,
WRITE : 2,
READ : 4
});
//@
//@ ### chmod(octal_mode || octal_string, file)
//@ ### chmod(symbolic_mode, file)
//@
//@ Available options:
//@
//@ + `-v`: output a diagnostic for every file processed//@
//@ + `-c`: like verbose but report only when a change is made//@
//@ + `-R`: change files and directories recursively//@
//@
//@ Examples:
//@
//@ ```javascript
//@ chmod(755, '/Users/brandon');
//@ chmod('755', '/Users/brandon'); // same as above
//@ chmod('u+x', '/Users/brandon');
//@ ```
//@
//@ Alters the permissions of a file or directory by either specifying the
//@ absolute permissions in octal form or expressing the changes in symbols.
//@ This command tries to mimic the POSIX behavior as much as possible.
//@ Notable exceptions:
//@
//@ + In symbolic modes, 'a-r' and '-r' are identical. No consideration is
//@ given to the umask.
//@ + There is no "quiet" option since default behavior is to run silent.
function _chmod(options, mode, filePattern) {
if (!filePattern) {
if (options.length > 0 && options.charAt(0) === '-') {
// Special case where the specified file permissions started with - to subtract perms, which
// get picked up by the option parser as command flags.
// If we are down by one argument and options starts with -, shift everything over.
filePattern = mode;
mode = options;
options = '';
}
else {
common.error('You must specify a file.');
}
}
options = common.parseOptions(options, {
'R': 'recursive',
'c': 'changes',
'v': 'verbose'
});
if (typeof filePattern === 'string') {
filePattern = [ filePattern ];
}
var files;
if (options.recursive) {
files = [];
common.expand(filePattern).forEach(function addFile(expandedFile) {
var stat = fs.lstatSync(expandedFile);
if (!stat.isSymbolicLink()) {
files.push(expandedFile);
if (stat.isDirectory()) { // intentionally does not follow symlinks.
fs.readdirSync(expandedFile).forEach(function (child) {
addFile(expandedFile + '/' + child);
});
}
}
});
}
else {
files = common.expand(filePattern);
}
files.forEach(function innerChmod(file) {
file = path.resolve(file);
if (!fs.existsSync(file)) {
common.error('File not found: ' + file);
}
// When recursing, don't follow symlinks.
if (options.recursive && fs.lstatSync(file).isSymbolicLink()) {
return;
}
var perms = fs.statSync(file).mode;
var type = perms & PERMS.TYPE_MASK;
var newPerms = perms;
if (isNaN(parseInt(mode, 8))) {
// parse options
mode.split(',').forEach(function (symbolicMode) {
/*jshint regexdash:true */
var pattern = /([ugoa]*)([=\+-])([rwxXst]*)/i;
var matches = pattern.exec(symbolicMode);
if (matches) {
var applyTo = matches[1];
var operator = matches[2];
var change = matches[3];
var changeOwner = applyTo.indexOf('u') != -1 || applyTo === 'a' || applyTo === '';
var changeGroup = applyTo.indexOf('g') != -1 || applyTo === 'a' || applyTo === '';
var changeOther = applyTo.indexOf('o') != -1 || applyTo === 'a' || applyTo === '';
var changeRead = change.indexOf('r') != -1;
var changeWrite = change.indexOf('w') != -1;
var changeExec = change.indexOf('x') != -1;
var changeSticky = change.indexOf('t') != -1;
var changeSetuid = change.indexOf('s') != -1;
var mask = 0;
if (changeOwner) {
mask |= (changeRead ? PERMS.OWNER_READ : 0) + (changeWrite ? PERMS.OWNER_WRITE : 0) + (changeExec ? PERMS.OWNER_EXEC : 0) + (changeSetuid ? PERMS.SETUID : 0);
}
if (changeGroup) {
mask |= (changeRead ? PERMS.GROUP_READ : 0) + (changeWrite ? PERMS.GROUP_WRITE : 0) + (changeExec ? PERMS.GROUP_EXEC : 0) + (changeSetuid ? PERMS.SETGID : 0);
}
if (changeOther) {
mask |= (changeRead ? PERMS.OTHER_READ : 0) + (changeWrite ? PERMS.OTHER_WRITE : 0) + (changeExec ? PERMS.OTHER_EXEC : 0);
}
// Sticky bit is special - it's not tied to user, group or other.
if (changeSticky) {
mask |= PERMS.STICKY;
}
switch (operator) {
case '+':
newPerms |= mask;
break;
case '-':
newPerms &= ~mask;
break;
case '=':
newPerms = type + mask;
// According to POSIX, when using = to explicitly set the permissions, setuid and setgid can never be cleared.
if (fs.statSync(file).isDirectory()) {
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
}
break;
}
if (options.verbose) {
log(file + ' -> ' + newPerms.toString(8));
}
if (perms != newPerms) {
if (!options.verbose && options.changes) {
log(file + ' -> ' + newPerms.toString(8));
}
fs.chmodSync(file, newPerms);
}
}
else {
common.error('Invalid symbolic mode change: ' + symbolicMode);
}
});
}
else {
// they gave us a full number
newPerms = type + parseInt(mode, 8);
// POSIX rules are that setuid and setgid can only be added using numeric form, but not cleared.
if (fs.statSync(file).isDirectory()) {
newPerms |= (PERMS.SETUID + PERMS.SETGID) & perms;
}
fs.chmodSync(file, newPerms);
}
});
}
module.exports = _chmod;

189
bin/node_modules/shelljs/src/common.js generated vendored Normal file
View File

@ -0,0 +1,189 @@
var os = require('os');
var fs = require('fs');
var _ls = require('./ls');
// Module globals
var config = {
silent: false,
fatal: false
};
exports.config = config;
var state = {
error: null,
currentCmd: 'shell.js',
tempDir: null
};
exports.state = state;
var platform = os.type().match(/^Win/) ? 'win' : 'unix';
exports.platform = platform;
function log() {
if (!config.silent)
console.log.apply(this, arguments);
}
exports.log = log;
// Shows error message. Throws unless _continue or config.fatal are true
function error(msg, _continue) {
if (state.error === null)
state.error = '';
state.error += state.currentCmd + ': ' + msg + '\n';
if (msg.length > 0)
log(state.error);
if (config.fatal)
process.exit(1);
if (!_continue)
throw '';
}
exports.error = error;
// In the future, when Proxies are default, we can add methods like `.to()` to primitive strings.
// For now, this is a dummy function to bookmark places we need such strings
function ShellString(str) {
return str;
}
exports.ShellString = ShellString;
// Returns {'alice': true, 'bob': false} when passed a dictionary, e.g.:
// parseOptions('-a', {'a':'alice', 'b':'bob'});
function parseOptions(str, map) {
if (!map)
error('parseOptions() internal error: no map given');
// All options are false by default
var options = {};
for (var letter in map)
options[map[letter]] = false;
if (!str)
return options; // defaults
if (typeof str !== 'string')
error('parseOptions() internal error: wrong str');
// e.g. match[1] = 'Rf' for str = '-Rf'
var match = str.match(/^\-(.+)/);
if (!match)
return options;
// e.g. chars = ['R', 'f']
var chars = match[1].split('');
chars.forEach(function(c) {
if (c in map)
options[map[c]] = true;
else
error('option not recognized: '+c);
});
return options;
}
exports.parseOptions = parseOptions;
// Expands wildcards with matching (ie. existing) file names.
// For example:
// expand(['file*.js']) = ['file1.js', 'file2.js', ...]
// (if the files 'file1.js', 'file2.js', etc, exist in the current dir)
function expand(list) {
var expanded = [];
list.forEach(function(listEl) {
// Wildcard present?
if (listEl.search(/\*/) > -1) {
_ls('', listEl).forEach(function(file) {
expanded.push(file);
});
} else {
expanded.push(listEl);
}
});
return expanded;
}
exports.expand = expand;
// Normalizes _unlinkSync() across platforms to match Unix behavior, i.e.
// file can be unlinked even if it's read-only, see https://github.com/joyent/node/issues/3006
function unlinkSync(file) {
try {
fs.unlinkSync(file);
} catch(e) {
// Try to override file permission
if (e.code === 'EPERM') {
fs.chmodSync(file, '0666');
fs.unlinkSync(file);
} else {
throw e;
}
}
}
exports.unlinkSync = unlinkSync;
// e.g. 'shelljs_a5f185d0443ca...'
function randomFileName() {
function randomHash(count) {
if (count === 1)
return parseInt(16*Math.random(), 10).toString(16);
else {
var hash = '';
for (var i=0; i<count; i++)
hash += randomHash(1);
return hash;
}
}
return 'shelljs_'+randomHash(20);
}
exports.randomFileName = randomFileName;
// extend(target_obj, source_obj1 [, source_obj2 ...])
// Shallow extend, e.g.:
// extend({A:1}, {b:2}, {c:3}) returns {A:1, b:2, c:3}
function extend(target) {
var sources = [].slice.call(arguments, 1);
sources.forEach(function(source) {
for (var key in source)
target[key] = source[key];
});
return target;
}
exports.extend = extend;
// Common wrapper for all Unix-like commands
function wrap(cmd, fn, options) {
return function() {
var retValue = null;
state.currentCmd = cmd;
state.error = null;
try {
var args = [].slice.call(arguments, 0);
if (options && options.notUnix) {
retValue = fn.apply(this, args);
} else {
if (args.length === 0 || typeof args[0] !== 'string' || args[0][0] !== '-')
args.unshift(''); // only add dummy option if '-option' not already present
retValue = fn.apply(this, args);
}
} catch (e) {
if (!state.error) {
// If state.error hasn't been set it's an error thrown by Node, not us - probably a bug...
console.log('shell.js: internal error');
console.log(e.stack || e);
process.exit(1);
}
if (config.fatal)
throw e;
}
state.currentCmd = 'shell.js';
return retValue;
};
} // wrap
exports.wrap = wrap;

200
bin/node_modules/shelljs/src/cp.js generated vendored Normal file
View File

@ -0,0 +1,200 @@
var fs = require('fs');
var path = require('path');
var common = require('./common');
// Buffered file copy, synchronous
// (Using readFileSync() + writeFileSync() could easily cause a memory overflow
// with large files)
function copyFileSync(srcFile, destFile) {
if (!fs.existsSync(srcFile))
common.error('copyFileSync: no such file or directory: ' + srcFile);
var BUF_LENGTH = 64*1024,
buf = new Buffer(BUF_LENGTH),
bytesRead = BUF_LENGTH,
pos = 0,
fdr = null,
fdw = null;
try {
fdr = fs.openSync(srcFile, 'r');
} catch(e) {
common.error('copyFileSync: could not read src file ('+srcFile+')');
}
try {
fdw = fs.openSync(destFile, 'w');
} catch(e) {
common.error('copyFileSync: could not write to dest file (code='+e.code+'):'+destFile);
}
while (bytesRead === BUF_LENGTH) {
bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
fs.writeSync(fdw, buf, 0, bytesRead);
pos += bytesRead;
}
fs.closeSync(fdr);
fs.closeSync(fdw);
fs.chmodSync(destFile, fs.statSync(srcFile).mode);
}
// Recursively copies 'sourceDir' into 'destDir'
// Adapted from https://github.com/ryanmcgrath/wrench-js
//
// Copyright (c) 2010 Ryan McGrath
// Copyright (c) 2012 Artur Adib
//
// Licensed under the MIT License
// http://www.opensource.org/licenses/mit-license.php
function cpdirSyncRecursive(sourceDir, destDir, opts) {
if (!opts) opts = {};
/* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
var checkDir = fs.statSync(sourceDir);
try {
fs.mkdirSync(destDir, checkDir.mode);
} catch (e) {
//if the directory already exists, that's okay
if (e.code !== 'EEXIST') throw e;
}
var files = fs.readdirSync(sourceDir);
for (var i = 0; i < files.length; i++) {
var srcFile = sourceDir + "/" + files[i];
var destFile = destDir + "/" + files[i];
var srcFileStat = fs.lstatSync(srcFile);
if (srcFileStat.isDirectory()) {
/* recursion this thing right on back. */
cpdirSyncRecursive(srcFile, destFile, opts);
} else if (srcFileStat.isSymbolicLink()) {
var symlinkFull = fs.readlinkSync(srcFile);
fs.symlinkSync(symlinkFull, destFile);
} else {
/* At this point, we've hit a file actually worth copying... so copy it on over. */
if (fs.existsSync(destFile) && !opts.force) {
common.log('skipping existing file: ' + files[i]);
} else {
copyFileSync(srcFile, destFile);
}
}
} // for files
} // cpdirSyncRecursive
//@
//@ ### cp([options ,] source [,source ...], dest)
//@ ### cp([options ,] source_array, dest)
//@ Available options:
//@
//@ + `-f`: force
//@ + `-r, -R`: recursive
//@
//@ Examples:
//@
//@ ```javascript
//@ cp('file1', 'dir1');
//@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
//@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
//@ ```
//@
//@ Copies files. The wildcard `*` is accepted.
function _cp(options, sources, dest) {
options = common.parseOptions(options, {
'f': 'force',
'R': 'recursive',
'r': 'recursive'
});
// Get sources, dest
if (arguments.length < 3) {
common.error('missing <source> and/or <dest>');
} else if (arguments.length > 3) {
sources = [].slice.call(arguments, 1, arguments.length - 1);
dest = arguments[arguments.length - 1];
} else if (typeof sources === 'string') {
sources = [sources];
} else if ('length' in sources) {
sources = sources; // no-op for array
} else {
common.error('invalid arguments');
}
var exists = fs.existsSync(dest),
stats = exists && fs.statSync(dest);
// Dest is not existing dir, but multiple sources given
if ((!exists || !stats.isDirectory()) && sources.length > 1)
common.error('dest is not a directory (too many sources)');
// Dest is an existing file, but no -f given
if (exists && stats.isFile() && !options.force)
common.error('dest file already exists: ' + dest);
if (options.recursive) {
// Recursive allows the shortcut syntax "sourcedir/" for "sourcedir/*"
// (see Github issue #15)
sources.forEach(function(src, i) {
if (src[src.length - 1] === '/')
sources[i] += '*';
});
// Create dest
try {
fs.mkdirSync(dest, parseInt('0777', 8));
} catch (e) {
// like Unix's cp, keep going even if we can't create dest dir
}
}
sources = common.expand(sources);
sources.forEach(function(src) {
if (!fs.existsSync(src)) {
common.error('no such file or directory: '+src, true);
return; // skip file
}
// If here, src exists
if (fs.statSync(src).isDirectory()) {
if (!options.recursive) {
// Non-Recursive
common.log(src + ' is a directory (not copied)');
} else {
// Recursive
// 'cp /a/source dest' should create 'source' in 'dest'
var newDest = path.join(dest, path.basename(src)),
checkDir = fs.statSync(src);
try {
fs.mkdirSync(newDest, checkDir.mode);
} catch (e) {
//if the directory already exists, that's okay
if (e.code !== 'EEXIST') throw e;
}
cpdirSyncRecursive(src, newDest, {force: options.force});
}
return; // done with dir
}
// If here, src is a file
// When copying to '/path/dir':
// thisDest = '/path/dir/file1'
var thisDest = dest;
if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
thisDest = path.normalize(dest + '/' + path.basename(src));
if (fs.existsSync(thisDest) && !options.force) {
common.error('dest file already exists: ' + thisDest, true);
return; // skip file
}
copyFileSync(src, thisDest);
}); // forEach(src)
}
module.exports = _cp;

191
bin/node_modules/shelljs/src/dirs.js generated vendored Normal file
View File

@ -0,0 +1,191 @@
var common = require('./common');
var _cd = require('./cd');
var path = require('path');
// Pushd/popd/dirs internals
var _dirStack = [];
function _isStackIndex(index) {
return (/^[\-+]\d+$/).test(index);
}
function _parseStackIndex(index) {
if (_isStackIndex(index)) {
if (Math.abs(index) < _dirStack.length + 1) { // +1 for pwd
return (/^-/).test(index) ? Number(index) - 1 : Number(index);
} else {
common.error(index + ': directory stack index out of range');
}
} else {
common.error(index + ': invalid number');
}
}
function _actualDirStack() {
return [process.cwd()].concat(_dirStack);
}
//@
//@ ### pushd([options,] [dir | '-N' | '+N'])
//@
//@ Available options:
//@
//@ + `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated.
//@
//@ Arguments:
//@
//@ + `dir`: Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir`.
//@ + `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
//@ + `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.
//@
//@ Examples:
//@
//@ ```javascript
//@ // process.cwd() === '/usr'
//@ pushd('/etc'); // Returns /etc /usr
//@ pushd('+1'); // Returns /usr /etc
//@ ```
//@
//@ Save the current directory on the top of the directory stack and then cd to `dir`. With no arguments, pushd exchanges the top two directories. Returns an array of paths in the stack.
function _pushd(options, dir) {
if (_isStackIndex(options)) {
dir = options;
options = '';
}
options = common.parseOptions(options, {
'n' : 'no-cd'
});
var dirs = _actualDirStack();
if (dir === '+0') {
return dirs; // +0 is a noop
} else if (!dir) {
if (dirs.length > 1) {
dirs = dirs.splice(1, 1).concat(dirs);
} else {
return common.error('no other directory');
}
} else if (_isStackIndex(dir)) {
var n = _parseStackIndex(dir);
dirs = dirs.slice(n).concat(dirs.slice(0, n));
} else {
if (options['no-cd']) {
dirs.splice(1, 0, dir);
} else {
dirs.unshift(dir);
}
}
if (options['no-cd']) {
dirs = dirs.slice(1);
} else {
dir = path.resolve(dirs.shift());
_cd('', dir);
}
_dirStack = dirs;
return _dirs('');
}
exports.pushd = _pushd;
//@
//@ ### popd([options,] ['-N' | '+N'])
//@
//@ Available options:
//@
//@ + `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated.
//@
//@ Arguments:
//@
//@ + `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero.
//@ + `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero.
//@
//@ Examples:
//@
//@ ```javascript
//@ echo(process.cwd()); // '/usr'
//@ pushd('/etc'); // '/etc /usr'
//@ echo(process.cwd()); // '/etc'
//@ popd(); // '/usr'
//@ echo(process.cwd()); // '/usr'
//@ ```
//@
//@ When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack.
function _popd(options, index) {
if (_isStackIndex(options)) {
index = options;
options = '';
}
options = common.parseOptions(options, {
'n' : 'no-cd'
});
if (!_dirStack.length) {
return common.error('directory stack empty');
}
index = _parseStackIndex(index || '+0');
if (options['no-cd'] || index > 0 || _dirStack.length + index === 0) {
index = index > 0 ? index - 1 : index;
_dirStack.splice(index, 1);
} else {
var dir = path.resolve(_dirStack.shift());
_cd('', dir);
}
return _dirs('');
}
exports.popd = _popd;
//@
//@ ### dirs([options | '+N' | '-N'])
//@
//@ Available options:
//@
//@ + `-c`: Clears the directory stack by deleting all of the elements.
//@
//@ Arguments:
//@
//@ + `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.
//@ + `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero.
//@
//@ Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified.
//@
//@ See also: pushd, popd
function _dirs(options, index) {
if (_isStackIndex(options)) {
index = options;
options = '';
}
options = common.parseOptions(options, {
'c' : 'clear'
});
if (options['clear']) {
_dirStack = [];
return _dirStack;
}
var stack = _actualDirStack();
if (index) {
index = _parseStackIndex(index);
if (index < 0) {
index = stack.length + index;
}
common.log(stack[index]);
return stack[index];
}
common.log(stack.join(' '));
return stack;
}
exports.dirs = _dirs;

20
bin/node_modules/shelljs/src/echo.js generated vendored Normal file
View File

@ -0,0 +1,20 @@
var common = require('./common');
//@
//@ ### echo(string [,string ...])
//@
//@ Examples:
//@
//@ ```javascript
//@ echo('hello world');
//@ var str = echo('hello world');
//@ ```
//@
//@ Prints string to stdout, and returns string with additional utility methods
//@ like `.to()`.
function _echo() {
var messages = [].slice.call(arguments, 0);
console.log.apply(this, messages);
return common.ShellString(messages.join(' '));
}
module.exports = _echo;

10
bin/node_modules/shelljs/src/error.js generated vendored Normal file
View File

@ -0,0 +1,10 @@
var common = require('./common');
//@
//@ ### error()
//@ Tests if error occurred in the last command. Returns `null` if no error occurred,
//@ otherwise returns string explaining the error
function error() {
return common.state.error;
};
module.exports = error;

181
bin/node_modules/shelljs/src/exec.js generated vendored Normal file
View File

@ -0,0 +1,181 @@
var common = require('./common');
var _tempDir = require('./tempdir');
var _pwd = require('./pwd');
var path = require('path');
var fs = require('fs');
var child = require('child_process');
// Hack to run child_process.exec() synchronously (sync avoids callback hell)
// Uses a custom wait loop that checks for a flag file, created when the child process is done.
// (Can't do a wait loop that checks for internal Node variables/messages as
// Node is single-threaded; callbacks and other internal state changes are done in the
// event loop).
function execSync(cmd, opts) {
var tempDir = _tempDir();
var stdoutFile = path.resolve(tempDir+'/'+common.randomFileName()),
codeFile = path.resolve(tempDir+'/'+common.randomFileName()),
scriptFile = path.resolve(tempDir+'/'+common.randomFileName()),
sleepFile = path.resolve(tempDir+'/'+common.randomFileName());
var options = common.extend({
silent: common.config.silent
}, opts);
var previousStdoutContent = '';
// Echoes stdout changes from running process, if not silent
function updateStdout() {
if (options.silent || !fs.existsSync(stdoutFile))
return;
var stdoutContent = fs.readFileSync(stdoutFile, 'utf8');
// No changes since last time?
if (stdoutContent.length <= previousStdoutContent.length)
return;
process.stdout.write(stdoutContent.substr(previousStdoutContent.length));
previousStdoutContent = stdoutContent;
}
function escape(str) {
return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0");
}
cmd += ' > '+stdoutFile+' 2>&1'; // works on both win/unix
var script =
"var child = require('child_process')," +
" fs = require('fs');" +
"child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: 20*1024*1024}, function(err) {" +
" fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');" +
"});";
if (fs.existsSync(scriptFile)) common.unlinkSync(scriptFile);
if (fs.existsSync(stdoutFile)) common.unlinkSync(stdoutFile);
if (fs.existsSync(codeFile)) common.unlinkSync(codeFile);
fs.writeFileSync(scriptFile, script);
child.exec('"'+process.execPath+'" '+scriptFile, {
env: process.env,
cwd: _pwd(),
maxBuffer: 20*1024*1024
});
// The wait loop
// sleepFile is used as a dummy I/O op to mitigate unnecessary CPU usage
// (tried many I/O sync ops, writeFileSync() seems to be only one that is effective in reducing
// CPU usage, though apparently not so much on Windows)
while (!fs.existsSync(codeFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); }
while (!fs.existsSync(stdoutFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); }
// At this point codeFile exists, but it's not necessarily flushed yet.
// Keep reading it until it is.
var code = parseInt('', 10);
while (isNaN(code)) {
code = parseInt(fs.readFileSync(codeFile, 'utf8'), 10);
}
var stdout = fs.readFileSync(stdoutFile, 'utf8');
// No biggie if we can't erase the files now -- they're in a temp dir anyway
try { common.unlinkSync(scriptFile); } catch(e) {}
try { common.unlinkSync(stdoutFile); } catch(e) {}
try { common.unlinkSync(codeFile); } catch(e) {}
try { common.unlinkSync(sleepFile); } catch(e) {}
// some shell return codes are defined as errors, per http://tldp.org/LDP/abs/html/exitcodes.html
if (code === 1 || code === 2 || code >= 126) {
common.error('', true); // unix/shell doesn't really give an error message after non-zero exit codes
}
// True if successful, false if not
var obj = {
code: code,
output: stdout
};
return obj;
} // execSync()
// Wrapper around exec() to enable echoing output to console in real time
function execAsync(cmd, opts, callback) {
var output = '';
var options = common.extend({
silent: common.config.silent
}, opts);
var c = child.exec(cmd, {env: process.env, maxBuffer: 20*1024*1024}, function(err) {
if (callback)
callback(err ? err.code : 0, output);
});
c.stdout.on('data', function(data) {
output += data;
if (!options.silent)
process.stdout.write(data);
});
c.stderr.on('data', function(data) {
output += data;
if (!options.silent)
process.stdout.write(data);
});
return c;
}
//@
//@ ### exec(command [, options] [, callback])
//@ Available options (all `false` by default):
//@
//@ + `async`: Asynchronous execution. Defaults to true if a callback is provided.
//@ + `silent`: Do not echo program output to console.
//@
//@ Examples:
//@
//@ ```javascript
//@ var version = exec('node --version', {silent:true}).output;
//@
//@ var child = exec('some_long_running_process', {async:true});
//@ child.stdout.on('data', function(data) {
//@ /* ... do something with data ... */
//@ });
//@
//@ exec('some_long_running_process', function(code, output) {
//@ console.log('Exit code:', code);
//@ console.log('Program output:', output);
//@ });
//@ ```
//@
//@ Executes the given `command` _synchronously_, unless otherwise specified.
//@ When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's
//@ `output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and
//@ the `callback` gets the arguments `(code, output)`.
//@
//@ **Note:** For long-lived processes, it's best to run `exec()` asynchronously as
//@ the current synchronous implementation uses a lot of CPU. This should be getting
//@ fixed soon.
function _exec(command, options, callback) {
if (!command)
common.error('must specify command');
// Callback is defined instead of options.
if (typeof options === 'function') {
callback = options;
options = { async: true };
}
// Callback is defined with options.
if (typeof options === 'object' && typeof callback === 'function') {
options.async = true;
}
options = common.extend({
silent: common.config.silent,
async: false
}, options);
if (options.async)
return execAsync(command, options, callback);
else
return execSync(command, options);
}
module.exports = _exec;

51
bin/node_modules/shelljs/src/find.js generated vendored Normal file
View File

@ -0,0 +1,51 @@
var fs = require('fs');
var common = require('./common');
var _ls = require('./ls');
//@
//@ ### find(path [,path ...])
//@ ### find(path_array)
//@ Examples:
//@
//@ ```javascript
//@ find('src', 'lib');
//@ find(['src', 'lib']); // same as above
//@ find('.').filter(function(file) { return file.match(/\.js$/); });
//@ ```
//@
//@ Returns array of all files (however deep) in the given paths.
//@
//@ The main difference from `ls('-R', path)` is that the resulting file names
//@ include the base directories, e.g. `lib/resources/file1` instead of just `file1`.
function _find(options, paths) {
if (!paths)
common.error('no path specified');
else if (typeof paths === 'object')
paths = paths; // assume array
else if (typeof paths === 'string')
paths = [].slice.call(arguments, 1);
var list = [];
function pushFile(file) {
if (common.platform === 'win')
file = file.replace(/\\/g, '/');
list.push(file);
}
// why not simply do ls('-R', paths)? because the output wouldn't give the base dirs
// to get the base dir in the output, we need instead ls('-R', 'dir/*') for every directory
paths.forEach(function(file) {
pushFile(file);
if (fs.statSync(file).isDirectory()) {
_ls('-RA', file+'/*').forEach(function(subfile) {
pushFile(subfile);
});
}
});
return list;
}
module.exports = _find;

52
bin/node_modules/shelljs/src/grep.js generated vendored Normal file
View File

@ -0,0 +1,52 @@
var common = require('./common');
var fs = require('fs');
//@
//@ ### grep([options ,] regex_filter, file [, file ...])
//@ ### grep([options ,] regex_filter, file_array)
//@ Available options:
//@
//@ + `-v`: Inverse the sense of the regex and print the lines not matching the criteria.
//@
//@ Examples:
//@
//@ ```javascript
//@ grep('-v', 'GLOBAL_VARIABLE', '*.js');
//@ grep('GLOBAL_VARIABLE', '*.js');
//@ ```
//@
//@ Reads input string from given files and returns a string containing all lines of the
//@ file that match the given `regex_filter`. Wildcard `*` accepted.
function _grep(options, regex, files) {
options = common.parseOptions(options, {
'v': 'inverse'
});
if (!files)
common.error('no paths given');
if (typeof files === 'string')
files = [].slice.call(arguments, 2);
// if it's array leave it as it is
files = common.expand(files);
var grep = '';
files.forEach(function(file) {
if (!fs.existsSync(file)) {
common.error('no such file or directory: ' + file, true);
return;
}
var contents = fs.readFileSync(file, 'utf8'),
lines = contents.split(/\r*\n/);
lines.forEach(function(line) {
var matched = line.match(regex);
if ((options.inverse && !matched) || (!options.inverse && matched))
grep += line + '\n';
});
});
return common.ShellString(grep);
}
module.exports = _grep;

126
bin/node_modules/shelljs/src/ls.js generated vendored Normal file
View File

@ -0,0 +1,126 @@
var path = require('path');
var fs = require('fs');
var common = require('./common');
var _cd = require('./cd');
var _pwd = require('./pwd');
//@
//@ ### ls([options ,] path [,path ...])
//@ ### ls([options ,] path_array)
//@ Available options:
//@
//@ + `-R`: recursive
//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`)
//@
//@ Examples:
//@
//@ ```javascript
//@ ls('projs/*.js');
//@ ls('-R', '/users/me', '/tmp');
//@ ls('-R', ['/users/me', '/tmp']); // same as above
//@ ```
//@
//@ Returns array of files in the given path, or in current directory if no path provided.
function _ls(options, paths) {
options = common.parseOptions(options, {
'R': 'recursive',
'A': 'all',
'a': 'all_deprecated'
});
if (options.all_deprecated) {
// We won't support the -a option as it's hard to image why it's useful
// (it includes '.' and '..' in addition to '.*' files)
// For backwards compatibility we'll dump a deprecated message and proceed as before
common.log('ls: Option -a is deprecated. Use -A instead');
options.all = true;
}
if (!paths)
paths = ['.'];
else if (typeof paths === 'object')
paths = paths; // assume array
else if (typeof paths === 'string')
paths = [].slice.call(arguments, 1);
var list = [];
// Conditionally pushes file to list - returns true if pushed, false otherwise
// (e.g. prevents hidden files to be included unless explicitly told so)
function pushFile(file, query) {
// hidden file?
if (path.basename(file)[0] === '.') {
// not explicitly asking for hidden files?
if (!options.all && !(path.basename(query)[0] === '.' && path.basename(query).length > 1))
return false;
}
if (common.platform === 'win')
file = file.replace(/\\/g, '/');
list.push(file);
return true;
}
paths.forEach(function(p) {
if (fs.existsSync(p)) {
var stats = fs.statSync(p);
// Simple file?
if (stats.isFile()) {
pushFile(p, p);
return; // continue
}
// Simple dir?
if (stats.isDirectory()) {
// Iterate over p contents
fs.readdirSync(p).forEach(function(file) {
if (!pushFile(file, p))
return;
// Recursive?
if (options.recursive) {
var oldDir = _pwd();
_cd('', p);
if (fs.statSync(file).isDirectory())
list = list.concat(_ls('-R'+(options.all?'A':''), file+'/*'));
_cd('', oldDir);
}
});
return; // continue
}
}
// p does not exist - possible wildcard present
var basename = path.basename(p);
var dirname = path.dirname(p);
// Wildcard present on an existing dir? (e.g. '/tmp/*.js')
if (basename.search(/\*/) > -1 && fs.existsSync(dirname) && fs.statSync(dirname).isDirectory) {
// Escape special regular expression chars
var regexp = basename.replace(/(\^|\$|\(|\)|<|>|\[|\]|\{|\}|\.|\+|\?)/g, '\\$1');
// Translates wildcard into regex
regexp = '^' + regexp.replace(/\*/g, '.*') + '$';
// Iterate over directory contents
fs.readdirSync(dirname).forEach(function(file) {
if (file.match(new RegExp(regexp))) {
if (!pushFile(path.normalize(dirname+'/'+file), basename))
return;
// Recursive?
if (options.recursive) {
var pp = dirname + '/' + file;
if (fs.lstatSync(pp).isDirectory())
list = list.concat(_ls('-R'+(options.all?'A':''), pp+'/*'));
} // recursive
} // if file matches
}); // forEach
return;
}
common.error('no such file or directory: ' + p, true);
});
return list;
}
module.exports = _ls;

68
bin/node_modules/shelljs/src/mkdir.js generated vendored Normal file
View File

@ -0,0 +1,68 @@
var common = require('./common');
var fs = require('fs');
var path = require('path');
// Recursively creates 'dir'
function mkdirSyncRecursive(dir) {
var baseDir = path.dirname(dir);
// Base dir exists, no recursion necessary
if (fs.existsSync(baseDir)) {
fs.mkdirSync(dir, parseInt('0777', 8));
return;
}
// Base dir does not exist, go recursive
mkdirSyncRecursive(baseDir);
// Base dir created, can create dir
fs.mkdirSync(dir, parseInt('0777', 8));
}
//@
//@ ### mkdir([options ,] dir [, dir ...])
//@ ### mkdir([options ,] dir_array)
//@ Available options:
//@
//@ + `p`: full path (will create intermediate dirs if necessary)
//@
//@ Examples:
//@
//@ ```javascript
//@ mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');
//@ mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above
//@ ```
//@
//@ Creates directories.
function _mkdir(options, dirs) {
options = common.parseOptions(options, {
'p': 'fullpath'
});
if (!dirs)
common.error('no paths given');
if (typeof dirs === 'string')
dirs = [].slice.call(arguments, 1);
// if it's array leave it as it is
dirs.forEach(function(dir) {
if (fs.existsSync(dir)) {
if (!options.fullpath)
common.error('path already exists: ' + dir, true);
return; // skip dir
}
// Base dir does not exist, and no -p option given
var baseDir = path.dirname(dir);
if (!fs.existsSync(baseDir) && !options.fullpath) {
common.error('no such file or directory: ' + baseDir, true);
return; // skip dir
}
if (options.fullpath)
mkdirSyncRecursive(dir);
else
fs.mkdirSync(dir, parseInt('0777', 8));
});
} // mkdir
module.exports = _mkdir;

80
bin/node_modules/shelljs/src/mv.js generated vendored Normal file
View File

@ -0,0 +1,80 @@
var fs = require('fs');
var path = require('path');
var common = require('./common');
//@
//@ ### mv(source [, source ...], dest')
//@ ### mv(source_array, dest')
//@ Available options:
//@
//@ + `f`: force
//@
//@ Examples:
//@
//@ ```javascript
//@ mv('-f', 'file', 'dir/');
//@ mv('file1', 'file2', 'dir/');
//@ mv(['file1', 'file2'], 'dir/'); // same as above
//@ ```
//@
//@ Moves files. The wildcard `*` is accepted.
function _mv(options, sources, dest) {
options = common.parseOptions(options, {
'f': 'force'
});
// Get sources, dest
if (arguments.length < 3) {
common.error('missing <source> and/or <dest>');
} else if (arguments.length > 3) {
sources = [].slice.call(arguments, 1, arguments.length - 1);
dest = arguments[arguments.length - 1];
} else if (typeof sources === 'string') {
sources = [sources];
} else if ('length' in sources) {
sources = sources; // no-op for array
} else {
common.error('invalid arguments');
}
sources = common.expand(sources);
var exists = fs.existsSync(dest),
stats = exists && fs.statSync(dest);
// Dest is not existing dir, but multiple sources given
if ((!exists || !stats.isDirectory()) && sources.length > 1)
common.error('dest is not a directory (too many sources)');
// Dest is an existing file, but no -f given
if (exists && stats.isFile() && !options.force)
common.error('dest file already exists: ' + dest);
sources.forEach(function(src) {
if (!fs.existsSync(src)) {
common.error('no such file or directory: '+src, true);
return; // skip file
}
// If here, src exists
// When copying to '/path/dir':
// thisDest = '/path/dir/file1'
var thisDest = dest;
if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
thisDest = path.normalize(dest + '/' + path.basename(src));
if (fs.existsSync(thisDest) && !options.force) {
common.error('dest file already exists: ' + thisDest, true);
return; // skip file
}
if (path.resolve(src) === path.dirname(path.resolve(thisDest))) {
common.error('cannot move to self: '+src, true);
return; // skip file
}
fs.renameSync(src, thisDest);
}); // forEach(src)
} // mv
module.exports = _mv;

1
bin/node_modules/shelljs/src/popd.js generated vendored Normal file
View File

@ -0,0 +1 @@
// see dirs.js

1
bin/node_modules/shelljs/src/pushd.js generated vendored Normal file
View File

@ -0,0 +1 @@
// see dirs.js

11
bin/node_modules/shelljs/src/pwd.js generated vendored Normal file
View File

@ -0,0 +1,11 @@
var path = require('path');
var common = require('./common');
//@
//@ ### pwd()
//@ Returns the current directory.
function _pwd(options) {
var pwd = path.resolve(process.cwd());
return common.ShellString(pwd);
}
module.exports = _pwd;

145
bin/node_modules/shelljs/src/rm.js generated vendored Normal file
View File

@ -0,0 +1,145 @@
var common = require('./common');
var fs = require('fs');
// Recursively removes 'dir'
// Adapted from https://github.com/ryanmcgrath/wrench-js
//
// Copyright (c) 2010 Ryan McGrath
// Copyright (c) 2012 Artur Adib
//
// Licensed under the MIT License
// http://www.opensource.org/licenses/mit-license.php
function rmdirSyncRecursive(dir, force) {
var files;
files = fs.readdirSync(dir);
// Loop through and delete everything in the sub-tree after checking it
for(var i = 0; i < files.length; i++) {
var file = dir + "/" + files[i],
currFile = fs.lstatSync(file);
if(currFile.isDirectory()) { // Recursive function back to the beginning
rmdirSyncRecursive(file, force);
}
else if(currFile.isSymbolicLink()) { // Unlink symlinks
if (force || isWriteable(file)) {
try {
common.unlinkSync(file);
} catch (e) {
common.error('could not remove file (code '+e.code+'): ' + file, true);
}
}
}
else // Assume it's a file - perhaps a try/catch belongs here?
if (force || isWriteable(file)) {
try {
common.unlinkSync(file);
} catch (e) {
common.error('could not remove file (code '+e.code+'): ' + file, true);
}
}
}
// Now that we know everything in the sub-tree has been deleted, we can delete the main directory.
// Huzzah for the shopkeep.
var result;
try {
result = fs.rmdirSync(dir);
} catch(e) {
common.error('could not remove directory (code '+e.code+'): ' + dir, true);
}
return result;
} // rmdirSyncRecursive
// Hack to determine if file has write permissions for current user
// Avoids having to check user, group, etc, but it's probably slow
function isWriteable(file) {
var writePermission = true;
try {
var __fd = fs.openSync(file, 'a');
fs.closeSync(__fd);
} catch(e) {
writePermission = false;
}
return writePermission;
}
//@
//@ ### rm([options ,] file [, file ...])
//@ ### rm([options ,] file_array)
//@ Available options:
//@
//@ + `-f`: force
//@ + `-r, -R`: recursive
//@
//@ Examples:
//@
//@ ```javascript
//@ rm('-rf', '/tmp/*');
//@ rm('some_file.txt', 'another_file.txt');
//@ rm(['some_file.txt', 'another_file.txt']); // same as above
//@ ```
//@
//@ Removes files. The wildcard `*` is accepted.
function _rm(options, files) {
options = common.parseOptions(options, {
'f': 'force',
'r': 'recursive',
'R': 'recursive'
});
if (!files)
common.error('no paths given');
if (typeof files === 'string')
files = [].slice.call(arguments, 1);
// if it's array leave it as it is
files = common.expand(files);
files.forEach(function(file) {
if (!fs.existsSync(file)) {
// Path does not exist, no force flag given
if (!options.force)
common.error('no such file or directory: '+file, true);
return; // skip file
}
// If here, path exists
var stats = fs.lstatSync(file);
if (stats.isFile() || stats.isSymbolicLink()) {
// Do not check for file writing permissions
if (options.force) {
common.unlinkSync(file);
return;
}
if (isWriteable(file))
common.unlinkSync(file);
else
common.error('permission denied: '+file, true);
return;
} // simple file
// Path is an existing directory, but no -r flag given
if (stats.isDirectory() && !options.recursive) {
common.error('path is a directory', true);
return; // skip path
}
// Recursively remove existing directory
if (stats.isDirectory() && options.recursive) {
rmdirSyncRecursive(file, options.force);
}
}); // forEach(file)
} // rm
module.exports = _rm;

43
bin/node_modules/shelljs/src/sed.js generated vendored Normal file
View File

@ -0,0 +1,43 @@
var common = require('./common');
var fs = require('fs');
//@
//@ ### sed([options ,] search_regex, replace_str, file)
//@ Available options:
//@
//@ + `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_
//@
//@ Examples:
//@
//@ ```javascript
//@ sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
//@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
//@ ```
//@
//@ Reads an input string from `file` and performs a JavaScript `replace()` on the input
//@ using the given search regex and replacement string. Returns the new string after replacement.
function _sed(options, regex, replacement, file) {
options = common.parseOptions(options, {
'i': 'inplace'
});
if (typeof replacement === 'string')
replacement = replacement; // no-op
else if (typeof replacement === 'number')
replacement = replacement.toString(); // fallback
else
common.error('invalid replacement string');
if (!file)
common.error('no file given');
if (!fs.existsSync(file))
common.error('no such file or directory: ' + file);
var result = fs.readFileSync(file, 'utf8').replace(regex, replacement);
if (options.inplace)
fs.writeFileSync(file, result, 'utf8');
return common.ShellString(result);
}
module.exports = _sed;

56
bin/node_modules/shelljs/src/tempdir.js generated vendored Normal file
View File

@ -0,0 +1,56 @@
var common = require('./common');
var os = require('os');
var fs = require('fs');
// Returns false if 'dir' is not a writeable directory, 'dir' otherwise
function writeableDir(dir) {
if (!dir || !fs.existsSync(dir))
return false;
if (!fs.statSync(dir).isDirectory())
return false;
var testFile = dir+'/'+common.randomFileName();
try {
fs.writeFileSync(testFile, ' ');
common.unlinkSync(testFile);
return dir;
} catch (e) {
return false;
}
}
//@
//@ ### tempdir()
//@
//@ Examples:
//@
//@ ```javascript
//@ var tmp = tempdir(); // "/tmp" for most *nix platforms
//@ ```
//@
//@ Searches and returns string containing a writeable, platform-dependent temporary directory.
//@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
function _tempDir() {
var state = common.state;
if (state.tempDir)
return state.tempDir; // from cache
state.tempDir = writeableDir(os.tempDir && os.tempDir()) || // node 0.8+
writeableDir(process.env['TMPDIR']) ||
writeableDir(process.env['TEMP']) ||
writeableDir(process.env['TMP']) ||
writeableDir(process.env['Wimp$ScrapDir']) || // RiscOS
writeableDir('C:\\TEMP') || // Windows
writeableDir('C:\\TMP') || // Windows
writeableDir('\\TEMP') || // Windows
writeableDir('\\TMP') || // Windows
writeableDir('/tmp') ||
writeableDir('/var/tmp') ||
writeableDir('/usr/tmp') ||
writeableDir('.'); // last resort
return state.tempDir;
}
module.exports = _tempDir;

85
bin/node_modules/shelljs/src/test.js generated vendored Normal file
View File

@ -0,0 +1,85 @@
var common = require('./common');
var fs = require('fs');
//@
//@ ### test(expression)
//@ Available expression primaries:
//@
//@ + `'-b', 'path'`: true if path is a block device
//@ + `'-c', 'path'`: true if path is a character device
//@ + `'-d', 'path'`: true if path is a directory
//@ + `'-e', 'path'`: true if path exists
//@ + `'-f', 'path'`: true if path is a regular file
//@ + `'-L', 'path'`: true if path is a symboilc link
//@ + `'-p', 'path'`: true if path is a pipe (FIFO)
//@ + `'-S', 'path'`: true if path is a socket
//@
//@ Examples:
//@
//@ ```javascript
//@ if (test('-d', path)) { /* do something with dir */ };
//@ if (!test('-f', path)) continue; // skip if it's a regular file
//@ ```
//@
//@ Evaluates expression using the available primaries and returns corresponding value.
function _test(options, path) {
if (!path)
common.error('no path given');
// hack - only works with unary primaries
options = common.parseOptions(options, {
'b': 'block',
'c': 'character',
'd': 'directory',
'e': 'exists',
'f': 'file',
'L': 'link',
'p': 'pipe',
'S': 'socket'
});
var canInterpret = false;
for (var key in options)
if (options[key] === true) {
canInterpret = true;
break;
}
if (!canInterpret)
common.error('could not interpret expression');
if (options.link) {
try {
return fs.lstatSync(path).isSymbolicLink();
} catch(e) {
return false;
}
}
if (!fs.existsSync(path))
return false;
if (options.exists)
return true;
var stats = fs.statSync(path);
if (options.block)
return stats.isBlockDevice();
if (options.character)
return stats.isCharacterDevice();
if (options.directory)
return stats.isDirectory();
if (options.file)
return stats.isFile();
if (options.pipe)
return stats.isFIFO();
if (options.socket)
return stats.isSocket();
} // test
module.exports = _test;

29
bin/node_modules/shelljs/src/to.js generated vendored Normal file
View File

@ -0,0 +1,29 @@
var common = require('./common');
var fs = require('fs');
var path = require('path');
//@
//@ ### 'string'.to(file)
//@
//@ Examples:
//@
//@ ```javascript
//@ cat('input.txt').to('output.txt');
//@ ```
//@
//@ Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as
//@ those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_
function _to(options, file) {
if (!file)
common.error('wrong arguments');
if (!fs.existsSync( path.dirname(file) ))
common.error('no such file or directory: ' + path.dirname(file));
try {
fs.writeFileSync(file, this.toString(), 'utf8');
} catch(e) {
common.error('could not write to file (code '+e.code+'): '+file, true);
}
}
module.exports = _to;

29
bin/node_modules/shelljs/src/toEnd.js generated vendored Normal file
View File

@ -0,0 +1,29 @@
var common = require('./common');
var fs = require('fs');
var path = require('path');
//@
//@ ### 'string'.toEnd(file)
//@
//@ Examples:
//@
//@ ```javascript
//@ cat('input.txt').toEnd('output.txt');
//@ ```
//@
//@ Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaScript strings (such as
//@ those returned by `cat`, `grep`, etc).
function _toEnd(options, file) {
if (!file)
common.error('wrong arguments');
if (!fs.existsSync( path.dirname(file) ))
common.error('no such file or directory: ' + path.dirname(file));
try {
fs.appendFileSync(file, this.toString(), 'utf8');
} catch(e) {
common.error('could not append to file (code '+e.code+'): '+file, true);
}
}
module.exports = _toEnd;

79
bin/node_modules/shelljs/src/which.js generated vendored Normal file
View File

@ -0,0 +1,79 @@
var common = require('./common');
var fs = require('fs');
var path = require('path');
// Cross-platform method for splitting environment PATH variables
function splitPath(p) {
for (i=1;i<2;i++) {}
if (!p)
return [];
if (common.platform === 'win')
return p.split(';');
else
return p.split(':');
}
//@
//@ ### which(command)
//@
//@ Examples:
//@
//@ ```javascript
//@ var nodeExec = which('node');
//@ ```
//@
//@ Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.
//@ Returns string containing the absolute path to the command.
function _which(options, cmd) {
if (!cmd)
common.error('must specify command');
var pathEnv = process.env.path || process.env.Path || process.env.PATH,
pathArray = splitPath(pathEnv),
where = null;
// No relative/absolute paths provided?
if (cmd.search(/\//) === -1) {
// Search for command in PATH
pathArray.forEach(function(dir) {
if (where)
return; // already found it
var attempt = path.resolve(dir + '/' + cmd);
if (fs.existsSync(attempt)) {
where = attempt;
return;
}
if (common.platform === 'win') {
var baseAttempt = attempt;
attempt = baseAttempt + '.exe';
if (fs.existsSync(attempt)) {
where = attempt;
return;
}
attempt = baseAttempt + '.cmd';
if (fs.existsSync(attempt)) {
where = attempt;
return;
}
attempt = baseAttempt + '.bat';
if (fs.existsSync(attempt)) {
where = attempt;
return;
}
} // if 'win'
});
}
// Command not found anywhere?
if (!fs.existsSync(cmd) && !where)
return null;
where = where || path.resolve(cmd);
return common.ShellString(where);
}
module.exports = _which;

23
bin/node_modules/which/LICENSE generated vendored Normal file
View File

@ -0,0 +1,23 @@
Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
All rights reserved.
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.

5
bin/node_modules/which/README.md generated vendored Normal file
View File

@ -0,0 +1,5 @@
The "which" util from npm's guts.
Finds the first instance of a specified executable in the PATH
environment variable. Does not cache the results, so `hash -r` is not
needed when the PATH changes.

14
bin/node_modules/which/bin/which generated vendored Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env node
var which = require("../")
if (process.argv.length < 3) {
console.error("Usage: which <thing>")
process.exit(1)
}
which(process.argv[2], function (er, thing) {
if (er) {
console.error(er.message)
process.exit(er.errno || 127)
}
console.log(thing)
})

31
bin/node_modules/which/package.json generated vendored Normal file
View File

@ -0,0 +1,31 @@
{
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me"
},
"name": "which",
"description": "Like which(1) unix command. Find the first instance of an executable in the PATH.",
"version": "1.0.5",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-which.git"
},
"main": "which.js",
"bin": {
"which": "./bin/which"
},
"engines": {
"node": "*"
},
"dependencies": {},
"devDependencies": {},
"readme": "The \"which\" util from npm's guts.\n\nFinds the first instance of a specified executable in the PATH\nenvironment variable. Does not cache the results, so `hash -r` is not\nneeded when the PATH changes.\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/isaacs/node-which/issues"
},
"homepage": "https://github.com/isaacs/node-which",
"_id": "which@1.0.5",
"_from": "which@"
}

104
bin/node_modules/which/which.js generated vendored Normal file
View File

@ -0,0 +1,104 @@
module.exports = which
which.sync = whichSync
var path = require("path")
, fs
, COLON = process.platform === "win32" ? ";" : ":"
, isExe
try {
fs = require("graceful-fs")
} catch (ex) {
fs = require("fs")
}
if (process.platform == "win32") {
// On windows, there is no good way to check that a file is executable
isExe = function isExe () { return true }
} else {
isExe = function isExe (mod, uid, gid) {
//console.error(mod, uid, gid);
//console.error("isExe?", (mod & 0111).toString(8))
var ret = (mod & 0001)
|| (mod & 0010) && process.getgid && gid === process.getgid()
|| (mod & 0100) && process.getuid && uid === process.getuid()
//console.error("isExe?", ret)
return ret
}
}
function which (cmd, cb) {
if (isAbsolute(cmd)) return cb(null, cmd)
var pathEnv = (process.env.PATH || "").split(COLON)
, pathExt = [""]
if (process.platform === "win32") {
pathEnv.push(process.cwd())
pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
if (cmd.indexOf(".") !== -1) pathExt.unshift("")
}
//console.error("pathEnv", pathEnv)
;(function F (i, l) {
if (i === l) return cb(new Error("not found: "+cmd))
var p = path.resolve(pathEnv[i], cmd)
;(function E (ii, ll) {
if (ii === ll) return F(i + 1, l)
var ext = pathExt[ii]
//console.error(p + ext)
fs.stat(p + ext, function (er, stat) {
if (!er &&
stat &&
stat.isFile() &&
isExe(stat.mode, stat.uid, stat.gid)) {
//console.error("yes, exe!", p + ext)
return cb(null, p + ext)
}
return E(ii + 1, ll)
})
})(0, pathExt.length)
})(0, pathEnv.length)
}
function whichSync (cmd) {
if (isAbsolute(cmd)) return cmd
var pathEnv = (process.env.PATH || "").split(COLON)
, pathExt = [""]
if (process.platform === "win32") {
pathEnv.push(process.cwd())
pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
if (cmd.indexOf(".") !== -1) pathExt.unshift("")
}
for (var i = 0, l = pathEnv.length; i < l; i ++) {
var p = path.join(pathEnv[i], cmd)
for (var j = 0, ll = pathExt.length; j < ll; j ++) {
var cur = p + pathExt[j]
var stat
try { stat = fs.statSync(cur) } catch (ex) {}
if (stat &&
stat.isFile() &&
isExe(stat.mode, stat.uid, stat.gid)) return cur
}
}
throw new Error("not found: "+cmd)
}
var isAbsolute = process.platform === "win32" ? absWin : absUnix
function absWin (p) {
if (absUnix(p)) return true
// pull off the device/UNC bit from a windows path.
// from node's lib/path.js
var splitDeviceRe =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?/
, result = splitDeviceRe.exec(p)
, device = result[1] || ''
, isUnc = device && device.charAt(1) !== ':'
, isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
return isAbsolute
}
function absUnix (p) {
return p.charAt(0) === "/" || p === ""
}

41
bin/templates/cordova/build Executable file
View File

@ -0,0 +1,41 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var build = require('./lib/build'),
reqs = require('./lib/check_reqs'),
args = process.argv;
// Support basic help commands
if(args[2] == '--help' ||
args[2] == '/?' ||
args[2] == '-h' ||
args[2] == 'help' ||
args[2] == '-help' ||
args[2] == '/help') {
build.help();
} else {
reqs.run().done(function() {
return build.run(args.slice(2));
}, function(err) {
console.error(err);
process.exit(2);
});
}

View File

@ -0,0 +1,26 @@
:: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations
:: under the License.
@ECHO OFF
SET script_path="%~dp0build"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'build' script in 'cordova' folder, aborting...>&2
EXIT /B 1
)

44
bin/templates/cordova/clean Executable file
View File

@ -0,0 +1,44 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var build = require('./lib/build'),
reqs = require('./lib/check_reqs'),
args = process.argv;
var path = require('path');
// Support basic help commands
if(args[2] == '--help' ||
args[2] == '/?' ||
args[2] == '-h' ||
args[2] == 'help' ||
args[2] == '-help' ||
args[2] == '/help') {
console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]));
console.log('Cleans the project directory.');
process.exit(0);
} else {
reqs.run().done(function() {
return build.runClean(args.slice(2));
}, function(err) {
console.error(err);
process.exit(2);
});
}

View File

@ -0,0 +1,26 @@
:: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations
:: under the License.
@ECHO OFF
SET script_path="%~dp0clean"
IF EXIST %script_path% (
node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'clean' script in 'cordova' folder, aborting...>&2
EXIT /B 1
)

41
bin/templates/cordova/lib/appinfo.js vendored Normal file
View File

@ -0,0 +1,41 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var path = require('path');
var fs = require('fs');
var cachedAppInfo = null;
function readAppInfoFromManifest() {
var manifestPath = path.join(__dirname, '..', '..', 'AndroidManifest.xml');
var manifestData = fs.readFileSync(manifestPath, {encoding:'utf8'});
var packageName = /\bpackage\s*=\s*"(.+?)"/.exec(manifestData);
if (!packageName) throw new Error('Could not find package name within ' + manifestPath);
var activityTag = /<activity\b[\s\S]*<\/activity>/.exec(manifestData);
if (!activityTag) throw new Error('Could not find <activity> within ' + manifestPath);
var activityName = /\bandroid:name\s*=\s*"(.+?)"/.exec(activityTag);
if (!activityName) throw new Error('Could not find android:name within ' + manifestPath);
return packageName[1] + '/.' + activityName[1];
}
exports.getActivityName = function() {
return cachedAppInfo = cachedAppInfo || readAppInfoFromManifest();
};

402
bin/templates/cordova/lib/build.js vendored Normal file
View File

@ -0,0 +1,402 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var shell = require('shelljs'),
spawn = require('./spawn'),
Q = require('q'),
path = require('path'),
fs = require('fs'),
ROOT = path.join(__dirname, '..', '..');
var check_reqs = require('./check_reqs');
var exec = require('./exec');
var LOCAL_PROPERTIES_TEMPLATE =
'# This file is automatically generated.\n' +
'# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n';
function find_files(directory, predicate) {
if (fs.existsSync(directory)) {
var candidates = fs.readdirSync(directory).filter(predicate).map(function(p) {
p = path.join(directory, p);
return { p: p, t: fs.statSync(p).mtime };
}).sort(function(a,b) {
var timeDiff = b.t - a.t;
if (timeDiff === 0) {
return a.p.length - b.p.length;
}
return timeDiff;
}).map(function(p) { return p.p; });
return candidates;
} else {
console.error('ERROR : unable to find project ' + directory + ' directory, could not locate .apk');
process.exit(2);
}
}
function hasCustomRules() {
return fs.existsSync(path.join(ROOT, 'custom_rules.xml'));
}
function extractProjectNameFromManifest(projectPath) {
var manifestPath = path.join(projectPath, 'AndroidManifest.xml');
var manifestData = fs.readFileSync(manifestPath, 'utf8');
var m = /<activity[\s\S]*?android:name\s*=\s*"(.*?)"/i.exec(manifestData);
if (!m) {
throw new Error('Could not find activity name in ' + manifestPath);
}
return m[1];
}
function extractSubProjectPaths() {
var data = fs.readFileSync(path.join(ROOT, 'project.properties'), 'utf8');
var ret = {};
var r = /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg
var m;
while (m = r.exec(data)) {
ret[m[1]] = 1;
}
return Object.keys(ret);
}
var builders = {
ant: {
getArgs: function(cmd) {
var args = [cmd, '-f', path.join(ROOT, 'build.xml')];
// custom_rules.xml is required for incremental builds.
if (hasCustomRules()) {
args.push('-Dout.dir=ant-build', '-Dgen.absolute.dir=ant-gen');
}
return args;
},
prepEnv: function() {
return check_reqs.check_ant()
.then(function() {
// Copy in build.xml on each build so that:
// A) we don't require the Android SDK at project creation time, and
// B) we always use the SDK's latest version of it.
var sdkDir = process.env['ANDROID_HOME'];
var buildTemplate = fs.readFileSync(path.join(sdkDir, 'tools', 'lib', 'build.template'), 'utf8');
function writeBuildXml(projectPath) {
var newData = buildTemplate.replace('PROJECT_NAME', extractProjectNameFromManifest(ROOT));
fs.writeFileSync(path.join(projectPath, 'build.xml'), newData);
if (!fs.existsSync(path.join(projectPath, 'local.properties'))) {
fs.writeFileSync(path.join(projectPath, 'local.properties'), LOCAL_PROPERTIES_TEMPLATE);
}
}
var subProjects = extractSubProjectPaths();
writeBuildXml(ROOT);
for (var i = 0; i < subProjects.length; ++i) {
writeBuildXml(path.join(ROOT, subProjects[i]));
}
});
},
/*
* Builds the project with ant.
* Returns a promise.
*/
build: function(build_type) {
// Without our custom_rules.xml, we need to clean before building.
var ret = Q();
if (!hasCustomRules()) {
// clean will call check_ant() for us.
ret = this.clean();
}
var builder = this;
var args = this.getArgs(build_type == 'debug' ? 'debug' : 'release');
return check_reqs.check_ant()
.then(function() {
return spawn('ant', args);
}).then(function() {
return builder.getOutputFiles();
});
},
clean: function() {
var args = this.getArgs('clean');
return check_reqs.check_ant()
.then(function() {
return spawn('ant', args);
});
},
// Find the recently-generated output APK files
// Ant only generates one output file; return it.
getOutputFiles: function() {
var binDir;
if(hasCustomRules()) {
binDir = path.join(ROOT, 'ant-build');
} else {
binDir = path.join(ROOT, 'bin');
}
var candidates = find_files(binDir, function(candidate) { return path.extname(candidate) == '.apk'; });
if (candidates.length === 0) {
console.error('ERROR : No .apk found in ' + binDir + ' directory');
process.exit(2);
}
var ret = candidates[0];
return [ret];
}
},
gradle: {
getArgs: function(cmd) {
var lintSteps;
if (process.env['BUILD_MULTIPLE_APKS']) {
lintSteps = [
'lint',
'lintVitalX86Release',
'lintVitalArmv7Release',
'compileLint',
'copyReleaseLint',
'copyDebugLint'
];
} else {
lintSteps = [
'lint',
'lintVitalRelease',
'compileLint',
'copyReleaseLint',
'copyDebugLint'
];
}
if (cmd == 'debug') {
cmd = 'assembleDebug';
} else if (cmd == 'release') {
cmd = 'assembleRelease';
}
var args = [cmd, '-b', path.join(ROOT, 'build.gradle')];
// 10 seconds -> 6 seconds
args.push('-Dorg.gradle.daemon=true');
// Excluding lint: 6s-> 1.6s
for (var i = 0; i < lintSteps.length; ++i) {
args.push('-x', lintSteps[i]);
}
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
// args.push('-Dorg.gradle.parallel=true');
return args;
},
prepEnv: function() {
return check_reqs.check_gradle()
.then(function() {
// Copy the gradle wrapper on each build so that:
// A) we don't require the Android SDK at project creation time, and
// B) we always use the SDK's latest version of it.
var projectPath = ROOT;
// check_reqs ensures that this is set.
var sdkDir = process.env['ANDROID_HOME'];
var wrapperDir = path.join(sdkDir, 'tools', 'templates', 'gradle', 'wrapper');
if (process.platform == 'win32') {
shell.cp('-f', path.join(wrapperDir, 'gradlew.bat'), projectPath);
} else {
shell.cp('-f', path.join(wrapperDir, 'gradlew'), projectPath);
}
shell.rm('-rf', path.join(projectPath, 'gradle', 'wrapper'));
shell.mkdir('-p', path.join(projectPath, 'gradle'));
shell.cp('-r', path.join(wrapperDir, 'gradle', 'wrapper'), path.join(projectPath, 'gradle'));
// If the gradle distribution URL is set, make sure it points to version 1.12.
// If it's not set, do nothing, assuming that we're using a future version of gradle that we don't want to mess with.
// For some reason, using ^ and $ don't work. This does the job, though.
var distributionUrlRegex = /distributionUrl.*zip/;
var distributionUrl = 'distributionUrl=http\\://services.gradle.org/distributions/gradle-1.12-all.zip';
var gradleWrapperPropertiesPath = path.join(projectPath, 'gradle', 'wrapper', 'gradle-wrapper.properties');
shell.sed('-i', distributionUrlRegex, distributionUrl, gradleWrapperPropertiesPath);
});
},
/*
* Builds the project with gradle.
* Returns a promise.
*/
build: function(build_type) {
var builder = this;
var wrapper = path.join(ROOT, 'gradlew');
var args = this.getArgs(build_type == 'debug' ? 'debug' : 'release');
return Q().then(function() {
return spawn(wrapper, args);
}).then(function() {
return builder.getOutputFiles(build_type);
});
},
clean: function() {
var builder = this;
var wrapper = path.join(ROOT, 'gradlew');
var args = builder.getArgs('clean');
return Q().then(function() {
return spawn(wrapper, args);
});
},
// Find the recently-generated output APK files
// Gradle can generate multiple output files; return all of them.
getOutputFiles: function(build_type) {
var binDir = path.join(ROOT, 'build', 'outputs', 'apk');
var candidates = find_files(binDir, function(candidate) {
// Need to choose between release and debug .apk.
if (build_type === 'debug') {
return (path.extname(candidate) == '.apk' && candidate.indexOf('-debug') >= 0);
}
if (build_type === 'release') {
return (path.extname(candidate) == '.apk' && candidate.indexOf('-release') >= 0);
}
return path.extname(candidate) == '.apk';
});
return candidates;
}
},
none: {
prepEnv: function() {
return Q();
},
build: function() {
console.log('Skipping build...');
return Q();
},
clean: function() {
return Q();
},
}
};
function parseOpts(options) {
// Backwards-compatibility: Allow a single string argument
if (typeof options == "string") options = [options];
var ret = {
buildType: 'debug',
buildMethod: process.env['ANDROID_BUILD'] || 'ant'
};
// Iterate through command line options
for (var i=0; options && (i < options.length); ++i) {
if (options[i].substring && options[i].substring(0,2) == "--") {
var option = options[i].substring(2);
switch(option) {
case 'debug':
case 'release':
ret.buildType = option;
break;
case 'ant':
case 'gradle':
ret.buildMethod = option;
break;
case 'nobuild' :
ret.buildMethod = 'none';
break;
default :
return Q.reject('Build option \'' + options[i] + '\' not recognized.');
}
} else {
return Q.reject('Build option \'' + options[i] + '\' not recognized.');
}
}
return ret;
}
/*
* Builds the project with the specifed options
* Returns a promise.
*/
module.exports.runClean = function(options) {
var opts = parseOpts(options);
var builder = builders[opts.buildMethod];
return builder.prepEnv()
.then(function() {
return builder.clean();
}).then(function() {
shell.rm('-rf', path.join(ROOT, 'out'));
});
};
/*
* Builds the project with the specifed options
* Returns a promise.
*/
module.exports.run = function(options) {
var opts = parseOpts(options);
var builder = builders[opts.buildMethod];
return builder.prepEnv()
.then(function() {
return builder.build(opts.buildType);
}).then(function(apkFiles) {
// TODO: Rather than copy apks to out, it might be better to
// just write out what the last .apk build was. These files
// are used by get_apk().
var outputDir = path.join(ROOT, 'out');
shell.mkdir('-p', outputDir);
var builtApks = [];
for (var i=0; i < apkFiles.length; ++i) {
var dst = path.join(outputDir, path.basename(apkFiles[i]));
builtApks.push(dst);
shell.cp('-f', apkFiles[i], dst);
}
console.log('Built the following APKs:\n' + builtApks.join('\n'));
return builtApks;
});
};
/*
* Detects the architecture of a device/emulator
* Returns "arm" or "x86".
*/
module.exports.detectArchitecture = function(target) {
return exec('adb -s ' + target + ' shell cat /proc/cpuinfo')
.then(function(output) {
if (/intel/i.exec(output)) {
return 'x86';
}
return 'arm';
});
};
/*
* Gets the path to the apk file, if not such file exists then
* the script will error out. (should we error or just return undefined?)
* This is called by the run script to install the apk to the device
*/
module.exports.get_apk = function(build_type, architecture) {
var outputDir = path.join(ROOT, 'out');
var candidates = find_files(outputDir, function(filename) { return (!architecture) || filename.indexOf(architecture) >= 0; });
if (candidates.length === 0) {
console.error('ERROR : No .apk found in ' + outputDir + ' directory');
process.exit(2);
}
// TODO: Use build_type here.
console.log('Using apk: ' + candidates[0]);
return candidates[0];
};
module.exports.help = function() {
console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'build')) + ' [build_type]');
console.log('Build Types : ');
console.log(' \'--debug\': Default build, will build project in debug mode');
console.log(' \'--release\': will build project for release');
console.log(' \'--ant\': Default build, will build project with ant');
console.log(' \'--gradle\': will build project with gradle');
console.log(' \'--nobuild\': will skip build process (can be used with run command)');
process.exit(0);
};

90
bin/templates/cordova/lib/device.js vendored Normal file
View File

@ -0,0 +1,90 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var exec = require('./exec'),
Q = require('q'),
path = require('path'),
build = require('./build'),
appinfo = require('./appinfo'),
ROOT = path.join(__dirname, '..', '..');
/**
* Returns a promise for the list of the device ID's found
*/
module.exports.list = function() {
return exec('adb devices')
.then(function(output) {
var response = output.split('\n');
var device_list = [];
for (var i = 1; i < response.length; i++) {
if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) {
device_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
}
}
return device_list;
});
}
/*
* Installs a previously built application on the device
* and launches it.
* Returns a promise.
*/
module.exports.install = function(target) {
var launchName;
return this.list()
.then(function(device_list) {
if (!device_list || !device_list.length)
return Q.reject('ERROR: Failed to deploy to device, no devices found.');
// default device
target = typeof target !== 'undefined' ? target : device_list[0];
if (device_list.indexOf(target) < 0) {
return Q.reject('ERROR: Unable to find target \'' + target + '\'.');
}
return build.detectArchitecture(target)
.then(function(arch) {
var apk_path = build.get_apk(null, arch);
launchName = appinfo.getActivityName();
console.log('Installing app on device...');
var cmd = 'adb -s ' + target + ' install -r "' + apk_path + '"';
return exec(cmd);
});
}).then(function(output) {
if (output.match(/Failure/)) return Q.reject('ERROR: Failed to install apk to device: ' + output);
//unlock screen
var cmd = 'adb -s ' + target + ' shell input keyevent 82';
return exec(cmd);
}, function(err) { return Q.reject('ERROR: Failed to install apk to device: ' + err); })
.then(function() {
// launch the application
console.log('Launching application...');
var cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
return exec(cmd);
}).then(function() {
console.log('LAUNCH SUCCESS');
}, function(err) {
return Q.reject('ERROR: Failed to launch application on device: ' + err);
});
}

323
bin/templates/cordova/lib/emulator.js vendored Normal file
View File

@ -0,0 +1,323 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var shell = require('shelljs'),
exec = require('./exec'),
Q = require('q'),
path = require('path'),
appinfo = require('./appinfo'),
build = require('./build'),
ROOT = path.join(__dirname, '..', '..'),
child_process = require('child_process'),
new_emulator = 'cordova_emulator';
var check_reqs = require('./check_reqs');
/**
* Returns a Promise for a list of emulator images in the form of objects
* {
name : <emulator_name>,
path : <path_to_emulator_image>,
target : <api_target>,
abi : <cpu>,
skin : <skin>
}
*/
module.exports.list_images = function() {
return exec('android list avds')
.then(function(output) {
var response = output.split('\n');
var emulator_list = [];
for (var i = 1; i < response.length; i++) {
// To return more detailed information use img_obj
var img_obj = {};
if (response[i].match(/Name:\s/)) {
img_obj['name'] = response[i].split('Name: ')[1].replace('\r', '');
if (response[i + 1].match(/Path:\s/)) {
i++;
img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
}
if (response[i + 1].match(/\(API\slevel\s/)) {
i++;
img_obj['target'] = response[i].replace('\r', '');
}
if (response[i + 1].match(/ABI:\s/)) {
i++;
img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
}
if (response[i + 1].match(/Skin:\s/)) {
i++;
img_obj['skin'] = response[i].split('Skin: ')[1].replace('\r', '');
}
emulator_list.push(img_obj);
}
/* To just return a list of names use this
if (response[i].match(/Name:\s/)) {
emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
}*/
}
return emulator_list;
});
}
/**
* Will return the closest avd to the projects target
* or undefined if no avds exist.
* Returns a promise.
*/
module.exports.best_image = function() {
var project_target = check_reqs.get_target().replace('android-', '');
return this.list_images()
.then(function(images) {
var closest = 9999;
var best = images[0];
for (i in images) {
var target = images[i].target;
if(target) {
var num = target.split('(API level ')[1].replace(')', '');
if (num == project_target) {
return images[i];
} else if (project_target - num < closest && project_target > num) {
var closest = project_target - num;
best = images[i];
}
}
}
return best;
});
}
// Returns a promise.
module.exports.list_started = function() {
return exec('adb devices')
.then(function(output) {
var response = output.split('\n');
var started_emulator_list = [];
for (var i = 1; i < response.length; i++) {
if (response[i].match(/device/) && response[i].match(/emulator/)) {
started_emulator_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
}
}
return started_emulator_list;
});
}
// Returns a promise.
module.exports.list_targets = function() {
return exec('android list targets')
.then(function(output) {
var target_out = output.split('\n');
var targets = [];
for (var i = target_out.length; i >= 0; i--) {
if(target_out[i].match(/id:/)) {
targets.push(targets[i].split(' ')[1]);
}
}
return targets;
});
}
/*
* Starts an emulator with the given ID,
* and returns the started ID of that emulator.
* If no ID is given it will used the first image available,
* if no image is available it will error out (maybe create one?).
*
* Returns a promise.
*/
module.exports.start = function(emulator_ID) {
var self = this;
var emulator_id, num_started, started_emulators;
return self.list_started()
.then(function(list) {
started_emulators = list;
num_started = started_emulators.length;
if (!emulator_ID) {
return self.list_images()
.then(function(emulator_list) {
if (emulator_list.length > 0) {
return self.best_image()
.then(function(best) {
emulator_ID = best.name;
console.log('WARNING : no emulator specified, defaulting to ' + emulator_ID);
return emulator_ID;
});
} else {
var androidCmd = check_reqs.getAbsoluteAndroidCmd();
return Q.reject('ERROR : No emulator images (avds) found.\n' +
'1. Download desired System Image by running: ' + androidCmd + ' sdk\n' +
'2. Create an AVD by running: ' + androidCmd + ' avd\n' +
'HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver\n');
}
});
} else {
return Q(emulator_ID);
}
}).then(function() {
var cmd = 'emulator';
var args = ['-avd', emulator_ID];
var proc = child_process.spawn(cmd, args, { stdio: 'inherit', detached: true });
proc.unref(); // Don't wait for it to finish, since the emulator will probably keep running for a long time.
}).then(function() {
// wait for emulator to start
console.log('Waiting for emulator...');
return self.wait_for_emulator(num_started);
}).then(function(new_started) {
if (new_started.length > 1) {
for (i in new_started) {
if (started_emulators.indexOf(new_started[i]) < 0) {
emulator_id = new_started[i];
}
}
} else {
emulator_id = new_started[0];
}
if (!emulator_id) return Q.reject('ERROR : Failed to start emulator, could not find new emulator');
//wait for emulator to boot up
process.stdout.write('Booting up emulator (this may take a while)...');
return self.wait_for_boot(emulator_id);
}).then(function() {
console.log('BOOT COMPLETE');
//unlock screen
return exec('adb -s ' + emulator_id + ' shell input keyevent 82');
}).then(function() {
//return the new emulator id for the started emulators
return emulator_id;
});
}
/*
* Waits for the new emulator to apear on the started-emulator list.
* Returns a promise with a list of newly started emulators' IDs.
*/
module.exports.wait_for_emulator = function(num_running) {
var self = this;
return self.list_started()
.then(function(new_started) {
if (new_started.length > num_running) {
return new_started;
} else {
return Q.delay(1000).then(function() {
return self.wait_for_emulator(num_running);
});
}
});
}
/*
* Waits for the boot animation property of the emulator to switch to 'stopped'
*/
module.exports.wait_for_boot = function(emulator_id) {
var self = this;
return exec('adb -s ' + emulator_id + ' shell getprop init.svc.bootanim')
.then(function(output) {
if (output.match(/stopped/)) {
return;
} else {
process.stdout.write('.');
return Q.delay(3000).then(function() {
return self.wait_for_boot(emulator_id);
});
}
});
}
/*
* Create avd
* TODO : Enter the stdin input required to complete the creation of an avd.
* Returns a promise.
*/
module.exports.create_image = function(name, target) {
console.log('Creating avd named ' + name);
if (target) {
return exec('android create avd --name ' + name + ' --target ' + target)
.then(null, function(error) {
console.error('ERROR : Failed to create emulator image : ');
console.error(' Do you have the latest android targets including ' + target + '?');
console.error(create.output);
});
} else {
console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
return exec('android create avd --name ' + name + ' --target ' + this.list_targets()[0])
.then(function() {
// TODO: This seems like another error case, even though it always happens.
console.error('ERROR : Unable to create an avd emulator, no targets found.');
console.error('Please insure you have targets available by running the "android" command');
return Q.reject();
}, function(error) {
console.error('ERROR : Failed to create emulator image : ');
console.error(error);
});
}
}
/*
* Installs a previously built application on the emulator and launches it.
* If no target is specified, then it picks one.
* If no started emulators are found, error out.
* Returns a promise.
*/
module.exports.install = function(target) {
var self = this;
return this.list_started()
.then(function(emulator_list) {
if (emulator_list.length < 1) {
return Q.reject('No started emulators found, please start an emultor before deploying your project.');
}
// default emulator
target = typeof target !== 'undefined' ? target : emulator_list[0];
if (emulator_list.indexOf(target) < 0) {
return Q.reject('Unable to find target \'' + target + '\'. Failed to deploy to emulator.');
}
return build.detectArchitecture(target)
.then(function(arch) {
var apk_path = build.get_apk(null, arch);
console.log('Installing app on emulator...');
return exec('adb -s ' + target + ' install -r "' + apk_path + '"');
});
}).then(function(output) {
if (output.match(/Failure/)) {
return Q.reject('Failed to install apk to emulator: ' + output);
}
return Q();
}, function(err) {
return Q.reject('Failed to install apk to emulator: ' + err);
}).then(function() {
//unlock screen
return exec('adb -s ' + target + ' shell input keyevent 82');
}).then(function() {
// launch the application
console.log('Launching application...');
var launchName = appinfo.getActivityName();
cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
return exec(cmd);
}).then(function(output) {
console.log('LAUNCH SUCCESS');
}, function(err) {
return Q.reject('Failed to launch app on emulator: ' + err);
});
}

41
bin/templates/cordova/lib/exec.js vendored Normal file
View File

@ -0,0 +1,41 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var child_process = require('child_process'),
Q = require('q');
// Takes a command and optional current working directory.
// Returns a promise that either resolves with the stdout, or
// rejects with an error message and the stderr.
module.exports = function(cmd, opt_cwd) {
var d = Q.defer();
try {
child_process.exec(cmd, {cwd: opt_cwd, maxBuffer: 1024000}, function(err, stdout, stderr) {
if (err) d.reject('Error executing "' + cmd + '": ' + stderr);
else d.resolve(stdout);
});
} catch(e) {
console.error('error caught: ' + e);
d.reject(e);
}
return d.promise;
}

View File

@ -0,0 +1,42 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var device = require('./device'),
args = process.argv;
if(args.length > 2) {
var install_target;
if (args[2].substring(0, 9) == '--target=') {
install_target = args[2].substring(9, args[2].length);
device.install(install_target).done(null, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});
} else {
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
process.exit(2);
}
} else {
device.install().done(null, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});
}

View File

@ -0,0 +1,26 @@
:: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations
:: under the License.
@ECHO OFF
SET script_path="%~dp0install-device"
IF EXIST %script_path% (
node "%script_path%" %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'install-device' script in 'cordova\lib' folder, aborting...>&2
EXIT /B 1
)

View File

@ -0,0 +1,38 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var emulator = require('./emulator'),
args = process.argv;
var install_target;
if(args.length > 2) {
if (args[2].substring(0, 9) == '--target=') {
install_target = args[2].substring(9, args[2].length);
} else {
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
process.exit(2);
}
}
emulator.install(install_target).done(null, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@ -0,0 +1,26 @@
:: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations
:: under the License.
@ECHO OFF
SET script_path="%~dp0install-emulator"
IF EXIST %script_path% (
node "%script_path%" %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'install-emulator' script in 'cordova\lib' folder, aborting...>&2
EXIT /B 1
)

View File

@ -0,0 +1,33 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var devices = require('./device');
// Usage support for when args are given
devices.list().done(function(device_list) {
device_list && device_list.forEach(function(dev) {
console.log(dev);
});
}, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

View File

@ -0,0 +1,26 @@
:: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations
:: under the License.
@ECHO OFF
SET script_path="%~dp0list-devices"
IF EXIST %script_path% (
node "%script_path%" %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'list-devices' script in 'cordova\lib' folder, aborting...>&2
EXIT /B 1
)

View File

@ -0,0 +1,32 @@
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var emulators = require('./emulator');
// Usage support for when args are given
emulators.list_images().done(function(emulator_list) {
emulator_list && emulator_list.forEach(function(emu) {
console.log(emu.name);
});
}, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});

Some files were not shown because too many files have changed in this diff Show More