├── .eslintignore ├── system-test ├── util_system_test.js └── .eslintrc.yml ├── .prettierignore ├── test ├── test_repos.txt ├── mocha.opts ├── .eslintrc.yml └── util_test.js ├── .npmignore ├── .circleci ├── key.json.enc ├── npm-install-retry.js └── config.yml ├── .prettierrc ├── defaultsettings.json ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── ISSUE_TEMPLATE.md └── CONTRIBUTING ├── .eslintrc.yml ├── .gitignore ├── renovate.json ├── .nycrc ├── package.json ├── CODE_OF_CONDUCT.md ├── bin └── labelcat.js ├── README.md ├── src └── util.js └── LICENSE /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | -------------------------------------------------------------------------------- /system-test/util_system_test.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | -------------------------------------------------------------------------------- /test/test_repos.txt: -------------------------------------------------------------------------------- 1 | fakeowner/fakerepo 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.sublime-* 2 | node_modules/ 3 | key.json 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --require intelli-espower-loader 2 | --timeout 10000 3 | --throw-deprecation 4 | -------------------------------------------------------------------------------- /test/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | env: 3 | mocha: true 4 | rules: 5 | node/no-unpublished-require: off 6 | -------------------------------------------------------------------------------- /.circleci/key.json.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleCloudPlatform/LabelCat/HEAD/.circleci/key.json.enc -------------------------------------------------------------------------------- /system-test/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | env: 3 | mocha: true 4 | rules: 5 | node/no-unpublished-require: off 6 | no-console: off 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | --- 2 | bracketSpacing: false 3 | printWidth: 80 4 | semi: true 5 | singleQuote: true 6 | tabWidth: 2 7 | trailingComma: es5 8 | useTabs: false 9 | -------------------------------------------------------------------------------- /defaultsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "githubClientID": "YOUR GITHUB CLIENT ID HERE", 3 | "githubClientSecret": "YOUR GITHUB CLIENT SECRET HERE", 4 | "projectID": "YOUR GCP PROJECT ID HERE", 5 | "computeRegion": "YOUR GCP PROJECT COMPUTE REGION HERE" 6 | } 7 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes # (it's a good idea to open an issue first for discussion) 2 | 3 | - [ ] Tests and linter pass 4 | - [ ] Code coverage does not decrease (if any source code was changed) 5 | - [ ] Appropriate docs were updated (if necessary) 6 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | extends: 3 | - 'eslint:recommended' 4 | - 'plugin:node/recommended' 5 | - prettier 6 | plugins: 7 | - node 8 | - prettier 9 | rules: 10 | prettier/prettier: error 11 | block-scoped-var: error 12 | eqeqeq: error 13 | no-warning-comments: warn 14 | no-var: error 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-* 2 | key.json 3 | npm-debug.log 4 | config.js 5 | coverage/ 6 | settings.json 7 | node_modules 8 | .DS_Store 9 | 10 | **/*.log 11 | **/node_modules 12 | .coverage 13 | .nyc_output 14 | docs/ 15 | out/ 16 | system-test/secrets.js 17 | system-test/*key.json 18 | *.lock 19 | package-lock.json 20 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | "docker:disable" 5 | ], 6 | "pinVersions": false, 7 | "rebaseStalePrs": true, 8 | "schedule": [ 9 | "after 9am and before 3pm" 10 | ], 11 | "gitAuthor": null, 12 | "packageRules": [ 13 | { 14 | "extends": "packages:linters", 15 | "groupName": "linters" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "report-dir": "./.coverage", 3 | "exclude": [ 4 | "bin/*.js", 5 | "src/*{/*,/**/*}.js", 6 | "src/*/v*/*.js", 7 | "test/**/*.js" 8 | ], 9 | "watermarks": { 10 | "branches": [ 11 | 95, 12 | 100 13 | ], 14 | "functions": [ 15 | 95, 16 | 100 17 | ], 18 | "lines": [ 19 | 95, 20 | 100 21 | ], 22 | "statements": [ 23 | 95, 24 | 100 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thanks for stopping by to let us know something could be better! 2 | 3 | Please run down the following list and make sure you've tried the usual "quick 4 | fixes": 5 | 6 | - Search the issues already opened: https://github.com/{{metadata['repository']}}/issues 7 | 8 | If you are still having issues, please be sure to include as much information as 9 | possible: 10 | 11 | #### Environment details 12 | 13 | - OS: 14 | - Node.js version: 15 | - npm version: 16 | - `{{ metadata['name'] }}` version: 17 | 18 | #### Steps to reproduce 19 | 20 | 1. ??? 21 | 2. ??? 22 | 23 | Following these steps will guarantee the quickest resolution possible. 24 | 25 | Thanks! 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "labelcat", 3 | "version": "1.0.0-alpha.1", 4 | "private": true, 5 | "license": "Apache Version 2.0", 6 | "author": "Google Inc.", 7 | "contributors": [ 8 | { 9 | "name": "Jason Dobry", 10 | "email": "jason.dobry@gmail.com" 11 | }, 12 | { 13 | "name": "Steffany Brown", 14 | "email": "steffanyb@google.com" 15 | } 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/GoogleCloudPlatform/LabelCat.git" 20 | }, 21 | "preferGlobal": true, 22 | "bin": { 23 | "labelcat": "bin/labelcat.js" 24 | }, 25 | "engines": { 26 | "node": ">= 8.x" 27 | }, 28 | "scripts": { 29 | "cover": "nyc --reporter=lcov mocha test/*.js && nyc report", 30 | "lint": "eslint src/ system-test/ test/ bin/", 31 | "prettier": "prettier --write bin/*.js src/*.js test/*.js system-test/*.js", 32 | "system-test": "mocha system-test/*.js --timeout 600000", 33 | "test-no-cover": "mocha test/*.js", 34 | "test": "npm run cover" 35 | }, 36 | "dependencies": { 37 | "@google-cloud/automl": "^0.1.2", 38 | "@octokit/rest": "^15.12.1", 39 | "csv-write-stream": "^2.0.0", 40 | "json2csv": "^4.2.1", 41 | "loglevel": "^1.6.1", 42 | "papaparse": "^4.6.1", 43 | "yargs": "^12.0.2" 44 | }, 45 | "devDependencies": { 46 | "codecov": "^3.0.2", 47 | "eslint": "^5.0.0", 48 | "eslint-config-prettier": "^3.0.0", 49 | "eslint-plugin-node": "^7.0.0", 50 | "eslint-plugin-prettier": "^2.6.0", 51 | "intelli-espower-loader": "^1.0.1", 52 | "mocha": "^5.2.0", 53 | "nyc": "^13.0.0", 54 | "power-assert": "^1.6.0", 55 | "prettier": "^1.13.5", 56 | "proxyquire": "^2.1.0", 57 | "sinon": "^6.3.4" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.circleci/npm-install-retry.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | let spawn = require('child_process').spawn; 4 | 5 | // 6 | //USE: ./index.js [... NPM ARGS] 7 | // 8 | 9 | let timeout = process.argv[2] || 60000; 10 | let attempts = process.argv[3] || 3; 11 | let args = process.argv.slice(4); 12 | if (args.length === 0) { 13 | args = ['install']; 14 | } 15 | 16 | (function npm() { 17 | let timer; 18 | args.push('--verbose'); 19 | let proc = spawn('npm', args); 20 | proc.stdout.pipe(process.stdout); 21 | proc.stderr.pipe(process.stderr); 22 | proc.stdin.end(); 23 | proc.stdout.on('data', () => { 24 | setTimer(); 25 | }); 26 | proc.stderr.on('data', () => { 27 | setTimer(); 28 | }); 29 | 30 | // side effect: this also restarts when npm exits with a bad code even if it 31 | // didnt timeout 32 | proc.on('close', (code, signal) => { 33 | clearTimeout(timer); 34 | if (code || signal) { 35 | console.log('[npm-are-you-sleeping] npm exited with code ' + code + ''); 36 | 37 | if (--attempts) { 38 | console.log('[npm-are-you-sleeping] restarting'); 39 | npm(); 40 | } else { 41 | console.log('[npm-are-you-sleeping] i tried lots of times. giving up.'); 42 | throw new Error("npm install fails"); 43 | } 44 | } 45 | }); 46 | 47 | function setTimer() { 48 | clearTimeout(timer); 49 | timer = setTimeout(() => { 50 | console.log('[npm-are-you-sleeping] killing npm with SIGTERM'); 51 | proc.kill('SIGTERM'); 52 | // wait a couple seconds 53 | timer = setTimeout(() => { 54 | // its it's still not closed sigkill 55 | console.log('[npm-are-you-sleeping] killing npm with SIGKILL'); 56 | proc.kill('SIGKILL'); 57 | }, 2000); 58 | }, timeout); 59 | } 60 | })(); 61 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING: -------------------------------------------------------------------------------- 1 | # How to become a contributor and submit your own code 2 | 3 | **Table of contents** 4 | 5 | * [Contributor License Agreements](#contributor-license-agreements) 6 | * [Contributing a patch](#contributing-a-patch) 7 | * [Running the tests](#running-the-tests) 8 | * [Releasing the library](#releasing-the-library) 9 | 10 | ## Contributor License Agreements 11 | 12 | We'd love to accept your sample apps and patches! Before we can take them, we 13 | have to jump a couple of legal hurdles. 14 | 15 | Please fill out either the individual or corporate Contributor License Agreement 16 | (CLA). 17 | 18 | * If you are an individual writing original source code and you're sure you 19 | own the intellectual property, then you'll need to sign an [individual CLA] 20 | (https://developers.google.com/open-source/cla/individual). 21 | * If you work for a company that wants to allow you to contribute your work, 22 | then you'll need to sign a [corporate CLA] 23 | (https://developers.google.com/open-source/cla/corporate). 24 | 25 | Follow either of the two links above to access the appropriate CLA and 26 | instructions for how to sign and return it. Once we receive it, we'll be able to 27 | accept your pull requests. 28 | 29 | ## Contributing A Patch 30 | 31 | 1. Submit an issue describing your proposed change to the repo in question. 32 | 1. The repo owner will respond to your issue promptly. 33 | 1. If your proposed change is accepted, and you haven't already done so, sign a 34 | Contributor License Agreement (see details above). 35 | 1. Fork the desired repo, develop and test your code changes. 36 | 1. Ensure that your code adheres to the existing style in the code to which 37 | you are contributing. 38 | 1. Ensure that your code has an appropriate set of tests which all pass. 39 | 1. Submit a pull request. 40 | 41 | ## Running the tests 42 | 43 | 1. [Prepare your environment for Node.js setup][setup]. 44 | 45 | 1. Install dependencies: 46 | 47 | npm install 48 | 49 | 1. Run the tests: 50 | 51 | npm test 52 | 53 | [setup]: https://cloud.google.com/nodejs/docs/setup -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, 4 | and in the interest of fostering an open and welcoming community, 5 | we pledge to respect all people who contribute through reporting issues, 6 | posting feature requests, updating documentation, 7 | submitting pull requests or patches, and other activities. 8 | 9 | We are committed to making participation in this project 10 | a harassment-free experience for everyone, 11 | regardless of level of experience, gender, gender identity and expression, 12 | sexual orientation, disability, personal appearance, 13 | body size, race, ethnicity, age, religion, or nationality. 14 | 15 | Examples of unacceptable behavior by participants include: 16 | 17 | * The use of sexualized language or imagery 18 | * Personal attacks 19 | * Trolling or insulting/derogatory comments 20 | * Public or private harassment 21 | * Publishing other's private information, 22 | such as physical or electronic 23 | addresses, without explicit permission 24 | * Other unethical or unprofessional conduct. 25 | 26 | Project maintainers have the right and responsibility to remove, edit, or reject 27 | comments, commits, code, wiki edits, issues, and other contributions 28 | that are not aligned to this Code of Conduct. 29 | By adopting this Code of Conduct, 30 | project maintainers commit themselves to fairly and consistently 31 | applying these principles to every aspect of managing this project. 32 | Project maintainers who do not follow or enforce the Code of Conduct 33 | may be permanently removed from the project team. 34 | 35 | This code of conduct applies both within project spaces and in public spaces 36 | when an individual is representing the project or its community. 37 | 38 | Instances of abusive, harassing, or otherwise unacceptable behavior 39 | may be reported by opening an issue 40 | or contacting one or more of the project maintainers. 41 | 42 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, 43 | available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) 44 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | workflows: 3 | version: 2 4 | tests: 5 | jobs: &workflow_jobs 6 | - lint: 7 | filters: &all_commits 8 | tags: 9 | only: /.*/ 10 | - node8: 11 | requires: 12 | - lint 13 | filters: *all_commits 14 | - node10: 15 | requires: 16 | - lint 17 | filters: *all_commits 18 | nightly: 19 | triggers: 20 | - schedule: 21 | cron: 0 7 * * * 22 | filters: 23 | branches: 24 | only: master 25 | jobs: *workflow_jobs 26 | jobs: 27 | lint: 28 | docker: 29 | - image: 'node:8' 30 | user: node 31 | steps: 32 | - checkout 33 | - run: &npm_install_and_link 34 | name: Install and link the module 35 | command: |- 36 | mkdir -p /home/node/.npm-global 37 | ./.circleci/npm-install-retry.js 38 | environment: 39 | NPM_CONFIG_PREFIX: /home/node/.npm-global 40 | - run: 41 | name: Run linting. 42 | command: npm run lint 43 | environment: 44 | NPM_CONFIG_PREFIX: /home/node/.npm-global 45 | node8: 46 | docker: 47 | - image: 'node:8' 48 | user: node 49 | steps: &tests_steps 50 | - checkout 51 | - run: 52 | name: Decrypt credentials. 53 | command: | 54 | if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then 55 | for encrypted_key in .circleci/*.json.enc; do 56 | openssl aes-256-cbc -d -in $encrypted_key \ 57 | -out $(echo $encrypted_key | sed 's/\.enc//') \ 58 | -k "${SYSTEM_TESTS_ENCRYPTION_KEY}" 59 | done 60 | fi 61 | - run: *npm_install_and_link 62 | - run: cp defaultsettings.json settings.json 63 | - run: 64 | name: Run the tests. 65 | command: npm test 66 | environment: 67 | GCLOUD_PROJECT: label-cat 68 | GOOGLE_APPLICATION_CREDENTIALS: .circleci/key.json 69 | - run: node_modules/.bin/codecov 70 | - run: 71 | name: Remove unencrypted key. 72 | command: | 73 | if ! [[ -z "${SYSTEM_TESTS_ENCRYPTION_KEY}" ]]; then 74 | rm .circleci/*.json 75 | fi 76 | when: always 77 | node10: 78 | docker: 79 | - image: 'node:10' 80 | user: node 81 | steps: *tests_steps 82 | -------------------------------------------------------------------------------- /bin/labelcat.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const util = require('../src/util.js'); 4 | const settings = require('../settings.json'); // eslint-disable-line node/no-missing-require 5 | 6 | require(`yargs`) 7 | .demand(1) 8 | .command( 9 | `retrieveIssues