safe-rm 3.1.3 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/rm.sh CHANGED
@@ -490,7 +490,11 @@ do_trash(){
490
490
 
491
491
 
492
492
  get_absolute_path(){
493
- echo $(cd "$(dirname "$1")" && pwd)/$(basename "$1")
493
+ local dir
494
+ local base
495
+ dir=$(cd "$(dirname -- "$1")" && pwd)
496
+ base=$(basename -- "$1")
497
+ printf '%s/%s\n' "$dir" "$base"
494
498
  }
495
499
 
496
500
 
@@ -601,7 +605,7 @@ check_target_to_move(){
601
605
  mac_trash(){
602
606
  check_target_to_move "$1"
603
607
  local move=$_to_move
604
- local base=$(basename "$move")
608
+ local base=$(basename -- "$move")
605
609
 
606
610
  # foo.jpg => "foo" + ".jpg"
607
611
  # foo => "foo" + ""
@@ -623,7 +627,7 @@ mac_trash(){
623
627
  [[ "$OPT_VERBOSE" == 1 ]] && list_files "$1"
624
628
 
625
629
  debug "$LINENO: mv $move to $trash_path"
626
- mv "$move" "$trash_path"
630
+ mv -- "$move" "$trash_path"
627
631
  local status=$?
628
632
 
629
633
  [[ "$_traveled" == 1 ]] && cd "$__DIRNAME" &> /dev/null
@@ -672,7 +676,7 @@ check_linux_trash_base(){
672
676
  linux_trash(){
673
677
  check_target_to_move "$1"
674
678
  local move=$_to_move
675
- local base=$(basename "$move")
679
+ local base=$(basename -- "$move")
676
680
 
677
681
  base=$(check_linux_trash_base "$base")
678
682
 
@@ -682,7 +686,7 @@ linux_trash(){
682
686
 
683
687
  # Move the target into the trash
684
688
  debug "$LINENO: mv $move to $trash_path"
685
- mv "$move" "$trash_path"
689
+ mv -- "$move" "$trash_path"
686
690
  local move_status=$?
687
691
 
688
692
  if [[ $move_status -ne 0 ]]; then
@@ -763,28 +767,20 @@ for file in "${FILE_NAME[@]}"; do
763
767
  fi
764
768
 
765
769
  # the same check also apply on /. /..
766
- if [[ $(basename "$file") == "." || $(basename "$file") == ".." ]]; then
770
+ if [[ $(basename -- "$file") == "." || $(basename -- "$file") == ".." ]]; then
767
771
  error "$COMMAND: \".\" and \"..\" may not be removed"
768
772
  EXIT_CODE=1
769
773
  continue
770
774
  fi
771
775
 
772
- # deal with wildcard and also, redirect error output
773
- ls_result=$(ls -d "$file" 2> /dev/null)
776
+ if [[ -e "$file" || -L "$file" ]]; then
777
+ remove "$file"
778
+ status=$?
779
+ debug "$LINENO: remove returned status: $status"
774
780
 
775
- # debug
776
- debug "$LINENO: ls_result: $ls_result"
777
-
778
- if [[ -n "$ls_result" ]]; then
779
- for file in "$ls_result"; do
780
- remove "$file"
781
- status=$?
782
- debug "$LINENO: remove returned status: $status"
783
-
784
- if [[ ! $status == 0 ]]; then
785
- EXIT_CODE=1
786
- fi
787
- done
781
+ if [[ ! $status == 0 ]]; then
782
+ EXIT_CODE=1
783
+ fi
788
784
  elif [[ -z "$OPT_FORCE" ]]; then
789
785
  error "$COMMAND: $file: No such file or directory" >&2
790
786
  EXIT_CODE=1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safe-rm",
3
- "version": "3.1.3",
3
+ "version": "3.1.4",
4
4
  "description": "A much safer replacement of bash rm with nearly full functionalities and options of the rm command!",
5
5
  "bin": {
6
6
  "safe-rm": "./bin/rm.sh"
package/test/cases.js CHANGED
@@ -447,4 +447,124 @@ fi
447
447
  t.false(await pathExists(link), 'symlink should be removed')
448
448
  t.true(await pathExists(target), 'target file should remain')
449
449
  })
450
+
451
+ !is_as(type) && test(`removes a dangling symlink`, async t => {
452
+ const {
453
+ source_path,
454
+ runRm
455
+ } = t.context
456
+
457
+ const missingTarget = path.join(source_path, 'missing-target')
458
+ const link = path.join(source_path, 'dangling_sym')
459
+ await fs.symlink(missingTarget, link)
460
+
461
+ const before = await fs.lstat(link)
462
+ t.true(before.isSymbolicLink(), 'should create symlink before remove')
463
+
464
+ const result = await runRm([link])
465
+
466
+ t.is(result.code, 0, 'exit code should be 0')
467
+ await t.throwsAsync(async () => fs.lstat(link), {
468
+ code: 'ENOENT'
469
+ })
470
+ })
471
+
472
+ !is_as(type) && test(`-r should not dereference a directory symlink`, async t => {
473
+ const {
474
+ createDir,
475
+ createFile,
476
+ runRm,
477
+ pathExists
478
+ } = t.context
479
+
480
+ const realDir = await createDir({
481
+ name: 'real-dir'
482
+ })
483
+
484
+ const keep = await createFile({
485
+ name: 'keep',
486
+ under: realDir
487
+ })
488
+
489
+ const link = path.join(path.dirname(realDir), 'real-dir-sym')
490
+ await fs.symlink(realDir, link)
491
+
492
+ const result = await runRm(['-r', link])
493
+
494
+ t.is(result.code, 0, 'exit code should be 0')
495
+ await t.throwsAsync(async () => fs.lstat(link), {
496
+ code: 'ENOENT'
497
+ })
498
+ t.true(await pathExists(realDir), 'target directory should remain')
499
+ t.true(await pathExists(keep), 'target content should remain')
500
+ })
501
+
502
+ !is_as(type) && test(`-ri should not dereference a directory symlink`, async t => {
503
+ const {
504
+ createDir,
505
+ createFile,
506
+ runRm,
507
+ pathExists
508
+ } = t.context
509
+
510
+ const realDir = await createDir({
511
+ name: 'real-dir-i'
512
+ })
513
+
514
+ const keep = await createFile({
515
+ name: 'keep-i',
516
+ under: realDir
517
+ })
518
+
519
+ const link = path.join(path.dirname(realDir), 'real-dir-sym-i')
520
+ await fs.symlink(realDir, link)
521
+
522
+ const result = await runRm(['-ri', link], {
523
+ input: ['y']
524
+ })
525
+
526
+ t.is(result.code, 0, 'exit code should be 0')
527
+ await t.throwsAsync(async () => fs.lstat(link), {
528
+ code: 'ENOENT'
529
+ })
530
+ t.true(await pathExists(realDir), 'target directory should remain')
531
+ t.true(await pathExists(keep), 'target content should remain')
532
+ })
533
+
534
+ !is_as(type) && test(`removes a file prefixed with "-" after --`, async t => {
535
+ const {
536
+ source_path,
537
+ createFile,
538
+ runRm,
539
+ pathExists
540
+ } = t.context
541
+
542
+ const name = '-dash-file'
543
+ await createFile({name})
544
+
545
+ const result = await runRm(['--', name], {
546
+ cwd: source_path
547
+ })
548
+
549
+ t.is(result.code, 0, 'exit code should be 0')
550
+ t.false(await pathExists(name), 'file should be removed')
551
+ })
552
+
553
+ !is_as(type) && test(`removes a file with newline in filename`, async t => {
554
+ const {
555
+ createFile,
556
+ runRm,
557
+ pathExists
558
+ } = t.context
559
+
560
+ const filename = 'line1\nline2'
561
+ const filepath = await createFile({
562
+ name: filename
563
+ })
564
+
565
+ const result = await runRm([filepath])
566
+
567
+ t.is(result.code, 0, 'exit code should be 0')
568
+ t.false(await pathExists(filepath), 'file should be removed')
569
+ })
450
570
  }
package/test/helper.js CHANGED
@@ -60,7 +60,8 @@ const generateContextMethods = (
60
60
  function runRm (args, {
61
61
  input = [],
62
62
  command = rm_command,
63
- env: arg_env = {}
63
+ env: arg_env = {},
64
+ cwd
64
65
  } = {}) {
65
66
  return new Promise((resolve, reject) => {
66
67
  const env = {
@@ -73,7 +74,8 @@ const generateContextMethods = (
73
74
  }
74
75
 
75
76
  const child = spawn(command, args, {
76
- env
77
+ env,
78
+ cwd
77
79
  })
78
80
  let stdout = ''
79
81
  let stderr = ''