From bb1e24845a1d8c7ec3c3a2950cf7a4e8d5c46be2 Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Fri, 14 Oct 2022 18:21:41 -0700 Subject: [PATCH] feat: add template-oss BREAKING CHANGE: this package is now compatible with the following semver range for node: `^14.17.0 || ^16.13.0 || >=18.0.0` --- .commitlintrc.js | 10 + .eslintrc.js | 17 ++ .github/CODEOWNERS | 3 + .github/ISSUE_TEMPLATE/bug.yml | 54 +++++ .github/ISSUE_TEMPLATE/config.yml | 3 + .github/dependabot.yml | 17 ++ .github/matchers/tap.json | 32 +++ .github/workflows/audit.yml | 37 ++++ .github/workflows/ci-release.yml | 210 ++++++++++++++++++ .github/workflows/ci.yml | 157 ++++++++++++++ .github/workflows/codeql-analysis.yml | 38 ++++ .github/workflows/post-dependabot.yml | 121 +++++++++++ .github/workflows/pull-request.yml | 48 +++++ .github/workflows/release.yml | 298 ++++++++++++++++++++++++++ .gitignore | 31 ++- .npmrc | 3 + .release-please-manifest.json | 3 + .travis.yml | 9 - CODE_OF_CONDUCT.md | 7 + README.md | 6 +- SECURITY.md | 3 + lib/index.js | 142 ++++++++++++ mute.js | 145 ------------- package.json | 43 ++-- release-please-config.json | 36 ++++ test/basic.js | 92 ++++---- 26 files changed, 1343 insertions(+), 222 deletions(-) create mode 100644 .commitlintrc.js create mode 100644 .eslintrc.js create mode 100644 .github/CODEOWNERS create mode 100644 .github/ISSUE_TEMPLATE/bug.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/matchers/tap.json create mode 100644 .github/workflows/audit.yml create mode 100644 .github/workflows/ci-release.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 .github/workflows/post-dependabot.yml create mode 100644 .github/workflows/pull-request.yml create mode 100644 .github/workflows/release.yml create mode 100644 .npmrc create mode 100644 .release-please-manifest.json delete mode 100644 .travis.yml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 SECURITY.md create mode 100644 lib/index.js delete mode 100644 mute.js create mode 100644 release-please-config.json diff --git a/.commitlintrc.js b/.commitlintrc.js new file mode 100644 index 0000000..5b0b1a5 --- /dev/null +++ b/.commitlintrc.js @@ -0,0 +1,10 @@ +/* This file is automatically added by @npmcli/template-oss. Do not edit. */ + +module.exports = { + extends: ['@commitlint/config-conventional'], + rules: { + 'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'deps', 'chore']], + 'header-max-length': [2, 'always', 80], + 'subject-case': [0, 'always', ['lower-case', 'sentence-case', 'start-case']], + }, +} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..5db9f81 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,17 @@ +/* This file is automatically added by @npmcli/template-oss. Do not edit. */ + +'use strict' + +const { readdirSync: readdir } = require('fs') + +const localConfigs = readdir(__dirname) + .filter((file) => file.startsWith('.eslintrc.local.')) + .map((file) => `./${file}`) + +module.exports = { + root: true, + extends: [ + '@npmcli', + ...localConfigs, + ], +} diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..2c54b0d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +* @npm/cli-team diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000..d043192 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,54 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: Bug +description: File a bug/issue +title: "[BUG] " +labels: [ Bug, Needs Triage ] + +body: + - type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please [search here](./issues) to see if an issue already exists for your problem. + options: + - label: I have searched the existing issues + required: true + - type: textarea + attributes: + label: Current Behavior + description: A clear & concise description of what you're experiencing. + validations: + required: false + - type: textarea + attributes: + label: Expected Behavior + description: A clear & concise description of what you expected to happen. + validations: + required: false + - type: textarea + attributes: + label: Steps To Reproduce + description: Steps to reproduce the behavior. + value: | + 1. In this environment... + 2. With this config... + 3. Run '...' + 4. See error... + validations: + required: false + - type: textarea + attributes: + label: Environment + description: | + examples: + - **npm**: 7.6.3 + - **Node**: 13.14.0 + - **OS**: Ubuntu 20.04 + - **platform**: Macbook Pro + value: | + - npm: + - Node: + - OS: + - platform: + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..d640909 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,3 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +blank_issues_enabled: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8da2a45 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +version: 2 + +updates: + - package-ecosystem: npm + directory: / + schedule: + interval: daily + allow: + - dependency-type: direct + versioning-strategy: increase-if-necessary + commit-message: + prefix: deps + prefix-development: chore + labels: + - "Dependencies" diff --git a/.github/matchers/tap.json b/.github/matchers/tap.json new file mode 100644 index 0000000..2c81ea9 --- /dev/null +++ b/.github/matchers/tap.json @@ -0,0 +1,32 @@ +{ + "//@npmcli/template-oss": "This file is automatically added by @npmcli/template-oss. Do not edit.", + "problemMatcher": [ + { + "owner": "tap", + "pattern": [ + { + "regexp": "^\\s*not ok \\d+ - (.*)", + "message": 1 + }, + { + "regexp": "^\\s*---" + }, + { + "regexp": "^\\s*at:" + }, + { + "regexp": "^\\s*line:\\s*(\\d+)", + "line": 1 + }, + { + "regexp": "^\\s*column:\\s*(\\d+)", + "column": 1 + }, + { + "regexp": "^\\s*file:\\s*(.*)", + "file": 1 + } + ] + } + ] +} diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml new file mode 100644 index 0000000..60bb334 --- /dev/null +++ b/.github/workflows/audit.yml @@ -0,0 +1,37 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: Audit + +on: + workflow_dispatch: + schedule: + # "At 08:00 UTC (01:00 PT) on Monday" https://crontab.guru/#0_8_*_*_1 + - cron: "0 8 * * 1" + +jobs: + audit: + name: Audit Dependencies + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + - name: Install npm@latest + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund --package-lock + - name: Run Audit + run: npm audit diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml new file mode 100644 index 0000000..6dad88c --- /dev/null +++ b/.github/workflows/ci-release.yml @@ -0,0 +1,210 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CI - Release + +on: + workflow_call: + inputs: + ref: + required: true + type: string + check-sha: + required: true + type: string + +jobs: + lint-all: + name: Lint All + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Get Workflow Job + uses: actions/github-script@v6 + + id: check-output + env: + JOB_NAME: "Lint All" + MATRIX_NAME: "" + with: + script: | + const { owner, repo } = context.repo + + const { data } = await github.rest.actions.listJobsForWorkflowRun({ + owner, + repo, + run_id: context.runId, + per_page: 100 + }) + + const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME + const job = data.jobs.find(j => j.name.endsWith(jobName)) + const jobUrl = job?.html_url + + const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/${{ inputs.check-sha }}` + + let summary = `This check is assosciated with ${shaUrl}\n\n` + + if (jobUrl) { + summary += `For run logs, click here: ${jobUrl}` + } else { + summary += `Run logs could not be found for a job with name: "${jobName}"` + } + + return { summary } + - name: Create Check + uses: LouisBrunner/checks-action@v1.3.1 + id: check + + with: + token: ${{ secrets.GITHUB_TOKEN }} + status: in_progress + name: Lint All + sha: ${{ inputs.check-sha }} + output: ${{ steps.check-output.outputs.result }} + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + - name: Install npm@latest + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund + - name: Lint + run: npm run lint --ignore-scripts + - name: Post Lint + run: npm run postlint --ignore-scripts + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.3.1 + if: always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ steps.check.outputs.check_id }} + + test-all: + name: Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest + shell: bash + - name: Windows + os: windows-latest + shell: cmd + node-version: + - 14.17.0 + - 14.x + - 16.13.0 + - 16.x + - 18.0.0 + - 18.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Get Workflow Job + uses: actions/github-script@v6 + + id: check-output + env: + JOB_NAME: "Test All" + MATRIX_NAME: " - ${{ matrix.platform.name }} - ${{ matrix.node-version }}" + with: + script: | + const { owner, repo } = context.repo + + const { data } = await github.rest.actions.listJobsForWorkflowRun({ + owner, + repo, + run_id: context.runId, + per_page: 100 + }) + + const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME + const job = data.jobs.find(j => j.name.endsWith(jobName)) + const jobUrl = job?.html_url + + const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/${{ inputs.check-sha }}` + + let summary = `This check is assosciated with ${shaUrl}\n\n` + + if (jobUrl) { + summary += `For run logs, click here: ${jobUrl}` + } else { + summary += `Run logs could not be found for a job with name: "${jobName}"` + } + + return { summary } + - name: Create Check + uses: LouisBrunner/checks-action@v1.3.1 + id: check + + with: + token: ${{ secrets.GITHUB_TOKEN }} + status: in_progress + name: Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + sha: ${{ inputs.check-sha }} + output: ${{ steps.check-output.outputs.result }} + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Update Windows npm + # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows + if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) + run: | + curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz + tar xf npm-7.5.4.tgz + cd package + node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz + cd .. + rmdir /s /q package + - name: Install npm@7 + if: startsWith(matrix.node-version, '10.') + run: npm i --prefer-online --no-fund --no-audit -g npm@7 + - name: Install npm@latest + if: ${{ !startsWith(matrix.node-version, '10.') }} + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.3.1 + if: always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ steps.check.outputs.check_id }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a6c934a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,157 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CI + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + - latest + schedule: + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +jobs: + engines: + name: Engines - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + node-version: + - 14.17.0 + - 16.13.0 + - 18.0.0 + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Update Windows npm + # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows + if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) + run: | + curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz + tar xf npm-7.5.4.tgz + cd package + node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz + cd .. + rmdir /s /q package + - name: Install npm@7 + if: startsWith(matrix.node-version, '10.') + run: npm i --prefer-online --no-fund --no-audit -g npm@7 + - name: Install npm@latest + if: ${{ !startsWith(matrix.node-version, '10.') }} + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund --engines-strict + + lint: + name: Lint + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + - name: Install npm@latest + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund + - name: Lint + run: npm run lint --ignore-scripts + - name: Post Lint + run: npm run postlint --ignore-scripts + + test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest + shell: bash + - name: Windows + os: windows-latest + shell: cmd + node-version: + - 14.17.0 + - 14.x + - 16.13.0 + - 16.x + - 18.0.0 + - 18.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Update Windows npm + # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows + if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) + run: | + curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz + tar xf npm-7.5.4.tgz + cd package + node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz + cd .. + rmdir /s /q package + - name: Install npm@7 + if: startsWith(matrix.node-version, '10.') + run: npm i --prefer-online --no-fund --no-audit -g npm@7 + - name: Install npm@latest + if: ${{ !startsWith(matrix.node-version, '10.') }} + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..66b9498 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,38 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CodeQL + +on: + push: + branches: + - main + - latest + pull_request: + branches: + - main + - latest + schedule: + # "At 10:00 UTC (03:00 PT) on Monday" https://crontab.guru/#0_10_*_*_1 + - cron: "0 10 * * 1" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: javascript + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/post-dependabot.yml b/.github/workflows/post-dependabot.yml new file mode 100644 index 0000000..88ac403 --- /dev/null +++ b/.github/workflows/post-dependabot.yml @@ -0,0 +1,121 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: Post Dependabot + +on: pull_request + +permissions: + contents: write + +jobs: + template-oss: + name: template-oss + if: github.repository_owner == 'npm' && github.actor == 'dependabot[bot]' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.ref }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + - name: Install npm@latest + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund + - name: Fetch Dependabot Metadata + id: metadata + uses: dependabot/fetch-metadata@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + # Dependabot can update multiple directories so we output which directory + # it is acting on so we can run the command for the correct root or workspace + - name: Get Dependabot Directory + if: contains(steps.metadata.outputs.dependency-names, '@npmcli/template-oss') + id: flags + run: | + dependabot_dir="${{ steps.metadata.outputs.directory }}" + if [[ "$dependabot_dir" == "/" ]]; then + echo "::set-output name=workspace::-iwr" + else + # strip leading slash from directory so it works as a + # a path to the workspace flag + echo "::set-output name=workspace::-w ${dependabot_dir#/}" + fi + + - name: Apply Changes + if: steps.flags.outputs.workspace + id: apply + run: | + npm run template-oss-apply ${{ steps.flags.outputs.workspace }} + if [[ `git status --porcelain` ]]; then + echo "::set-output name=changes::true" + fi + # This only sets the conventional commit prefix. This workflow can't reliably determine + # what the breaking change is though. If a BREAKING CHANGE message is required then + # this PR check will fail and the commit will be amended with stafftools + if [[ "${{ steps.dependabot-metadata.outputs.update-type }}" == "version-update:semver-major" ]]; then + prefix='feat!' + else + prefix='chore!' + fi + echo "::set-output name=message::$prefix: postinstall for dependabot template-oss PR" + + # This step will fail if template-oss has made any workflow updates. It is impossible + # for a workflow to update other workflows. In the case it does fail, we continue + # and then try to apply only a portion of the changes in the next step + - name: Push All Changes + if: steps.apply.outputs.changes + id: push + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git commit -am "${{ steps.apply.outputs.message }}" + git push + + # If the previous step failed, then reset the commit and remove any workflow changes + # and attempt to commit and push again. This is helpful because we will have a commit + # with the correct prefix that we can then --amend with @npmcli/stafftools later. + - name: Push All Changes Except Workflows + if: steps.apply.outputs.changes && steps.push-all.outcome == 'failure' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git reset HEAD~ + git checkout HEAD -- .github/workflows/ + git clean -fd .github/workflows/ + git commit -am "${{ steps.apply.outputs.message }}" + git push + + # Check if all the necessary template-oss changes were applied. Since we continued + # on errors in one of the previous steps, this check will fail if our follow up + # only applied a portion of the changes and we need to followup manually. + # + # Note that this used to run `lint` and `postlint` but that will fail this action + # if we've also shipped any linting changes separate from template-oss. We do + # linting in another action, so we want to fail this one only if there are + # template-oss changes that could not be applied. + - name: Check Changes + if: steps.apply.outputs.changes + run: | + npm exec --offline ${{ steps.flags.outputs.workspace }} -- template-oss-check + + - name: Fail on Breaking Change + if: steps.apply.outputs.changes && startsWith(steps.apply.outputs.message, 'feat!') + run: | + echo "This PR has a breaking change. Run 'npx -p @npmcli/stafftools gh template-oss-fix'" + echo "for more information on how to fix this with a BREAKING CHANGE footer." + exit 1 diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..1a1d1ee --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,48 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: Pull Request + +on: + pull_request: + types: + - opened + - reopened + - edited + - synchronize + +jobs: + commitlint: + name: Lint Commits + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + - name: Install npm@latest + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund + - name: Run Commitlint on Commits + id: commit + continue-on-error: true + run: | + npx --offline commitlint -V --from origin/${{ github.base_ref }} --to ${{ github.event.pull_request.head.sha }} + - name: Run Commitlint on PR Title + if: steps.commit.outcome == 'failure' + run: | + echo ${{ github.event.pull_request.title }} | npx --offline commitlint -V diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..2f7dee0 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,298 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: Release + +on: + workflow_dispatch: + push: + branches: + - main + - latest + +permissions: + contents: write + pull-requests: write + checks: write + +jobs: + release: + outputs: + pr: ${{ steps.release.outputs.pr }} + releases: ${{ steps.release.outputs.releases }} + release-flags: ${{ steps.release.outputs.release-flags }} + branch: ${{ steps.release.outputs.pr-branch }} + pr-number: ${{ steps.release.outputs.pr-number }} + comment-id: ${{ steps.pr-comment.outputs.result }} + check-id: ${{ steps.check.outputs.check_id }} + name: Release + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + - name: Install npm@latest + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund + - name: Release Please + id: release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + npx --offline template-oss-release-please ${{ github.ref_name }} ${{ github.event_name }} + - name: Post Pull Request Comment + if: steps.release.outputs.pr-number + uses: actions/github-script@v6 + id: pr-comment + env: + PR_NUMBER: ${{ steps.release.outputs.pr-number }} + REF_NAME: ${{ github.ref_name }} + with: + script: | + const { REF_NAME, PR_NUMBER } = process.env + const repo = { owner: context.repo.owner, repo: context.repo.repo } + const issue = { ...repo, issue_number: PR_NUMBER } + + const { data: workflow } = await github.rest.actions.getWorkflowRun({ ...repo, run_id: context.runId }) + + let body = '## Release Manager\n\n' + + const comments = await github.paginate(github.rest.issues.listComments, issue) + let commentId = comments?.find(c => c.user.login === 'github-actions[bot]' && c.body.startsWith(body))?.id + + body += `Release workflow run: ${workflow.html_url}\n\n#### Force CI to Rerun for This Release\n\n` + body += `This PR will be updated and CI will run for every non-\`chore:\` commit that is pushed to \`main\`. ` + body += `To force CI to rerun, run this command:\n\n` + body += `\`\`\`\ngh workflow run release.yml -r ${REF_NAME}\n\`\`\`` + + if (commentId) { + await github.rest.issues.updateComment({ ...repo, comment_id: commentId, body }) + } else { + const { data: comment } = await github.rest.issues.createComment({ ...issue, body }) + commentId = comment?.id + } + + return commentId + - name: Get Workflow Job + uses: actions/github-script@v6 + if: steps.release.outputs.pr-number + id: check-output + env: + JOB_NAME: "Release" + MATRIX_NAME: "" + with: + script: | + const { owner, repo } = context.repo + + const { data } = await github.rest.actions.listJobsForWorkflowRun({ + owner, + repo, + run_id: context.runId, + per_page: 100 + }) + + const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME + const job = data.jobs.find(j => j.name.endsWith(jobName)) + const jobUrl = job?.html_url + + const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/${{ steps.release.outputs.pr-sha }}` + + let summary = `This check is assosciated with ${shaUrl}\n\n` + + if (jobUrl) { + summary += `For run logs, click here: ${jobUrl}` + } else { + summary += `Run logs could not be found for a job with name: "${jobName}"` + } + + return { summary } + - name: Create Check + uses: LouisBrunner/checks-action@v1.3.1 + id: check + if: steps.release.outputs.pr-number + with: + token: ${{ secrets.GITHUB_TOKEN }} + status: in_progress + name: Release + sha: ${{ steps.release.outputs.pr-sha }} + output: ${{ steps.check-output.outputs.result }} + + update: + needs: release + outputs: + sha: ${{ steps.commit.outputs.sha }} + check-id: ${{ steps.check.outputs.check_id }} + name: Update - Release + if: github.repository_owner == 'npm' && needs.release.outputs.pr + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ needs.release.outputs.branch }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + - name: Install npm@latest + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund + - name: Run Post Pull Request Actions + env: + RELEASE_PR_NUMBER: ${{ needs.release.outputs.pr-number }} + RELEASE_COMMENT_ID: ${{ needs.release.outputs.comment-id }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + npm exec --offline -- template-oss-release-manager + npm run rp-pull-request --ignore-scripts --if-present + - name: Commit + id: commit + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git commit --all --amend --no-edit || true + git push --force-with-lease + echo "::set-output name=sha::$(git rev-parse HEAD)" + - name: Get Workflow Job + uses: actions/github-script@v6 + + id: check-output + env: + JOB_NAME: "Update - Release" + MATRIX_NAME: "" + with: + script: | + const { owner, repo } = context.repo + + const { data } = await github.rest.actions.listJobsForWorkflowRun({ + owner, + repo, + run_id: context.runId, + per_page: 100 + }) + + const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME + const job = data.jobs.find(j => j.name.endsWith(jobName)) + const jobUrl = job?.html_url + + const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/${{ steps.commit.outputs.sha }}` + + let summary = `This check is assosciated with ${shaUrl}\n\n` + + if (jobUrl) { + summary += `For run logs, click here: ${jobUrl}` + } else { + summary += `Run logs could not be found for a job with name: "${jobName}"` + } + + return { summary } + - name: Create Check + uses: LouisBrunner/checks-action@v1.3.1 + id: check + + with: + token: ${{ secrets.GITHUB_TOKEN }} + status: in_progress + name: Release + sha: ${{ steps.commit.outputs.sha }} + output: ${{ steps.check-output.outputs.result }} + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.3.1 + if: always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ needs.release.outputs.check-id }} + + ci: + name: CI - Release + needs: [ release, update ] + if: needs.release.outputs.pr + uses: ./.github/workflows/ci-release.yml + with: + ref: ${{ needs.release.outputs.branch }} + check-sha: ${{ needs.update.outputs.sha }} + + post-ci: + needs: [ release, update, ci ] + name: Post CI - Release + if: github.repository_owner == 'npm' && needs.release.outputs.pr && always() + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Get Needs Result + id: needs-result + run: | + result="" + if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then + result="failure" + elif [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then + result="cancelled" + else + result="success" + fi + echo "::set-output name=result::$result" + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.3.1 + if: always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ steps.needs-result.outputs.result }} + check_id: ${{ needs.update.outputs.check-id }} + + post-release: + needs: release + name: Post Release - Release + if: github.repository_owner == 'npm' && needs.release.outputs.releases + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 18.x + - name: Install npm@latest + run: npm i --prefer-online --no-fund --no-audit -g npm@latest + - name: npm Version + run: npm -v + - name: Install Dependencies + run: npm i --ignore-scripts --no-audit --no-fund + - name: Run Post Release Actions + env: + RELEASES: ${{ needs.release.outputs.releases }} + run: | + npm run rp-release --ignore-scripts --if-present ${{ join(fromJSON(needs.release.outputs.release-flags), ' ') }} diff --git a/.gitignore b/.gitignore index a1aa3dd..0ec3c84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,28 @@ -node_modules -package-lock.json -.nyc_output +# This file is automatically added by @npmcli/template-oss. Do not edit. + +# ignore everything in the root +/* + +# keep these +!**/.gitignore +!/.commitlintrc.js +!/.eslintrc.js +!/.eslintrc.local.* +!/.github/ +!/.gitignore +!/.npmrc +!/.release-please-manifest.json +!/bin/ +!/CHANGELOG* +!/CODE_OF_CONDUCT.md +!/docs/ +!/lib/ +!/LICENSE* +!/map.js +!/package.json +!/README* +!/release-please-config.json +!/scripts/ +!/SECURITY.md +!/tap-snapshots/ +!/test/ diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..529f93e --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +; This file is automatically added by @npmcli/template-oss. Do not edit. + +package-lock=false diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..493bd4e --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.0.8" +} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 99f2bbf..0000000 --- a/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: node_js -language: node_js -node_js: - - '0.8' - - '0.10' - - '0.12' - - 'iojs' -before_install: - - npm install -g npm@latest diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..167043c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,7 @@ +<!-- This file is automatically added by @npmcli/template-oss. Do not edit. --> + +All interactions in this repo are covered by the [npm Code of +Conduct](https://docs.npmjs.com/policies/conduct) + +The npm cli team may, at its own discretion, moderate, remove, or edit +any interactions such as pull requests, issues, and comments. diff --git a/README.md b/README.md index 8ab1238..d238be6 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ silently dropped, rather than being passed through. ## Usage ```javascript -var MuteStream = require('mute-stream') +const MuteStream = require('mute-stream') -var ms = new MuteStream(options) +const ms = new MuteStream(options) ms.pipe(process.stdout) ms.write('foo') // writes 'foo' to stdout @@ -20,7 +20,7 @@ ms.unmute() ms.write('baz') // writes 'baz' to stdout // can also be used to mute incoming data -var ms = new MuteStream +const ms = new MuteStream input.pipe(ms) ms.on('data', function (c) { diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..a93106d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,3 @@ +<!-- This file is automatically added by @npmcli/template-oss. Do not edit. --> + +Please send vulnerability reports through [hackerone](https://hackerone.com/github). diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..599a617 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,142 @@ +const Stream = require('stream') + +class MuteStream extends Stream { + #isTTY = null + + constructor (opts = {}) { + super(opts) + this.writable = this.readable = true + this.muted = false + this.on('pipe', this._onpipe) + this.replace = opts.replace + + // For readline-type situations + // This much at the start of a line being redrawn after a ctrl char + // is seen (such as backspace) won't be redrawn as the replacement + this._prompt = opts.prompt || null + this._hadControl = false + } + + #destSrc (key, def) { + if (this._dest) { + return this._dest[key] + } + if (this._src) { + return this._src[key] + } + return def + } + + #proxy (method, ...args) { + if (typeof this._dest?.[method] === 'function') { + this._dest[method](...args) + } + if (typeof this._src?.[method] === 'function') { + this._src[method](...args) + } + } + + get isTTY () { + if (this.#isTTY !== null) { + return this.#isTTY + } + return this.#destSrc('isTTY', false) + } + + // basically just get replace the getter/setter with a regular value + set isTTY (val) { + this.#isTTY = val + } + + get rows () { + return this.#destSrc('rows') + } + + get columns () { + return this.#destSrc('columns') + } + + mute () { + this.muted = true + } + + unmute () { + this.muted = false + } + + _onpipe (src) { + this._src = src + } + + pipe (dest, options) { + this._dest = dest + return super.pipe(dest, options) + } + + pause () { + if (this._src) { + return this._src.pause() + } + } + + resume () { + if (this._src) { + return this._src.resume() + } + } + + write (c) { + if (this.muted) { + if (!this.replace) { + return true + } + // eslint-disable-next-line no-control-regex + if (c.match(/^\u001b/)) { + if (c.indexOf(this._prompt) === 0) { + c = c.substr(this._prompt.length) + c = c.replace(/./g, this.replace) + c = this._prompt + c + } + this._hadControl = true + return this.emit('data', c) + } else { + if (this._prompt && this._hadControl && + c.indexOf(this._prompt) === 0) { + this._hadControl = false + this.emit('data', this._prompt) + c = c.substr(this._prompt.length) + } + c = c.toString().replace(/./g, this.replace) + } + } + this.emit('data', c) + } + + end (c) { + if (this.muted) { + if (c && this.replace) { + c = c.toString().replace(/./g, this.replace) + } else { + c = null + } + } + if (c) { + this.emit('data', c) + } + this.emit('end') + } + + destroy (...args) { + return this.#proxy('destroy', ...args) + } + + destroySoon (...args) { + return this.#proxy('destroySoon', ...args) + } + + close (...args) { + return this.#proxy('close', ...args) + } +} + +module.exports = MuteStream diff --git a/mute.js b/mute.js deleted file mode 100644 index a24fc09..0000000 --- a/mute.js +++ /dev/null @@ -1,145 +0,0 @@ -var Stream = require('stream') - -module.exports = MuteStream - -// var out = new MuteStream(process.stdout) -// argument auto-pipes -function MuteStream (opts) { - Stream.apply(this) - opts = opts || {} - this.writable = this.readable = true - this.muted = false - this.on('pipe', this._onpipe) - this.replace = opts.replace - - // For readline-type situations - // This much at the start of a line being redrawn after a ctrl char - // is seen (such as backspace) won't be redrawn as the replacement - this._prompt = opts.prompt || null - this._hadControl = false -} - -MuteStream.prototype = Object.create(Stream.prototype) - -Object.defineProperty(MuteStream.prototype, 'constructor', { - value: MuteStream, - enumerable: false -}) - -MuteStream.prototype.mute = function () { - this.muted = true -} - -MuteStream.prototype.unmute = function () { - this.muted = false -} - -Object.defineProperty(MuteStream.prototype, '_onpipe', { - value: onPipe, - enumerable: false, - writable: true, - configurable: true -}) - -function onPipe (src) { - this._src = src -} - -Object.defineProperty(MuteStream.prototype, 'isTTY', { - get: getIsTTY, - set: setIsTTY, - enumerable: true, - configurable: true -}) - -function getIsTTY () { - return( (this._dest) ? this._dest.isTTY - : (this._src) ? this._src.isTTY - : false - ) -} - -// basically just get replace the getter/setter with a regular value -function setIsTTY (isTTY) { - Object.defineProperty(this, 'isTTY', { - value: isTTY, - enumerable: true, - writable: true, - configurable: true - }) -} - -Object.defineProperty(MuteStream.prototype, 'rows', { - get: function () { - return( this._dest ? this._dest.rows - : this._src ? this._src.rows - : undefined ) - }, enumerable: true, configurable: true }) - -Object.defineProperty(MuteStream.prototype, 'columns', { - get: function () { - return( this._dest ? this._dest.columns - : this._src ? this._src.columns - : undefined ) - }, enumerable: true, configurable: true }) - - -MuteStream.prototype.pipe = function (dest, options) { - this._dest = dest - return Stream.prototype.pipe.call(this, dest, options) -} - -MuteStream.prototype.pause = function () { - if (this._src) return this._src.pause() -} - -MuteStream.prototype.resume = function () { - if (this._src) return this._src.resume() -} - -MuteStream.prototype.write = function (c) { - if (this.muted) { - if (!this.replace) return true - if (c.match(/^\u001b/)) { - if(c.indexOf(this._prompt) === 0) { - c = c.substr(this._prompt.length); - c = c.replace(/./g, this.replace); - c = this._prompt + c; - } - this._hadControl = true - return this.emit('data', c) - } else { - if (this._prompt && this._hadControl && - c.indexOf(this._prompt) === 0) { - this._hadControl = false - this.emit('data', this._prompt) - c = c.substr(this._prompt.length) - } - c = c.toString().replace(/./g, this.replace) - } - } - this.emit('data', c) -} - -MuteStream.prototype.end = function (c) { - if (this.muted) { - if (c && this.replace) { - c = c.toString().replace(/./g, this.replace) - } else { - c = null - } - } - if (c) this.emit('data', c) - this.emit('end') -} - -function proxy (fn) { return function () { - var d = this._dest - var s = this._src - if (d && d[fn]) d[fn].apply(d, arguments) - if (s && s[fn]) s[fn].apply(s, arguments) -}} - -MuteStream.prototype.destroy = proxy('destroy') -MuteStream.prototype.destroySoon = proxy('destroySoon') -MuteStream.prototype.close = proxy('close') diff --git a/package.json b/package.json index 812b7d3..b4f2fcd 100644 --- a/package.json +++ b/package.json @@ -1,35 +1,52 @@ { "name": "mute-stream", "version": "0.0.8", - "main": "mute.js", - "directories": { - "test": "test" - }, + "main": "lib/index.js", "devDependencies": { - "tap": "^16.0.1" + "@npmcli/eslint-config": "^4.0.0", + "@npmcli/template-oss": "4.6.0", + "tap": "^16.3.0" }, "scripts": { - "test": "tap test/*.js --cov" + "test": "tap", + "lint": "eslint \"**/*.js\"", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run lint -- --fix", + "snap": "tap", + "posttest": "npm run lint" }, "repository": { "type": "git", - "url": "git://github.com/isaacs/mute-stream" + "url": "https://github.com/npm/mute-stream.git" }, "keywords": [ "mute", "stream", "pipe" ], - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "author": "GitHub Inc.", "license": "ISC", "description": "Bytes go in, but they don't come out (when muted).", "files": [ - "mute.js" + "bin/", + "lib/" ], "tap": { - "statements": 75, - "branches": 57, - "functions": 93, - "lines": 77 + "statements": 70, + "branches": 60, + "functions": 81, + "lines": 70, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.6.0" } } diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..73d1e35 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,36 @@ +{ + "exclude-packages-from-root": true, + "group-pull-request-title-pattern": "chore: release ${version}", + "pull-request-title-pattern": "chore: release${component} ${version}", + "changelog-sections": [ + { + "type": "feat", + "section": "Features", + "hidden": false + }, + { + "type": "fix", + "section": "Bug Fixes", + "hidden": false + }, + { + "type": "docs", + "section": "Documentation", + "hidden": false + }, + { + "type": "deps", + "section": "Dependencies", + "hidden": false + }, + { + "type": "chore", + "hidden": true + } + ], + "packages": { + ".": { + "package-name": "" + } + } +} diff --git a/test/basic.js b/test/basic.js index 41f9e10..76b0743 100644 --- a/test/basic.js +++ b/test/basic.js @@ -1,48 +1,42 @@ -var Stream = require('stream') -var tap = require('tap') -var MS = require('../mute.js') +const Stream = require('stream') +const tap = require('tap') +const MS = require('../') // some marker objects var END = {} var PAUSE = {} var RESUME = {} -function PassThrough () { - Stream.call(this) - this.readable = this.writable = true -} +class PassThrough extends Stream { + constructor (opts) { + super(opts) + this.readable = this.writable = true + } -PassThrough.prototype = Object.create(Stream.prototype, { - constructor: { - value: PassThrough - }, - write: { - value: function (c) { - this.emit('data', c) - return true - } - }, - end: { - value: function (c) { - if (c) this.write(c) - this.emit('end') - } - }, - pause: { - value: function () { - this.emit('pause') - } - }, - resume: { - value: function () { - this.emit('resume') + write (c) { + this.emit('data', c) + return true + } + + end (c) { + if (c) { + this.write(c) } + this.emit('end') } -}) + + pause () { + this.emit('pause') + } + + resume () { + this.emit('resume') + } +} tap.test('incoming', function (t) { - var ms = new MS - var str = new PassThrough + var ms = new MS() + var str = new PassThrough() str.pipe(ms) var expect = ['foo', 'boo', END] @@ -64,8 +58,8 @@ tap.test('incoming', function (t) { }) tap.test('outgoing', function (t) { - var ms = new MS - var str = new PassThrough + var ms = new MS() + var str = new PassThrough() ms.pipe(str) var expect = ['foo', 'boo', END] @@ -88,12 +82,12 @@ tap.test('outgoing', function (t) { }) tap.test('isTTY', function (t) { - var str = new PassThrough + var str = new PassThrough() str.isTTY = true - str.columns=80 - str.rows=24 + str.columns = 80 + str.rows = 24 - var ms = new MS + var ms = new MS() t.equal(ms.isTTY, false) t.equal(ms.columns, undefined) t.equal(ms.rows, undefined) @@ -114,7 +108,7 @@ tap.test('isTTY', function (t) { t.equal(ms.columns, 80) t.equal(ms.rows, 24) - ms = new MS + ms = new MS() t.equal(ms.isTTY, false) str.pipe(ms) t.equal(ms.isTTY, true) @@ -129,8 +123,8 @@ tap.test('isTTY', function (t) { }) tap.test('pause/resume incoming', function (t) { - var str = new PassThrough - var ms = new MS + var str = new PassThrough() + var ms = new MS() str.on('pause', function () { t.equal(PAUSE, expect.shift()) }) @@ -148,8 +142,8 @@ tap.test('pause/resume incoming', function (t) { }) tap.test('replace with *', function (t) { - var str = new PassThrough - var ms = new MS({replace: '*'}) + var str = new PassThrough() + var ms = new MS({ replace: '*' }) str.pipe(ms) var expect = ['foo', '*****', 'bar', '***', 'baz', 'boo', '**', '****'] @@ -176,12 +170,12 @@ tap.test('replace with *', function (t) { }) tap.test('replace with ~YARG~', function (t) { - var str = new PassThrough - var ms = new MS({replace: '~YARG~'}) + var str = new PassThrough() + var ms = new MS({ replace: '~YARG~' }) str.pipe(ms) var expect = ['foo', '~YARG~~YARG~~YARG~~YARG~~YARG~', 'bar', - '~YARG~~YARG~~YARG~', 'baz', 'boo', '~YARG~~YARG~', - '~YARG~~YARG~~YARG~~YARG~'] + '~YARG~~YARG~~YARG~', 'baz', 'boo', '~YARG~~YARG~', + '~YARG~~YARG~~YARG~~YARG~'] ms.on('data', function (c) { t.equal(c, expect.shift())