From f61abf56038c21e29c8eeebdd15f47460b1b9f2f Mon Sep 17 00:00:00 2001 From: Richard King Date: Fri, 19 Aug 2016 13:50:37 +0200 Subject: [PATCH] Initial commit --- .doclets.yml | 13 + .editorconfig | 14 + .eslintrc.js | 144 +++++++++ .gitattributes | 59 ++++ .gitignore | 17 + .npmignore | 26 ++ .travis.yml | 15 + dist/js-partial-is-array.js | 92 ++++++ dist/js-partial-is-array.min.js | 2 + license.md | 16 + package.json | 59 ++++ readme.md | 97 ++++++ scripts/gulp/main.js | 17 + scripts/gulp/tasks/build/index.js | 70 +++++ scripts/gulp/tasks/bump/index.js | 147 +++++++++ scripts/gulp/tasks/ci/index.js | 26 ++ scripts/gulp/tasks/test/index.js | 153 +++++++++ scripts/gulp/vars.js | 5 + scripts/tasks/main.py | 290 ++++++++++++++++++ scripts/tasks/npm-adduser.sh | 15 + scripts/vagrant/content/home/vagrant/.bashrc | 6 + scripts/vagrant/provision.sh | 27 ++ scripts/vagrant/scripts/install_essentials.sh | 19 ++ scripts/vagrant/scripts/install_git.sh | 7 + scripts/vagrant/scripts/install_node.sh | 39 +++ scripts/vagrant/scripts/install_python.sh | 10 + src/js-partial-is-array.js | 98 ++++++ src/license-header-template.json | 3 + tests/tests.js | 66 ++++ tests/variables.js | 3 + vagrantfile | 9 + 31 files changed, 1564 insertions(+) create mode 100644 .doclets.yml create mode 100644 .editorconfig create mode 100644 .eslintrc.js create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 .travis.yml create mode 100644 dist/js-partial-is-array.js create mode 100644 dist/js-partial-is-array.min.js create mode 100644 license.md create mode 100644 package.json create mode 100644 readme.md create mode 100644 scripts/gulp/main.js create mode 100644 scripts/gulp/tasks/build/index.js create mode 100644 scripts/gulp/tasks/bump/index.js create mode 100644 scripts/gulp/tasks/ci/index.js create mode 100644 scripts/gulp/tasks/test/index.js create mode 100644 scripts/gulp/vars.js create mode 100644 scripts/tasks/main.py create mode 100644 scripts/tasks/npm-adduser.sh create mode 100644 scripts/vagrant/content/home/vagrant/.bashrc create mode 100644 scripts/vagrant/provision.sh create mode 100644 scripts/vagrant/scripts/install_essentials.sh create mode 100644 scripts/vagrant/scripts/install_git.sh create mode 100644 scripts/vagrant/scripts/install_node.sh create mode 100644 scripts/vagrant/scripts/install_python.sh create mode 100644 src/js-partial-is-array.js create mode 100644 src/license-header-template.json create mode 100644 tests/tests.js create mode 100644 tests/variables.js create mode 100644 vagrantfile diff --git a/.doclets.yml b/.doclets.yml new file mode 100644 index 0000000..9562a0b --- /dev/null +++ b/.doclets.yml @@ -0,0 +1,13 @@ +packageJson: package.json + +dir: src + +articles: + - Overview: readme.md + +branches: + - master + - develop + - feature/* + - release/* + - hotfix/* diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f167c6d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{json,yml}] +indent_size = 2 diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..4e0feef --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,144 @@ +module.exports = { + extends : [ + 'eslint:all' + ], + globals : { + 'define': true, + 'module': true, + 'require' : true, + 'console' : true, + + 'Symbol' : true, + + // typed arrays + 'Int8Array' : true, + 'Uint8Array' : true, + 'Uint8ClampedArray' : true, + 'Int16Array' : true, + 'Uint16Array' : true, + 'Int32Array' : true, + 'Uint32Array' : true, + 'Float32Array' : true, + 'Float64Array' : true + }, + 'parserOptions': { + 'ecmaVersion': 5 + }, + rules : { + 'strict': 'off', + 'padded-blocks': 'off', + 'func-names': 'off', + 'no-var' : 'off', + 'sort-vars' : 'off', + 'no-multi-spaces': 'off', + 'init-declarations': 'off', + 'prefer-arrow-callback' : 'off', + 'func-style': 'off', + 'no-plusplus': 'off', + 'no-continue': 'off', + 'no-prototype-builtins': 'off', + 'vars-on-top': 'error', + 'prefer-reflect': 'off', + 'space-unary-ops': 'off', + 'key-spacing' : 'off', + 'callback-return' : 'off', + 'no-implicit-coercion' : 'off', + 'no-negated-condition' : 'off', + 'guard-for-in' : 'off', + 'no-lonely-if' : 'off', + 'no-self-compare': 'off', + 'no-inline-comments' : 'off', + 'lines-around-comment' : 'off', + 'no-underscore-dangle': 'off', + 'no-unused-expressions': 'off', + 'one-var': 'off', + 'indent': 'off', + 'arrow-body-style' : 'off', + 'wrap-regex' : 'off', + 'prefer-spread' : 'off', + 'prefer-rest-params' : 'off', + 'no-invalid-this' : 'off', + 'newline-before-return': 'off', + 'no-console': [ + 'error', { + allow: [ + 'warn', + 'error' + ] + } + ], + 'new-cap': [ + 'error', { + 'newIsCap': false, + 'capIsNew': true, + } + ], + 'comma-dangle' : [ + 'error', 'always-multiline' + ], + 'max-params': [ + 'error', 5 + ], + 'max-lines': [ + 'error', { + 'max' : 999, + 'skipBlankLines' : true, + 'skipComments' : true + } + ], + 'quote-props': [ + 'error', + 'as-needed', { + 'keywords': false + } + ], + 'space-in-parens': 'off', + 'id-length': [ + 'error', { + 'exceptions': [ + 'i', 'j', 'p', 'n', 'x', 'y', 'w', 'e', 'h' + ] + } + ], + 'linebreak-style': [ + 'error', 'unix' + ], + 'complexity': [ + 'error', 50 + ], + 'max-statements': [ + 'error', 40 + ], + 'max-len': [ + 'error', 120, 4 + ], + 'camelcase': [ + 'error', { + 'properties': 'never' + } + ], + 'quotes' : [ + 'error', 'single', { + 'avoidEscape' : true, + 'allowTemplateLiterals' : true + } + ], + 'default-case': [ + 'error', { + 'commentPattern' : '^skip\\sdefault' + } + ], + 'no-magic-numbers': [ + 'error', { + 'ignore' : [-1, 0, 1, 2], + 'ignoreArrayIndexes' : true + } + ], + 'space-before-function-paren': [ + 'error', { + 'anonymous' : 'never', + 'named' : 'never' + } + ] + } +}; diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7f23c90 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,59 @@ +# General .gitattributes v1.0.0 + +# Auto detect text files and perform LF normalization +* text=auto +* eol=lf + +# These files are text and should be normalized (Convert crlf => lf) +*.php text +*.css text +*.scss text +*.sass text +*.js text +*.htm text +*.html text +*.xml text +*.txt text +*.ini text +*.inc text +.htaccess text + +# These files are binary and should be left untouched +# images +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.psd binary +*.ai binary + +# fonts +*.ttf binary +*.woff binary +*.woff2 binary +*.eot binary + +# documents +*.pdf binary +*.doc binary +*.docx binary + +# compressed formats +*.zip binary +*.tar binary +*.gz binary +*.rar binary +*.7z binary + +# executables +*.phar binary +*.exe binary + +# media formats +*.mov binary +*.mp4 binary +*.mp3 binary +*.flv binary +*.fla binary +*.swf binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..318f6a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# IntelliJ project directory +.idea/ + +# Vagrant VM directory +.vagrant/ + +# Node project dependencies +/node_modules/ + +# Code coverage report +/cov/ + +# Logs +/npm-debug.log + +# Required data for publishing project +/.publish.json diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..13c0ea7 --- /dev/null +++ b/.npmignore @@ -0,0 +1,26 @@ +# IntelliJ project directory +/.idea/ + +# Vagrant VM directory +/.vagrant/ + +# coverage directory (for development) +/cov/ + +# scripts directory (for development) +/scripts/ + +# source directory (for development) +/src/ + +# tests directory (for development) +/tests/ + +.doclets.yml +.editorconfig +.eslintrc.js +.gitattributes +.npmignore +.publish.json +.travis.yml +vagrantfile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ed89963 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: node_js + +node_js: + - stable + - "6" + - "6.1" + - "5" + - "5.1" + - "4" + - "4.2" + - "4.1" + - "4.0" + +script: + - npm run ci diff --git a/dist/js-partial-is-array.js b/dist/js-partial-is-array.js new file mode 100644 index 0000000..d5c5ba7 --- /dev/null +++ b/dist/js-partial-is-array.js @@ -0,0 +1,92 @@ +/* + |---------------------------------------------------------------------------------------------------------------------- + | A partial to check whether an object is an array. + |---------------------------------------------------------------------------------------------------------------------- + */ + +/** + * More information on [JavaScript Open Standards]{@link https://github.com/jsopenstd/jsopenstd}. + * + * @namespace js.partial + * @version 0.0.0 + * + * @author Richard King [GitHub]{@link https://github.com/richrdkng} + * @license [MIT]{@link https://github.com/jsopenstd/js-partial-foreach/blob/master/license.md} + */ + +/** + * UMD - [returnExports.js pattern]{@link https://github.com/umdjs/umd/blob/master/templates/returnExports.js} + * For more information and license, check the link below: + * [UMD GitHub Repository]{@link https://github.com/umdjs/umd} + */ +(function(root, factory) { + // AMD + /* istanbul ignore next: ignore coverage test for UMD */ + if (typeof define === 'function' && define.amd) { + define([], factory); + + // CommonJS + } else if (typeof module === 'object' && module.exports) { + module.exports = factory(); + + // Browser + } else { + root.js_partial_isArray = factory(); + } +}(this, function() { + 'use strict'; + + /** + * Determines whether an object is an array. + * By default it handles **typed arrays and array-likes as non-arrays**. + * + * @function isArray + * @memberOf js.partial + * + * @param {*} object - The object to check. + * @param {boolean} [handleTypedArrayAsArray=false] - Handle a typed array as a regular array too. + * By default a typed array is not classified as a regular array. + * @param {boolean} [handleArrayLikeAsArray=false] - Handle an array-like as a regular array too. + * An array-like is anything, that has a valid .length property + * and behaves as a collection, that stores values + * (e.g.: arguments, strings, objects based on arrays/objects). + * By default an array-like is not classified as a regular array. + * + * @returns {boolean} If the object is an array, it will return true. + */ + return function isArray(object, handleTypedArrayAsArray, handleArrayLikeAsArray) { + var handleTypedArray = handleTypedArrayAsArray === true, + handleArrayLike = handleArrayLikeAsArray === true; + + if (object !== null && typeof object === 'object') { + + if ( ! handleTypedArray && + ! handleArrayLike) { + + return Object.prototype.toString.call(object) === '[object Array]'; + } + + if (handleTypedArray) { + return object instanceof Int8Array || + object instanceof Uint8Array || + object instanceof Uint8ClampedArray || + object instanceof Int16Array || + object instanceof Uint16Array || + object instanceof Int32Array || + object instanceof Uint32Array || + object instanceof Float32Array || + object instanceof Float64Array; + } + + if (handleArrayLike) { + if ('length' in object && + typeof object.length === 'number') { + + return true; + } + } + } + + return false; + }; +})); diff --git a/dist/js-partial-is-array.min.js b/dist/js-partial-is-array.min.js new file mode 100644 index 0000000..a0ec52a --- /dev/null +++ b/dist/js-partial-is-array.min.js @@ -0,0 +1,2 @@ +/*! js-partial-is-array v0.0.0 | MIT License | (c) Richard King - richrdkng@gmail.com */ +!function(n,t){"function"==typeof define&&define.amd?define([],t):"object"==typeof module&&module.exports?module.exports=t():n.js_partial_isArray=t()}(this,function(){"use strict";return function(n,t,r){var e=t===!0,i=r===!0;if(null!==n&&"object"==typeof n){if(!e&&!i)return"[object Array]"===Object.prototype.toString.call(n);if(e)return n instanceof Int8Array||n instanceof Uint8Array||n instanceof Uint8ClampedArray||n instanceof Int16Array||n instanceof Uint16Array||n instanceof Int32Array||n instanceof Uint32Array||n instanceof Float32Array||n instanceof Float64Array;if(i&&"length"in n&&"number"==typeof n.length)return!0}return!1}}); \ No newline at end of file diff --git a/license.md b/license.md new file mode 100644 index 0000000..ae3f703 --- /dev/null +++ b/license.md @@ -0,0 +1,16 @@ +**The MIT License (MIT)** + +Copyright (c) 2016 **Richard King** [richrdkng@gmail.com](richrdkng@gmail.com) + +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. diff --git a/package.json b/package.json new file mode 100644 index 0000000..b7ff487 --- /dev/null +++ b/package.json @@ -0,0 +1,59 @@ +{ + "name": "js-partial-is-array", + "version": "0.0.0", + "description": "A partial to check whether an object is an array.", + "main": "dist/js-partial-is-array.js", + "license": "MIT", + "homepage": "https://github.com/jsopenstd/js-partial-is-array#readme", + "repository": { + "type": "git", + "url": "git://github.com/jsopenstd/js-partial-is-array.git" + }, + "bugs": { + "url": "https://github.com/jsopenstd/js-partial-is-array/issues" + }, + "author": { + "name": "Richard King", + "email": "richrdkng@gmail.com", + "url": "https://github.com/richrdkng" + }, + "scripts": { + "g": "node --harmony `which gulp` --gulpfile scripts/gulp/main.js", + "gulp": "npm run g", + "build": "npm run g -- tasks/build", + "test": "npm run g -- tasks/test", + "ci": "npm run g -- tasks/ci" + }, + "dependencies": {}, + "devDependencies": { + "assert": "^1.3.0", + "coveralls": "^2.11.9", + "del": "^2.2.0", + "gulp": "^3.9.1", + "gulp-coveralls": "^0.1.4", + "gulp-debug": "^2.1.2", + "gulp-eslint": "^3.0.1", + "gulp-header": "^1.8.8", + "gulp-istanbul": "^1.0.0", + "gulp-mocha": "^3.0.0", + "gulp-rename": "^1.2.2", + "gulp-sequence": "^0.4.5", + "gulp-uglify": "^2.0.0", + "merge2": "^1.0.2", + "semver": "^5.3.0" + }, + "keywords": [ + "js", + "partial", + "is", + "array", + "isarray", + "is-array", + "js-partial-is-array", + "jsopenstd", + "umd", + "amd", + "commonjs", + "browser" + ] +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..a9e9cf2 --- /dev/null +++ b/readme.md @@ -0,0 +1,97 @@ +# js-partial-is-array + +[![Recent Version][npm-badge]][npm-url] +[![Travis CI - Build Status][travis-badge]][travis-url] +[![Coveralls - Code Coverage Status][cov-badge]][cov-url] +[![David - Dependencies][dep-badge]][dep-url] +[![David - DevDependencies][dev-dep-badge]][dev-dep-url] +[![Doclets][doclets-badge]][doclets-url] +[![Gitter - Repository Chat][chat-badge]][chat-url] + +## Synopsis + +A partial to check whether **an object is an array**. +By default it handles **typed arrays and array-likes as non-arrays**. + +- Written in **UMD** + +## Install + +``` +npm install js-partial-is-array +``` + +## Usage + +For additional examples, +check the **[test folder](https://github.com/jsopenstd/js-partial-is-array/tree/master/tests)** + +```javascript +// TODO +``` + +## Documentation + +Check the source +[here](https://github.com/jsopenstd/js-partial-is-array/blob/master/src/js-partial-is-array.js) +since it's well structured and documented. Also you can find the rendered jsDoc documentation on +[Doclets.io](https://doclets.io/jsopenstd/js-partial-is-array/master). + +Also, check the [unit tests](https://github.com/jsopenstd/js-partial-is-array/blob/master/tests/tests.js) +in order to grasp the full-fledged capabilities. + +Have fun! ;) + +## Issues + +If you find any bugs and other issues, check the +[GSDC Guide - Issues](https://github.com/openstd/general-software-development-contribution-guide#issues) +section on how to submit issues in a standardized way on +[the project's issues page](https://github.com/jsopenstd/js-partial-is-array/issues). + +In case you have any suggestions regarding the project (features, additional capabilities, etc.), check the +[GSDC Guide - Suggestions](https://github.com/openstd/general-software-development-contribution-guide#suggestions) +section on how to submit suggestions in an easy, standardized way on +[the project's issues page](https://github.com/jsopenstd/js-partial-is-array/issues). + +## Contribution + +In order to contribute to this project, check the +[GSDC Guide](https://github.com/openstd/general-software-development-contribution-guide) +for an easy, standardized way on how to contribute to projects. + +## Support + +If you **by any means** find this project useful, +[consider supporting the organization](https://github.com/jsopenstd/jsopenstd/blob/master/support.md). + +There are multiple options to support the project and the developers. +Any means of support is beneficial and helpful. + +## License + +[MIT](license.md) @ Richard King + +[npm-badge]: https://img.shields.io/npm/v/js-partial-is-array.svg +[npm-url]: https://www.npmjs.com/package/js-partial-is-array + +[travis-badge]: https://travis-ci.org/jsopenstd/js-partial-is-array.svg?branch=master +[travis-url]: https://travis-ci.org/jsopenstd/js-partial-is-array + +[cov-badge]: https://coveralls.io/repos/github/jsopenstd/js-partial-is-array/badge.svg?branch=master +[cov-url]: https://coveralls.io/github/jsopenstd/js-partial-is-array + +[dep-badge]: https://david-dm.org/jsopenstd/js-partial-is-array.svg +[dep-url]: https://david-dm.org/jsopenstd/js-partial-is-array + +[dev-dep-badge]: https://david-dm.org/jsopenstd/js-partial-is-array/dev-status.svg +[dev-dep-url]: https://david-dm.org/jsopenstd/js-partial-is-array#info=devDependencies + +[doclets-badge]: https://img.shields.io/badge/style-on_doclets-brightgreen.svg?style=flat-square&label=docs +[doclets-url]: https://doclets.io/jsopenstd/js-partial-is-array/master + +[chat-badge]: https://badges.gitter.im/jsopenstd/js-partial-is-array.svg +[chat-url]: https://gitter.im/jsopenstd/js-partial-is-array?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge + +[partial-link]: https://github.com/jsopenstd/jsopenstd/blob/master/readme.md#partial +[umd-link]: https://github.com/jsopenstd/jsopenstd/blob/master/readme.md#umd diff --git a/scripts/gulp/main.js b/scripts/gulp/main.js new file mode 100644 index 0000000..78c219d --- /dev/null +++ b/scripts/gulp/main.js @@ -0,0 +1,17 @@ +'use strict'; + +const gulp = require(`gulp`), + debug = require(`gulp-debug`); + +require(`./tasks/build`); +require(`./tasks/bump`); +require(`./tasks/test`); +require(`./tasks/ci`); + +// left here for quick check whether gulp works +gulp.task( + `default`, + () => { + return gulp; + } +); diff --git a/scripts/gulp/tasks/build/index.js b/scripts/gulp/tasks/build/index.js new file mode 100644 index 0000000..81e3644 --- /dev/null +++ b/scripts/gulp/tasks/build/index.js @@ -0,0 +1,70 @@ +'use strict'; + +const gulp = require(`gulp`), + remove = require(`del`), + compressor = require('gulp-uglify'), + header = require('gulp-header'), + rename = require('gulp-rename'), + sequence = require(`gulp-sequence`), + debug = require(`gulp-debug`); + +gulp.task( + `tasks/build.clear`, + (cb) => { + remove.sync( + [ + `../../dist` + ], + { + force : true + } + ); + + cb(); + } +); + +gulp.task( + `tasks/build.development`, + () => { + return gulp + .src(`../../src/**/*.js`) + .pipe(gulp.dest(`../../dist`)); + } +); + +gulp.task( + `tasks/build.production`, + () => { + let template = require('../../../../src/license-header-template.json').template, + pkg = require('../../../../package.json'), + data = { + name : pkg.name, + version : pkg.version, + author : pkg.author.name, + email : pkg.author.email, + }; + + return gulp + .src(`../../src/**/*.js`) + .pipe(compressor()) + .pipe(header(template, data)) + .pipe(rename( + { + extname : '.min.js' + } + )) + .pipe(gulp.dest(`../../dist`)); + } +); + +gulp.task( + `tasks/build`, + (cb) => { + sequence( + `tasks/build.clear`, + `tasks/build.development`, + `tasks/build.production` + )(cb); + } +); diff --git a/scripts/gulp/tasks/bump/index.js b/scripts/gulp/tasks/bump/index.js new file mode 100644 index 0000000..7d29879 --- /dev/null +++ b/scripts/gulp/tasks/bump/index.js @@ -0,0 +1,147 @@ +'use strict'; + +const gulp = require('gulp'), + sequence = require('gulp-sequence'), + debug = require('gulp-debug'), + semver = require('semver'), + fs = require('fs'), + vars = require('../../vars'); + +const MAJOR = 1, + MINOR = 2, + PATCH = 3; + +let bumpType, + _nextVersion; + +const getNextVersion = () => { + let ver; + + if ( ! _nextVersion) { + ver = require('../../../../package.json').version; + + switch (bumpType) { + case MAJOR : + ver = semver.inc(ver, 'major'); + break; + + case MINOR : + ver = semver.inc(ver, 'minor'); + break; + + case PATCH : + ver = semver.inc(ver, 'patch'); + break; + } + + _nextVersion = ver; + } + + return _nextVersion; +}; + +gulp.task( + 'tasks/bump.set-bump-major', + (cb) => { + bumpType = MAJOR; + cb(); + } +); + +gulp.task( + 'tasks/bump.set-bump-minor', + (cb) => { + bumpType = MINOR; + cb(); + } +); + +gulp.task( + 'tasks/bump.set-bump-patch', + (cb) => { + bumpType = PATCH; + cb(); + } +); + +gulp.task( + 'tasks/bump.package_json', + (cb) => { + let path = '/vagrant/package.json', + pkg = require(path); + + pkg.version = getNextVersion(); + + var data = JSON.stringify(pkg, null, 2); + + // add new line to the end of the file by adding to the data + data += '\n'; + + fs.writeFileSync(path, data); + + cb(); + } +); + +gulp.task( + 'tasks/bump.src', + (cb) => { + bumpType = MAJOR; + + let path = `/vagrant/src/${vars.sourceName}.js`, + version = getNextVersion(), + src = fs.readFileSync( + path, + { + encoding : 'utf8' + } + ), + pattern = /\* @version [\d.]+/; + + src = src.replace(pattern, '* @version ' + version); + + fs.writeFileSync(path, src); + + cb(); + } +); + +gulp.task( + 'tasks/bump.bump-files', + (cb) => { + sequence( + 'tasks/bump.package_json', + 'tasks/bump.src' + )(cb); + } +); + +gulp.task( + 'tasks/bump-major', + (cb) => { + sequence( + 'tasks/bump.set-bump-major', + 'tasks/bump.bump-files' + )(cb); + } +); + +gulp.task( + 'tasks/bump-minor', + (cb) => { + sequence( + 'tasks/bump.set-bump-minor', + 'tasks/bump.bump-files' + )(cb); + } +); + +gulp.task( + 'tasks/bump-patch', + (cb) => { + sequence( + 'tasks/bump.set-bump-patch', + 'tasks/bump.bump-files' + )(cb); + } +); diff --git a/scripts/gulp/tasks/ci/index.js b/scripts/gulp/tasks/ci/index.js new file mode 100644 index 0000000..c726526 --- /dev/null +++ b/scripts/gulp/tasks/ci/index.js @@ -0,0 +1,26 @@ +'use strict'; + +const gulp = require(`gulp`), + coveralls = require(`gulp-coveralls`), + sequence = require(`gulp-sequence`), + debug = require(`gulp-debug`); + +gulp.task( + `tasks/submit-to-coveralls`, + () => { + return gulp + .src(`../../cov/**/lcov.info`) + .pipe(coveralls()); + } +); + +gulp.task( + `tasks/ci`, + (cb) => { + sequence( + `tasks/build`, + `tasks/test`, + `tasks/submit-to-coveralls` + )(cb); + } +); diff --git a/scripts/gulp/tasks/test/index.js b/scripts/gulp/tasks/test/index.js new file mode 100644 index 0000000..b70ee8d --- /dev/null +++ b/scripts/gulp/tasks/test/index.js @@ -0,0 +1,153 @@ +'use strict'; + +const gulp = require(`gulp`), + mocha = require(`gulp-mocha`), + coverage = require(`gulp-istanbul`), + sequence = require(`gulp-sequence`), + lint = require(`gulp-eslint`), + debug = require(`gulp-debug`), + vars = require(`../../vars`), + testVars = require(`../../../../tests/variables`); + +const sourceName = vars.sourceName; + +gulp.task( + `tasks/test.src`, + () => { + testVars.path = `../src/${sourceName}.js`; + + return gulp + .src( + `../../tests/tests.js`, + { + read : false + } + ) + .pipe( + mocha({ + ui : `exports` + }) + ); + } +); + +gulp.task( + `tasks/test.dist.development`, + () => { + testVars.path = `../dist/${sourceName}.js`; + + return gulp + .src( + `../../tests/tests.js`, + { + read : false + } + ) + .pipe( + mocha({ + ui : `exports` + }) + ); + } +); + +gulp.task( + `tasks/test.dist.production`, + () => { + testVars.path = `../dist/${sourceName}.min.js`; + + return gulp + .src( + `../../tests/tests.js`, + { + read : false + } + ) + .pipe( + mocha({ + ui : `exports` + }) + ); + } +); + +gulp.task( + `tasks/test.init-cov`, + () => { + return gulp + .src(`../../src/**/*.js`) + .pipe(coverage()) + .pipe(coverage.hookRequire()); + } +); + +gulp.task( + `tasks/test.with-cov`, + [ + `tasks/test.init-cov` + ], + () => { + testVars.path = `../src/${sourceName}.js`; + + return gulp + .src( + `../../tests/tests.js`, + { + read : false + } + ) + .pipe( + mocha({ + ui : `exports` + }) + ) + .pipe( + coverage.writeReports({ + dir : `../../cov` + }) + ) + .pipe( + coverage.enforceThresholds({ + thresholds : { + global : 100 // enforce 100% coverage + } + } + )); + } +); + +gulp.task( + `tasks/test.with-lint`, + [ + `tasks/test.src` + ], + () => { + return gulp + .src(`../../src/**/*.js`) + .pipe(lint()) + .pipe(lint.format()) + .pipe(lint.failAfterError()); + } +); + +gulp.task( + `tasks/test.dist`, + (cb) => { + sequence( + `tasks/test.dist.development`, + `tasks/test.dist.production` + )(cb); + } +); + +gulp.task( + `tasks/test`, + (cb) => { + sequence( + `tasks/test.src`, + `tasks/test.with-cov`, + `tasks/test.with-lint`, + `tasks/test.dist` + )(cb); + } +); diff --git a/scripts/gulp/vars.js b/scripts/gulp/vars.js new file mode 100644 index 0000000..c0636d0 --- /dev/null +++ b/scripts/gulp/vars.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + sourceName : 'js-partial-is-array' +}; diff --git a/scripts/tasks/main.py b/scripts/tasks/main.py new file mode 100644 index 0000000..5b89b52 --- /dev/null +++ b/scripts/tasks/main.py @@ -0,0 +1,290 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import shlex +import subprocess +import collections +import os.path +import json +import getpass + + +def exec_command(command, **kwargs): + shell = kwargs.get("shell", False) + stdin = kwargs.get("stdin", None) + stdout = kwargs.get("stdout", None) + stderr = kwargs.get("stderr", None) + + kwargs.update(shell=shell) + kwargs.update(stdin=stdin) + kwargs.update(stdout=stdout) + kwargs.update(stderr=stderr) + + if not isinstance(command, list): + command = shlex.split(command) + + return subprocess.call(command, **kwargs) + + +def observe_command(command, **kwargs): + shell = kwargs.get("shell", False) + stdin = kwargs.get("stdin", subprocess.PIPE) + stdout = kwargs.get("stdout", subprocess.PIPE) + stderr = kwargs.get("stderr", subprocess.PIPE) + + kwargs.update(shell=shell) + kwargs.update(stdin=stdin) + kwargs.update(stdout=stdout) + kwargs.update(stderr=stderr) + + if not isinstance(command, list): + command = shlex.split(command) + + proc = subprocess.Popen(command, **kwargs) + + try: + _stdin = proc.stdin.read() + except IOError: + _stdin = None + + try: + _stdout = proc.stdout.read() + except IOError: + _stdout = None + + try: + _stderr = proc.stderr.read() + except IOError: + _stderr = None + + if not _stdin: + _stdin = None + + if not _stdout: + _stdout = None + + if not _stderr: + _stderr = None + + Result = collections.namedtuple("result", "stdin, stdout, stderr") + + return Result(stdin=_stdin, stdout=_stdout, stderr=_stderr) + + +def file_exists(path): + return os.path.isfile(path) + + +def get_json_data(path): + with open(path) as data_file: + data = json.load(data_file) + + return data + + +def data_exists(json_data, key): + return get_data(json_data, key) is not None + + +def get_data(json_data, key): + parts = key.split(".") + value = None + + for part in parts: + + if part in json_data: + json_data = json_data[part] + value = json_data + + else: + value = None + break + + return value + + +def git_data_exists(json_data): + if (data_exists(json_data, "git") and + data_exists(json_data, "git.name") and + data_exists(json_data, "git.email")): + + return True + + return False + + +def npm_data_exists(json_data): + if (data_exists(json_data, "npm") and + data_exists(json_data, "npm.username") and + data_exists(json_data, "npm.email")): + + return True + + return False + + +def git_prerequisites_exist(): + output = observe_command("git config --global user.name") + + if output.stdout is None: + return False + + output = observe_command("git config --global user.email") + + if output.stdout is None: + return False + + return True + + +def npm_prerequisites_exist(): + output = observe_command("npm whoami") + + if output.stderr is not None: + return False + + return True + + +def git_set_prerequisites(json_data): + name = get_data(json_data, "git.name") + email = get_data(json_data, "git.email") + + exec_command("git config --global user.name \"{}\"".format(name)) + exec_command("git config --global user.email \"{}\"".format(email)) + + +def npm_set_prerequisites(npm_adduser_path, json_data): + username = get_data(json_data, "npm.username") + email = get_data(json_data, "npm.email") + + password = getpass.getpass("NPM Password: ") + + exec_command("{} {} {} {}".format(npm_adduser_path, username, password, email)) + + +def bump_project(bump_type): + bump = "tasks/bump-project-{}" + + if (bump_type == "major" or + bump_type == "minor" or + bump_type == "patch"): + + bump = bump.format(bump_type) + + else: + # "patch" is the default bump_type + bump = bump.format("patch") + + run_gulp(bump) + + +def bump_project_files(bump_type): + bump = "tasks/bump-{}" + + if (bump_type == "major" or + bump_type == "minor" or + bump_type == "patch"): + + bump = bump.format(bump_type) + + else: + # "patch" is the default bump_type + bump = bump.format("patch") + + run_gulp(bump) + + +def git_publish(): + data = get_json_data(package_json) + version = get_data(data, 'version') + + # stage files + exec_command(["git add --all"], shell=True) + + # commit + exec_command(["git commit -m \"{}\"".format(version)], shell=True) + + # tag + exec_command(["git tag {}".format(version)], shell=True) + + # push + exec_command(["git push origin master --tags"], shell=True) + + +def npm_publish(): + exec_command("npm publish") + + +def run_gulp(task=None): + if task is None: + task = "" + + exec_command(gulp.format(task)) + + +# necessary paths +publish_json = "/vagrant/.publish.json" +package_json = "/vagrant/package.json" +npm_adduser_sh = "/vagrant/scripts/tasks/npm-adduser.sh" + +# gulp path +gulp = "gulp --gulpfile /vagrant/scripts/gulp/main.js {}" + +args = sys.argv[1:] + +if len(args) > 0: + main_task = args[0] + sub_task = None + + if len(args) > 1: + sub_task = args[1] + + # process according to main_task + if main_task == "test": + run_gulp("tasks/test") + + elif main_task == "bump": + bump_project(sub_task) + + elif main_task == "build": + run_gulp("tasks/build") + + elif main_task == "publish": + if not file_exists(publish_json): + raise FileNotFoundError(".publish.json doesn't exist on: \"{}\"".format(publish_json)) + + data = get_json_data(publish_json) + + # check necessary data presence + if not git_data_exists(data): + raise ValueError("git data not found in .publish.json") + + if not npm_data_exists(data): + raise ValueError("npm data not found in .publish.json") + + # check prerequisites + if not git_prerequisites_exist(): + git_set_prerequisites(data) + + if not npm_prerequisites_exist(): + npm_set_prerequisites(npm_adduser_sh, data) + + # bump file versions according to sub_task + bump_project_files(sub_task) + + # build files + run_gulp("tasks/build") + + # commit and push files + git_publish() + + # publish on NPM + npm_publish() + + else: + run_gulp(main_task) + +else: + run_gulp() diff --git a/scripts/tasks/npm-adduser.sh b/scripts/tasks/npm-adduser.sh new file mode 100644 index 0000000..8740615 --- /dev/null +++ b/scripts/tasks/npm-adduser.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +export H_NPM_USERNAME="$1" +export H_NPM_PASSWORD="$2" +export H_NPM_EMAIL="$3" + +npm adduser <> /home/vagrant/.bashrc diff --git a/scripts/vagrant/scripts/install_essentials.sh b/scripts/vagrant/scripts/install_essentials.sh new file mode 100644 index 0000000..cc96e81 --- /dev/null +++ b/scripts/vagrant/scripts/install_essentials.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# install essentials +sudo apt-get install python-software-properties \ + build-essential \ + git \ + nano \ + curl \ + mc \ + -y + +# install stress to be able to quickly check if the VM can use all the resources of the host CPU +# usage: + # for 1 core: stress -c 1 + # for 4 cores: stress -c 4 +sudo apt-get install stress -y + +# update after essentials (especially python-software-properties) +sudo apt-get update -y diff --git a/scripts/vagrant/scripts/install_git.sh b/scripts/vagrant/scripts/install_git.sh new file mode 100644 index 0000000..da05134 --- /dev/null +++ b/scripts/vagrant/scripts/install_git.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +# update git +sudo add-apt-repository ppa:git-core/ppa -y +sudo apt-get update -y + +sudo apt-get install git -y diff --git a/scripts/vagrant/scripts/install_node.sh b/scripts/vagrant/scripts/install_node.sh new file mode 100644 index 0000000..46d3f3d --- /dev/null +++ b/scripts/vagrant/scripts/install_node.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +function clean_up_dependencies() +{ + cd /vagrant + rm -rf node_modules + npm cache clean +} + +# install node & update npm +curl -sL https://deb.nodesource.com/setup_6.x | sudo bash - +sudo apt-get install nodejs -y + +sudo npm install npm --global + +# install dependency version updater globally +sudo npm rm npm-check-updates --global +sudo npm install npm-check-updates --global + +# install gulp globally +sudo npm rm gulp --global +sudo npm install gulp gulp-cli --global + +# install project dependencies +# clean-up before the first try to prevent "ENOENT: no such file or directory, open..." error during npm install +clean_up_dependencies + +# install dependencies +if ! npm install; then + + # clean-up before another try + clean_up_dependencies + + # when running Vagrant under Windows, in case of "EPROTO: protocol error, symlink...", + # try install dependencies with "--no-bin-links" + if ! npm install --no-bin-links; then + echo '"npm install" AND "npm install --no-bin-links" failed, try to resolve it manually' + fi +fi diff --git a/scripts/vagrant/scripts/install_python.sh b/scripts/vagrant/scripts/install_python.sh new file mode 100644 index 0000000..70bdb5d --- /dev/null +++ b/scripts/vagrant/scripts/install_python.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +# update python 2.7.x +sudo add-apt-repository ppa:fkrull/deadsnakes-python2.7 -y + +sudo apt-get update -y +sudo apt-get install python2.7 -y + +# install pip (python's package manager) +sudo apt-get install python-pip -y diff --git a/src/js-partial-is-array.js b/src/js-partial-is-array.js new file mode 100644 index 0000000..7ff4ba3 --- /dev/null +++ b/src/js-partial-is-array.js @@ -0,0 +1,98 @@ +/* + |---------------------------------------------------------------------------------------------------------------------- + | A partial to check whether an object is an array. + |---------------------------------------------------------------------------------------------------------------------- + */ + +/** + * More information on [JavaScript Open Standards]{@link https://github.com/jsopenstd/jsopenstd}. + * + * @namespace js.partial + * @version 0.0.0 + * + * @author Richard King [GitHub]{@link https://github.com/richrdkng} + * @license [MIT]{@link https://github.com/jsopenstd/js-partial-foreach/blob/master/license.md} + */ + +/** + * UMD - [returnExports.js pattern]{@link https://github.com/umdjs/umd/blob/master/templates/returnExports.js} + * For more information and license, check the link below: + * [UMD GitHub Repository]{@link https://github.com/umdjs/umd} + */ +(function(root, factory) { + // AMD + /* istanbul ignore next: ignore coverage test for UMD */ + if (typeof define === 'function' && define.amd) { + define([], factory); + + // CommonJS + } else if (typeof module === 'object' && module.exports) { + module.exports = factory(); + + // Browser + } else { + root.js_partial_isArray = factory(); + } +}(this, function() { + 'use strict'; + + /** + * Determines whether an object is an array. + * By default it handles **typed arrays and array-likes as non-arrays**. + * + * @function isArray + * @memberOf js.partial + * + * @param {*} object - The object to check. + * @param {boolean|null} [handleTypedArrayAsArray=false] - Handle a typed array as a regular array too. + * By default a typed array is not classified + * as a regular array. + * **Pass null to skip this argument** and leave its value + * with the default value. + * @param {boolean} [handleArrayLikeAsArray=false] - Handle an array-like as a regular array too. + * An array-like is anything, that has a valid .length + * property and behaves as a collection, that stores values + * such as arguments, strings, other objects based on + * arrays or objects. + * By default an array-like is not classified + * as a regular array. + * + * @returns {boolean} If the object is an array, it will return true. + */ + return function isArray(object, handleTypedArrayAsArray, handleArrayLikeAsArray) { + var handleTypedArray = handleTypedArrayAsArray === true, + handleArrayLike = handleArrayLikeAsArray === true; + + if (object !== null && typeof object === 'object') { + + if (Object.prototype.toString.call(object) === '[object Array]') { + return true; + } + + if (handleTypedArray) { + if (object instanceof Int8Array || + object instanceof Uint8Array || + object instanceof Uint8ClampedArray || + object instanceof Int16Array || + object instanceof Uint16Array || + object instanceof Int32Array || + object instanceof Uint32Array || + object instanceof Float32Array || + object instanceof Float64Array) { + + return true; + } + } + + if (handleArrayLike) { + if ('length' in object && + typeof object.length === 'number') { + + return true; + } + } + } + + return false; + }; +})); diff --git a/src/license-header-template.json b/src/license-header-template.json new file mode 100644 index 0000000..9592372 --- /dev/null +++ b/src/license-header-template.json @@ -0,0 +1,3 @@ +{ + "template" : "/*! <%= name %> v<%= version %> | MIT License | (c) <%= author %> - <%= email %> */\n" +} diff --git a/tests/tests.js b/tests/tests.js new file mode 100644 index 0000000..58ceae5 --- /dev/null +++ b/tests/tests.js @@ -0,0 +1,66 @@ +'use strict'; + +const assert = require('assert'), + vars = require('./variables'), + isArray = require(vars.path); + +module.exports = { + 'js-partial-is-object' : () => { + let _undefined = undefined, + _null = null, + _boolean = false, + _number = 0, + _string = 'str', + _function = () => {}, + _array = [], + _object = {}, + + _objectCreated_1 = Object.create({}), + _objectCreated_2 = Object.create(Object.prototype), + _nullProtoObject = Object.create(null), + + _typedArray = new Uint8Array(0), + _arrayLike = (function() { return arguments; })(1, 2, 3); + + assert(isArray() === false); + assert(isArray(_undefined) === false); + assert(isArray(_null) === false); + assert(isArray(_boolean) === false); + assert(isArray(_number) === false); + assert(isArray(_string) === false); + assert(isArray(_function) === false); + assert(isArray(_array) === true); + assert(isArray(_object) === false); + + assert(isArray(_objectCreated_1) === false); + assert(isArray(_objectCreated_2) === false); + assert(isArray(_nullProtoObject) === false); + + assert(isArray(_array, true) === true); + assert(isArray(_array, false) === true); + + assert(isArray(_typedArray, true) === true); + assert(isArray(_typedArray, false) === false); + + assert(isArray(_arrayLike, true) === false); + assert(isArray(_arrayLike, false) === false); + + assert(isArray(_array, true, true) === true); + assert(isArray(_array, false, true) === true); + assert(isArray(_array, null, true) === true); + + assert(isArray(_typedArray, true, true) === true); + assert(isArray(_typedArray, false, false) === false); + assert(isArray(_typedArray, null, false) === false); + + assert(isArray(_arrayLike, true, true) === true); + assert(isArray(_arrayLike, false, false) === false); + assert(isArray(_arrayLike, null, true) === true); + assert(isArray(_arrayLike, null, false) === false); + + assert(isArray(_object, true, true) === false); + assert(isArray(_object, false, false) === false); + assert(isArray(_object, null, true) === false); + assert(isArray(_object, null, false) === false); + } +}; diff --git a/tests/variables.js b/tests/variables.js new file mode 100644 index 0000000..1ed86df --- /dev/null +++ b/tests/variables.js @@ -0,0 +1,3 @@ +module.exports = { + path : '' +}; diff --git a/vagrantfile b/vagrantfile new file mode 100644 index 0000000..015c0bd --- /dev/null +++ b/vagrantfile @@ -0,0 +1,9 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure(2) do |config| + + config.vm.box = "ubuntu/trusty64" + config.vm.provision :shell, :path => "scripts/vagrant/provision.sh" + +end