pax_global_header 0000666 0000000 0000000 00000000064 14322171071 0014510 g ustar 00root root 0000000 0000000 52 comment=a40209e5de23279d07d210e0eb6c895f9423f057
move-file-3.0.0/ 0000775 0000000 0000000 00000000000 14322171071 0013373 5 ustar 00root root 0000000 0000000 move-file-3.0.0/.commitlintrc.js 0000664 0000000 0000000 00000000553 14322171071 0016516 0 ustar 00root root 0000000 0000000 /* 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']],
},
}
move-file-3.0.0/.eslintrc.js 0000664 0000000 0000000 00000000545 14322171071 0015636 0 ustar 00root root 0000000 0000000 /* 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,
],
}
move-file-3.0.0/.github/ 0000775 0000000 0000000 00000000000 14322171071 0014733 5 ustar 00root root 0000000 0000000 move-file-3.0.0/.github/CODEOWNERS 0000664 0000000 0000000 00000000132 14322171071 0016322 0 ustar 00root root 0000000 0000000 # This file is automatically added by @npmcli/template-oss. Do not edit.
* @npm/cli-team
move-file-3.0.0/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 14322171071 0017116 5 ustar 00root root 0000000 0000000 move-file-3.0.0/.github/ISSUE_TEMPLATE/bug.yml 0000664 0000000 0000000 00000002655 14322171071 0020426 0 ustar 00root root 0000000 0000000 # 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
move-file-3.0.0/.github/ISSUE_TEMPLATE/config.yml 0000664 0000000 0000000 00000000145 14322171071 0021106 0 ustar 00root root 0000000 0000000 # This file is automatically added by @npmcli/template-oss. Do not edit.
blank_issues_enabled: true
move-file-3.0.0/.github/dependabot.yml 0000664 0000000 0000000 00000000563 14322171071 0017567 0 ustar 00root root 0000000 0000000 # 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"
move-file-3.0.0/.github/matchers/ 0000775 0000000 0000000 00000000000 14322171071 0016541 5 ustar 00root root 0000000 0000000 move-file-3.0.0/.github/matchers/tap.json 0000664 0000000 0000000 00000001204 14322171071 0020215 0 ustar 00root root 0000000 0000000 {
"//@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
}
]
}
]
}
move-file-3.0.0/.github/settings.yml 0000664 0000000 0000000 00000000055 14322171071 0017316 0 ustar 00root root 0000000 0000000 ---
_extends: '.github:npm-cli/settings.yml'
move-file-3.0.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14322171071 0016770 5 ustar 00root root 0000000 0000000 move-file-3.0.0/.github/workflows/audit.yml 0000664 0000000 0000000 00000001775 14322171071 0020633 0 ustar 00root root 0000000 0000000 # 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
move-file-3.0.0/.github/workflows/ci-release.yml 0000664 0000000 0000000 00000012105 14322171071 0021523 0 ustar 00root root 0000000 0000000 # 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: 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 }}
# XXX: this does not work when using the default GITHUB_TOKEN.
# Instead we post the main job url to the PR as a comment which
# will link to all the other checks. To work around this we would
# need to create a GitHub that would create on-demand tokens.
# https://github.com/LouisBrunner/checks-action/issues/18
# details_url:
- 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: 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 }}
# XXX: this does not work when using the default GITHUB_TOKEN.
# Instead we post the main job url to the PR as a comment which
# will link to all the other checks. To work around this we would
# need to create a GitHub that would create on-demand tokens.
# https://github.com/LouisBrunner/checks-action/issues/18
# details_url:
- 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 }}
move-file-3.0.0/.github/workflows/ci.yml 0000664 0000000 0000000 00000011746 14322171071 0020117 0 ustar 00root root 0000000 0000000 # 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
move-file-3.0.0/.github/workflows/codeql-analysis.yml 0000664 0000000 0000000 00000001605 14322171071 0022605 0 ustar 00root root 0000000 0000000 # 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
move-file-3.0.0/.github/workflows/post-dependabot.yml 0000664 0000000 0000000 00000011653 14322171071 0022611 0 ustar 00root root 0000000 0000000 # 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
move-file-3.0.0/.github/workflows/pull-request.yml 0000664 0000000 0000000 00000002545 14322171071 0022163 0 ustar 00root root 0000000 0000000 # 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
move-file-3.0.0/.github/workflows/release.yml 0000664 0000000 0000000 00000017745 14322171071 0021151 0 ustar 00root root 0000000 0000000 # This file is automatically added by @npmcli/template-oss. Do not edit.
name: Release
on:
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 }}
- 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 }}
with:
script: |
const repo = { owner: context.repo.owner, repo: context.repo.repo }
const issue = { ...repo, issue_number: process.env.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}`
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: 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 }}
# XXX: this does not work when using the default GITHUB_TOKEN.
# Instead we post the main job url to the PR as a comment which
# will link to all the other checks. To work around this we would
# need to create a GitHub that would create on-demand tokens.
# https://github.com/LouisBrunner/checks-action/issues/18
# details_url:
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: 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 }}
# XXX: this does not work when using the default GITHUB_TOKEN.
# Instead we post the main job url to the PR as a comment which
# will link to all the other checks. To work around this we would
# need to create a GitHub that would create on-demand tokens.
# https://github.com/LouisBrunner/checks-action/issues/18
# details_url:
- 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), ' ') }}
move-file-3.0.0/.gitignore 0000664 0000000 0000000 00000000665 14322171071 0015372 0 ustar 00root root 0000000 0000000 # 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/
move-file-3.0.0/.npmrc 0000664 0000000 0000000 00000000135 14322171071 0014512 0 ustar 00root root 0000000 0000000 ; This file is automatically added by @npmcli/template-oss. Do not edit.
package-lock=false
move-file-3.0.0/.release-please-manifest.json 0000664 0000000 0000000 00000000023 14322171071 0021032 0 ustar 00root root 0000000 0000000 {
".": "3.0.0"
}
move-file-3.0.0/CHANGELOG.md 0000664 0000000 0000000 00000002110 14322171071 0015176 0 ustar 00root root 0000000 0000000 # Changelog
## [3.0.0](https://github.com/npm/move-file/compare/v2.0.1...v3.0.0) (2022-10-10)
### ⚠️ BREAKING CHANGES
* `@npmcli/move-file` is now compatible with the following semver range for node: `^14.17.0 || ^16.13.0 || >=18.0.0`
### Features
* [`401b148`](https://github.com/npm/move-file/commit/401b148c4ca06282acdf96b5a75abcc5404f7bc9) [#29](https://github.com/npm/move-file/pull/29) postinstall for dependabot template-oss PR (@lukekarrys)
## [2.0.1](https://github.com/npm/move-file/compare/v2.0.0...v2.0.1) (2022-08-15)
### Bug Fixes
* linting ([#19](https://github.com/npm/move-file/issues/19)) ([919bbd5](https://github.com/npm/move-file/commit/919bbd5bc1691c6731af0892d2be8d489fa4b528))
## [2.0.0](https://github.com/npm/move-file/compare/v1.1.2...v2.0.0) (2022-04-05)
### ⚠ BREAKING CHANGES
* this drops support for node 10 and non-LTS versions of node 12 and node 14
### Dependencies
* @npmcli/template-oss@3.2.2 ([#13](https://github.com/npm/move-file/issues/13)) ([0be4b76](https://github.com/npm/move-file/commit/0be4b76290efe056627d4831ac2a929241b974b8))
move-file-3.0.0/CODE_OF_CONDUCT.md 0000664 0000000 0000000 00000000507 14322171071 0016174 0 ustar 00root root 0000000 0000000
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.
move-file-3.0.0/LICENSE.md 0000664 0000000 0000000 00000002165 14322171071 0015003 0 ustar 00root root 0000000 0000000 MIT License
Copyright (c) Sindre Sorhus (https://sindresorhus.com)
Copyright (c) npm, Inc.
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.
move-file-3.0.0/README.md 0000664 0000000 0000000 00000002663 14322171071 0014661 0 ustar 00root root 0000000 0000000 # @npmcli/move-file
A fork of [move-file](https://github.com/sindresorhus/move-file) with
compatibility with all node 10.x versions.
> Move a file (or directory)
The built-in
[`fs.rename()`](https://nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback)
is just a JavaScript wrapper for the C `rename(2)` function, which doesn't
support moving files across partitions or devices. This module is what you
would have expected `fs.rename()` to be.
## Highlights
- Promise API.
- Supports moving a file across partitions and devices.
- Optionally prevent overwriting an existing file.
- Creates non-existent destination directories for you.
- Support for Node versions that lack built-in recursive `fs.mkdir()`
- Automatically recurses when source is a directory.
## Install
```
$ npm install @npmcli/move-file
```
## Usage
```js
const moveFile = require('@npmcli/move-file');
(async () => {
await moveFile('source/unicorn.png', 'destination/unicorn.png');
console.log('The file has been moved');
})();
```
## API
### moveFile(source, destination, options?)
Returns a `Promise` that resolves when the file has been moved.
### moveFile.sync(source, destination, options?)
#### source
Type: `string`
File, or directory, you want to move.
#### destination
Type: `string`
Where you want the file or directory moved.
#### options
Type: `object`
##### overwrite
Type: `boolean`\
Default: `true`
Overwrite existing destination file(s).
move-file-3.0.0/SECURITY.md 0000664 0000000 0000000 00000000246 14322171071 0015166 0 ustar 00root root 0000000 0000000
Please send vulnerability reports through [hackerone](https://hackerone.com/github).
move-file-3.0.0/lib/ 0000775 0000000 0000000 00000000000 14322171071 0014141 5 ustar 00root root 0000000 0000000 move-file-3.0.0/lib/index.js 0000664 0000000 0000000 00000011547 14322171071 0015616 0 ustar 00root root 0000000 0000000 const { dirname, join, resolve, relative, isAbsolute } = require('path')
const rimraf_ = require('rimraf')
const { promisify } = require('util')
const {
access: access_,
accessSync,
copyFile: copyFile_,
copyFileSync,
readdir: readdir_,
readdirSync,
rename: rename_,
renameSync,
stat: stat_,
statSync,
lstat: lstat_,
lstatSync,
symlink: symlink_,
symlinkSync,
readlink: readlink_,
readlinkSync,
} = require('fs')
const access = promisify(access_)
const copyFile = promisify(copyFile_)
const readdir = promisify(readdir_)
const rename = promisify(rename_)
const stat = promisify(stat_)
const lstat = promisify(lstat_)
const symlink = promisify(symlink_)
const readlink = promisify(readlink_)
const rimraf = promisify(rimraf_)
const rimrafSync = rimraf_.sync
const mkdirp = require('mkdirp')
const pathExists = async path => {
try {
await access(path)
return true
} catch (er) {
return er.code !== 'ENOENT'
}
}
const pathExistsSync = path => {
try {
accessSync(path)
return true
} catch (er) {
return er.code !== 'ENOENT'
}
}
const moveFile = async (source, destination, options = {}, root = true, symlinks = []) => {
if (!source || !destination) {
throw new TypeError('`source` and `destination` file required')
}
options = {
overwrite: true,
...options,
}
if (!options.overwrite && await pathExists(destination)) {
throw new Error(`The destination file exists: ${destination}`)
}
await mkdirp(dirname(destination))
try {
await rename(source, destination)
} catch (error) {
if (error.code === 'EXDEV' || error.code === 'EPERM') {
const sourceStat = await lstat(source)
if (sourceStat.isDirectory()) {
const files = await readdir(source)
await Promise.all(files.map((file) =>
moveFile(join(source, file), join(destination, file), options, false, symlinks)
))
} else if (sourceStat.isSymbolicLink()) {
symlinks.push({ source, destination })
} else {
await copyFile(source, destination)
}
} else {
throw error
}
}
if (root) {
await Promise.all(symlinks.map(async ({ source: symSource, destination: symDestination }) => {
let target = await readlink(symSource)
// junction symlinks in windows will be absolute paths, so we need to
// make sure they point to the symlink destination
if (isAbsolute(target)) {
target = resolve(symDestination, relative(symSource, target))
}
// try to determine what the actual file is so we can create the correct
// type of symlink in windows
let targetStat = 'file'
try {
targetStat = await stat(resolve(dirname(symSource), target))
if (targetStat.isDirectory()) {
targetStat = 'junction'
}
} catch {
// targetStat remains 'file'
}
await symlink(
target,
symDestination,
targetStat
)
}))
await rimraf(source)
}
}
const moveFileSync = (source, destination, options = {}, root = true, symlinks = []) => {
if (!source || !destination) {
throw new TypeError('`source` and `destination` file required')
}
options = {
overwrite: true,
...options,
}
if (!options.overwrite && pathExistsSync(destination)) {
throw new Error(`The destination file exists: ${destination}`)
}
mkdirp.sync(dirname(destination))
try {
renameSync(source, destination)
} catch (error) {
if (error.code === 'EXDEV' || error.code === 'EPERM') {
const sourceStat = lstatSync(source)
if (sourceStat.isDirectory()) {
const files = readdirSync(source)
for (const file of files) {
moveFileSync(join(source, file), join(destination, file), options, false, symlinks)
}
} else if (sourceStat.isSymbolicLink()) {
symlinks.push({ source, destination })
} else {
copyFileSync(source, destination)
}
} else {
throw error
}
}
if (root) {
for (const { source: symSource, destination: symDestination } of symlinks) {
let target = readlinkSync(symSource)
// junction symlinks in windows will be absolute paths, so we need to
// make sure they point to the symlink destination
if (isAbsolute(target)) {
target = resolve(symDestination, relative(symSource, target))
}
// try to determine what the actual file is so we can create the correct
// type of symlink in windows
let targetStat = 'file'
try {
targetStat = statSync(resolve(dirname(symSource), target))
if (targetStat.isDirectory()) {
targetStat = 'junction'
}
} catch {
// targetStat remains 'file'
}
symlinkSync(
target,
symDestination,
targetStat
)
}
rimrafSync(source)
}
}
module.exports = moveFile
module.exports.sync = moveFileSync
move-file-3.0.0/package.json 0000664 0000000 0000000 00000002124 14322171071 0015660 0 ustar 00root root 0000000 0000000 {
"name": "@npmcli/move-file",
"version": "3.0.0",
"files": [
"bin/",
"lib/"
],
"main": "lib/index.js",
"description": "move a file (fork of move-file)",
"dependencies": {
"mkdirp": "^1.0.4",
"rimraf": "^3.0.2"
},
"devDependencies": {
"@npmcli/eslint-config": "^3.0.1",
"@npmcli/template-oss": "4.5.1",
"tap": "^16.0.1"
},
"scripts": {
"test": "tap",
"snap": "tap",
"lint": "eslint \"**/*.js\"",
"postlint": "template-oss-check",
"template-oss-apply": "template-oss-apply --force",
"lintfix": "npm run lint -- --fix",
"posttest": "npm run lint"
},
"repository": {
"type": "git",
"url": "https://github.com/npm/move-file.git"
},
"tap": {
"check-coverage": true,
"nyc-arg": [
"--exclude",
"tap-snapshots/**"
]
},
"license": "MIT",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
},
"author": "GitHub Inc.",
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
"version": "4.5.1"
}
}
move-file-3.0.0/release-please-config.json 0000664 0000000 0000000 00000001254 14322171071 0020422 0 ustar 00root root 0000000 0000000 {
"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": ""
}
}
}
move-file-3.0.0/test/ 0000775 0000000 0000000 00000000000 14322171071 0014352 5 ustar 00root root 0000000 0000000 move-file-3.0.0/test/async.js 0000664 0000000 0000000 00000020701 14322171071 0016025 0 ustar 00root root 0000000 0000000 const fs = require('fs')
const { join } = require('path')
const t = require('tap')
const moveFile = require('../')
const fixture = '🦄'
t.test('missing `source` or `destination` throws', t => t.rejects(moveFile()))
t.test('move a file', async t => {
const dir = t.testdir({
src: fixture,
})
const dest = `${dir}/dest`
await moveFile(`${dir}/src`, dest)
t.equal(fs.readFileSync(dest, 'utf8'), fixture)
})
t.test('move a directory', async t => {
const dir = t.testdir({
src: {
one: fixture,
two: fixture,
sub: {
three: fixture,
four: fixture,
five: t.fixture('symlink', './four'),
},
link: t.fixture('symlink', './sub'),
},
})
const dest = `${dir}/dest`
await moveFile(`${dir}/src`, dest)
const destStat = fs.statSync(dest)
t.ok(destStat.isDirectory(), 'created a directory')
t.equal(fs.readFileSync(`${dest}/one`, 'utf8'), fixture, 'copied file one')
t.equal(fs.readFileSync(`${dest}/two`, 'utf8'), fixture, 'copied file two')
const subStat = fs.statSync(`${dest}/sub`)
t.ok(subStat.isDirectory(), 'created the subdirectory')
t.equal(fs.readFileSync(`${dest}/sub/three`, 'utf8'), fixture, 'copied file three')
t.equal(fs.readFileSync(`${dest}/sub/four`, 'utf8'), fixture, 'copied file four')
t.ok(fs.lstatSync(`${dest}/sub/five`).isSymbolicLink(), 'created a file symbolic link')
t.equal(fs.realpathSync(`${dest}/sub/five`), join(dest, 'sub/four'), 'created file symlink')
t.equal(fs.readFileSync(`${dest}/sub/five`, 'utf8'), fixture, 'copied file four')
t.ok(fs.lstatSync(`${dest}/link`).isSymbolicLink(), 'created a directory symbolic link')
})
t.test('other types of errors fail', async t => {
const randoError = new Error()
randoError.code = 'ERANDO'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
rename: (s, d, cb) => process.nextTick(() => cb(randoError)),
},
})
const dir = t.testdir({
src: fixture,
})
const dest = `${dir}/dest`
await t.rejects(() => moveFileWithError(`${dir}/src`, dest), randoError)
})
t.test('move a file across devices', async t => {
const exdevError = new Error()
exdevError.code = 'EXDEV'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
rename: (s, d, cb) => process.nextTick(() => cb(exdevError)),
},
})
const dir = t.testdir({
src: fixture,
})
const dest = `${dir}/dest`
await moveFileWithError(`${dir}/src`, dest)
t.equal(fs.readFileSync(dest, 'utf8'), fixture)
})
t.test('move a file across devices (EPERM)', async t => {
const exdevError = new Error()
exdevError.code = 'EPERM'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
rename: (s, d, cb) => process.nextTick(() => cb(exdevError)),
},
})
const dir = t.testdir({
src: fixture,
})
const dest = `${dir}/dest`
await moveFileWithError(`${dir}/src`, dest)
t.equal(fs.readFileSync(dest, 'utf8'), fixture)
})
t.test('move a directory across devices', async t => {
const exdevError = new Error()
exdevError.code = 'EXDEV'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
rename: (s, d, cb) => process.nextTick(() => cb(exdevError)),
},
})
const dir = t.testdir({
src: {
one: fixture,
two: fixture,
sub: {
three: fixture,
four: fixture,
five: t.fixture('symlink', './four'),
reallysub: {
six: t.fixture('symlink', '../../one'),
},
},
link: t.fixture('symlink', './sub'),
abs: t.fixture('symlink', process.cwd()),
},
})
const dest = `${dir}/dest`
await moveFileWithError(`${dir}/src`, dest)
t.ok(fs.statSync(dest).isDirectory(), 'created a directory')
t.equal(fs.readFileSync(`${dest}/one`, 'utf8'), fixture, 'copied file one')
t.equal(fs.readFileSync(`${dest}/two`, 'utf8'), fixture, 'copied file two')
t.ok(fs.statSync(`${dest}/sub`).isDirectory(), 'created the subdirectory')
t.equal(fs.readFileSync(`${dest}/sub/three`, 'utf8'), fixture, 'copied file three')
t.equal(fs.readFileSync(`${dest}/sub/four`, 'utf8'), fixture, 'copied file four')
t.ok(fs.lstatSync(`${dest}/sub/five`).isSymbolicLink(), 'created a file symbolic link')
t.equal(fs.readlinkSync(`${dest}/sub/five`).replace(/\\/g, '/'), './four', 'created file symlink')
t.ok(fs.lstatSync(`${dest}/link`).isSymbolicLink(), 'created a directory symbolic link')
// below assertion varies for windows because junctions are absolute paths
t.equal(
fs.readlinkSync(`${dest}/link`),
process.platform === 'win32' ? join(dest, 'sub\\') : './sub',
'created the directory symbolic link with the correct target'
)
t.ok(fs.lstatSync(`${dest}/sub/reallysub`).isDirectory(), 'created the innermost subdirectory')
t.ok(fs.lstatSync(`${dest}/sub/reallysub/six`).isSymbolicLink(), 'created the innermost symlink')
t.equal(
fs.readlinkSync(`${dest}/sub/reallysub/six`).replace(/\\/g, '/'),
'../../one',
'created the symlink with the appropriate target'
)
t.ok(fs.lstatSync(`${dest}/abs`).isSymbolicLink(), 'created the absolute path symlink')
t.equal(
fs.readlinkSync(`${dest}/abs`),
process.platform === 'win32' ? `${process.cwd()}\\` : process.cwd(),
'kept the correct absolute path'
)
})
t.test('move a directory across devices (EPERM)', async t => {
const exdevError = new Error()
exdevError.code = 'EXDEV'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
rename: (s, d, cb) => process.nextTick(() => cb(exdevError)),
},
})
const dir = t.testdir({
src: {
one: fixture,
two: fixture,
sub: {
three: fixture,
four: fixture,
five: t.fixture('symlink', './four'),
reallysub: {
six: t.fixture('symlink', '../../one'),
},
},
link: t.fixture('symlink', './sub'),
abs: t.fixture('symlink', process.cwd()),
},
})
const dest = `${dir}/dest`
await moveFileWithError(`${dir}/src`, dest)
t.ok(fs.statSync(dest).isDirectory(), 'created a directory')
t.equal(fs.readFileSync(`${dest}/one`, 'utf8'), fixture, 'copied file one')
t.equal(fs.readFileSync(`${dest}/two`, 'utf8'), fixture, 'copied file two')
t.ok(fs.statSync(`${dest}/sub`).isDirectory(), 'created the subdirectory')
t.equal(fs.readFileSync(`${dest}/sub/three`, 'utf8'), fixture, 'copied file three')
t.equal(fs.readFileSync(`${dest}/sub/four`, 'utf8'), fixture, 'copied file four')
t.ok(fs.lstatSync(`${dest}/sub/five`).isSymbolicLink(), 'created a file symbolic link')
t.equal(fs.readlinkSync(`${dest}/sub/five`).replace(/\\/g, '/'), './four', 'created file symlink')
t.ok(fs.lstatSync(`${dest}/link`).isSymbolicLink(), 'created a directory symbolic link')
// below assertion varies for windows because junctions are absolute paths
t.equal(
fs.readlinkSync(`${dest}/link`),
process.platform === 'win32' ? join(dest, 'sub\\') : './sub',
'created the directory symbolic link with the correct target'
)
t.ok(fs.lstatSync(`${dest}/sub/reallysub`).isDirectory(), 'created the innermost subdirectory')
t.ok(fs.lstatSync(`${dest}/sub/reallysub/six`).isSymbolicLink(), 'created the innermost symlink')
t.equal(
fs.readlinkSync(`${dest}/sub/reallysub/six`).replace(/\\/g, '/'),
'../../one',
'created the symlink with the appropriate target'
)
t.ok(fs.lstatSync(`${dest}/abs`).isSymbolicLink(), 'created the absolute path symlink')
t.equal(
fs.readlinkSync(`${dest}/abs`),
process.platform === 'win32' ? `${process.cwd()}\\` : process.cwd(),
'kept the correct absolute path'
)
})
t.test('overwrite option', async t => {
const dir = t.testdir({
src: 'x',
dest: 'y',
})
await t.rejects(moveFile(`${dir}/src`, `${dir}/dest`, { overwrite: false }))
t.equal(fs.readFileSync(`${dir}/dest`, 'utf8'), 'y')
await moveFile(`${dir}/src`, `${dir}/dest`)
t.equal(fs.readFileSync(`${dir}/dest`, 'utf8'), 'x')
})
t.test('overwrite option with non-ENOENT access error', async t => {
const dir = t.testdir({
src: 'x',
})
const er = Object.assign(new Error('its there, just bad'), {
code: 'ETHEREBUTBAD',
})
const moveFileWithError = t.mock('../', {
fs: {
...fs,
access: (p, cb) => process.nextTick(() => cb(er)),
},
})
await t.rejects(moveFileWithError(`${dir}/src`, `${dir}/dest`, { overwrite: false }))
// it actually isn't there tho, so this fails, obviously
t.throws(() => fs.readFileSync(`${dir}/dest`, 'utf8'), 'y')
await moveFileWithError(`${dir}/src`, `${dir}/dest`)
t.equal(fs.readFileSync(`${dir}/dest`, 'utf8'), 'x')
})
move-file-3.0.0/test/sync.js 0000664 0000000 0000000 00000017741 14322171071 0015676 0 ustar 00root root 0000000 0000000 const fs = require('fs')
const { join } = require('path')
const t = require('tap')
const moveFile = require('../')
const fixture = '🦄'
t.test('missing `source` or `destination` throws', async t => t.throws(() => moveFile.sync()))
t.test('move a file', async t => {
const dir = t.testdir({
src: fixture,
})
const dest = `${dir}/dest`
moveFile.sync(`${dir}/src`, dest)
t.equal(fs.readFileSync(dest, 'utf8'), fixture)
})
t.test('move a directory', async t => {
const dir = t.testdir({
src: {
one: fixture,
two: fixture,
sub: {
three: fixture,
four: fixture,
},
},
})
const dest = `${dir}/dest`
moveFile.sync(`${dir}/src`, dest)
const destStat = fs.statSync(dest)
t.ok(destStat.isDirectory(), 'created a directory')
t.equal(fs.readFileSync(`${dest}/one`, 'utf8'), fixture, 'copied file one')
t.equal(fs.readFileSync(`${dest}/two`, 'utf8'), fixture, 'copied file two')
const subStat = fs.statSync(`${dest}/sub`)
t.ok(subStat.isDirectory(), 'created the subdirectory')
t.equal(fs.readFileSync(`${dest}/sub/three`, 'utf8'), fixture, 'copied file three')
t.equal(fs.readFileSync(`${dest}/sub/four`, 'utf8'), fixture, 'copied file four')
})
t.test('move a file across devices', async t => {
const exdevError = new Error()
exdevError.code = 'EXDEV'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
renameSync: () => {
throw exdevError
},
},
})
const dir = t.testdir({
src: fixture,
})
const dest = `${dir}/dest`
moveFileWithError.sync(`${dir}/src`, dest)
t.equal(fs.readFileSync(dest, 'utf8'), fixture)
})
t.test('move a file across devices (EPERM)', async t => {
const exdevError = new Error()
exdevError.code = 'EPERM'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
renameSync: () => {
throw exdevError
},
},
})
const dir = t.testdir({
src: fixture,
})
const dest = `${dir}/dest`
moveFileWithError.sync(`${dir}/src`, dest)
t.equal(fs.readFileSync(dest, 'utf8'), fixture)
})
t.test('move a directory across devices', async t => {
const exdevError = new Error()
exdevError.code = 'EXDEV'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
renameSync: () => {
throw exdevError
},
},
})
const dir = t.testdir({
src: {
one: fixture,
two: fixture,
sub: {
three: fixture,
four: fixture,
five: t.fixture('symlink', './four'),
reallysub: {
six: t.fixture('symlink', '../../one'),
},
},
link: t.fixture('symlink', './sub'),
abs: t.fixture('symlink', process.cwd()),
},
})
const dest = `${dir}/dest`
moveFileWithError.sync(`${dir}/src`, dest)
t.ok(fs.statSync(dest).isDirectory(), 'created a directory')
t.equal(fs.readFileSync(`${dest}/one`, 'utf8'), fixture, 'copied file one')
t.equal(fs.readFileSync(`${dest}/two`, 'utf8'), fixture, 'copied file two')
t.ok(fs.statSync(`${dest}/sub`).isDirectory(), 'created the subdirectory')
t.equal(fs.readFileSync(`${dest}/sub/three`, 'utf8'), fixture, 'copied file three')
t.equal(fs.readFileSync(`${dest}/sub/four`, 'utf8'), fixture, 'copied file four')
t.ok(fs.lstatSync(`${dest}/sub/five`).isSymbolicLink(), 'created a file symbolic link')
t.equal(fs.readlinkSync(`${dest}/sub/five`).replace(/\\/g, '/'), './four', 'created file symlink')
t.ok(fs.lstatSync(`${dest}/link`).isSymbolicLink(), 'created a directory symbolic link')
// below assertion varies for windows because junctions are absolute paths
t.equal(
fs.readlinkSync(`${dest}/link`),
process.platform === 'win32' ? join(dest, 'sub\\') : './sub',
'created the directory symbolic link with the correct target'
)
t.ok(fs.lstatSync(`${dest}/sub/reallysub`).isDirectory(), 'created the innermost subdirectory')
t.ok(fs.lstatSync(`${dest}/sub/reallysub/six`).isSymbolicLink(), 'created the innermost symlink')
t.equal(
fs.readlinkSync(`${dest}/sub/reallysub/six`).replace(/\\/g, '/'),
'../../one',
'created the symlink with the appropriate target'
)
t.ok(fs.lstatSync(`${dest}/abs`).isSymbolicLink(), 'created the absolute path symlink')
t.equal(
fs.readlinkSync(`${dest}/abs`),
process.platform === 'win32' ? `${process.cwd()}\\` : process.cwd(),
'kept the correct absolute path'
)
})
t.test('move a directory across devices (EPERM)', async t => {
const exdevError = new Error()
exdevError.code = 'EXDEV'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
renameSync: () => {
throw exdevError
},
},
})
const dir = t.testdir({
src: {
one: fixture,
two: fixture,
sub: {
three: fixture,
four: fixture,
five: t.fixture('symlink', './four'),
reallysub: {
six: t.fixture('symlink', '../../one'),
},
},
link: t.fixture('symlink', './sub'),
abs: t.fixture('symlink', process.cwd()),
},
})
const dest = `${dir}/dest`
moveFileWithError.sync(`${dir}/src`, dest)
t.ok(fs.statSync(dest).isDirectory(), 'created a directory')
t.equal(fs.readFileSync(`${dest}/one`, 'utf8'), fixture, 'copied file one')
t.equal(fs.readFileSync(`${dest}/two`, 'utf8'), fixture, 'copied file two')
t.ok(fs.statSync(`${dest}/sub`).isDirectory(), 'created the subdirectory')
t.equal(fs.readFileSync(`${dest}/sub/three`, 'utf8'), fixture, 'copied file three')
t.equal(fs.readFileSync(`${dest}/sub/four`, 'utf8'), fixture, 'copied file four')
t.ok(fs.lstatSync(`${dest}/sub/five`).isSymbolicLink(), 'created a file symbolic link')
t.equal(fs.readlinkSync(`${dest}/sub/five`).replace(/\\/g, '/'), './four', 'created file symlink')
t.ok(fs.lstatSync(`${dest}/link`).isSymbolicLink(), 'created a directory symbolic link')
// below assertion varies for windows because junctions are absolute paths
t.equal(
fs.readlinkSync(`${dest}/link`),
process.platform === 'win32' ? join(dest, 'sub\\') : './sub',
'created the directory symbolic link with the correct target'
)
t.ok(fs.lstatSync(`${dest}/sub/reallysub`).isDirectory(), 'created the innermost subdirectory')
t.ok(fs.lstatSync(`${dest}/sub/reallysub/six`).isSymbolicLink(), 'created the innermost symlink')
t.equal(
fs.readlinkSync(`${dest}/sub/reallysub/six`).replace(/\\/g, '/'),
'../../one',
'created the symlink with the appropriate target'
)
t.ok(fs.lstatSync(`${dest}/abs`).isSymbolicLink(), 'created the absolute path symlink')
t.equal(
fs.readlinkSync(`${dest}/abs`),
process.platform === 'win32' ? `${process.cwd()}\\` : process.cwd(),
'kept the correct absolute path'
)
})
t.test('other types of errors fail', async t => {
const randoError = new Error()
randoError.code = 'ERANDO'
const moveFileWithError = t.mock('../', {
fs: {
...fs,
renameSync: () => {
throw randoError
},
},
})
const dir = t.testdir({
src: fixture,
})
const dest = `${dir}/dest`
t.throws(() => moveFileWithError.sync(`${dir}/src`, dest), randoError)
})
t.test('overwrite option', async t => {
const dir = t.testdir({
src: 'x',
dest: 'y',
})
t.throws(() => moveFile.sync(`${dir}/src`, `${dir}/dest`, { overwrite: false }))
t.equal(fs.readFileSync(`${dir}/dest`, 'utf8'), 'y')
moveFile.sync(`${dir}/src`, `${dir}/dest`)
t.equal(fs.readFileSync(`${dir}/dest`, 'utf8'), 'x')
})
t.test('overwrite option with non-ENOENT access error', async t => {
const dir = t.testdir({
src: 'x',
})
const er = Object.assign(new Error('its there, just bad'), {
code: 'ETHEREBUTBAD',
})
const moveFileWithError = t.mock('../', {
fs: {
...fs,
accessSync: () => {
throw er
},
},
})
t.throws(() => moveFileWithError.sync(`${dir}/src`, `${dir}/dest`, { overwrite: false }))
// it actually isn't there tho, so this fails, obviously
t.throws(() => fs.readFileSync(`${dir}/dest`, 'utf8'), 'y')
moveFileWithError.sync(`${dir}/src`, `${dir}/dest`)
t.equal(fs.readFileSync(`${dir}/dest`, 'utf8'), 'x')
})