renamr 1.0.15 → 1.0.16

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b39e4e5a0e8eb0a2858888181609bcdddfdc71ab315de810bb7c23b6fb626ff0
4
- data.tar.gz: 40d581dd0b0351db79c896ced04446bf5cf5d2af0ec2ae186f044bb499b09cff
3
+ metadata.gz: aa2277535f12269fea504e41087d5d20d762ccec138969cac71f399fa845b0f2
4
+ data.tar.gz: 9eae0471d031870cc7a44586d5634b4f1e31464c1b573dd923e1bbb9207c7108
5
5
  SHA512:
6
- metadata.gz: 03b888d15545d19a1e7ad552ebf416d51cf0d0c8dd3c11a547e2b07d467aa733bc64b888340aa7886136d1eadae811b2210db973f38e6c6f4301756c22daa83d
7
- data.tar.gz: ad1d1388214aa414ee34fa7f73823f82ff240d31695453fb920f09a218aa8c144754b38f669c7b4f06f43735719e8b1433cb32447d5994a1528847abb01a4e34
6
+ metadata.gz: bfc1abe2a3672e9461e40fde27bc58d5d0b0a9f91fce0c37f77d7132adcdf2787914d8f5b2fccbde8da53425626743e627b329633f9435eda870cdf171cce0bf
7
+ data.tar.gz: '095378848bee64538adcc2979b54b75527643060ed226390c7dfb476be82b347e4fcb8ec35f52f8a2c1d508b343942173b8c4ca530086b9e7c1e4794c3a091e0'
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2020-2025 David Rabkin
1
+ Copyright 2020-2026 David Rabkin
2
2
 
3
3
  Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
4
4
 
data/README.adoc CHANGED
@@ -8,7 +8,6 @@
8
8
  :img-rake: https://github.com/rdavid/renamr/actions/workflows/rake.yml/badge.svg
9
9
  :img-rubocop: https://github.com/rdavid/renamr/actions/workflows/rubocop.yml/badge.svg
10
10
  :img-style: https://img.shields.io/badge/code_style-rubocop-brightgreen.svg
11
- :img-test: https://github.com/rdavid/renamr/actions/workflows/test.yml/badge.svg
12
11
  :url-cv: http://cv.rabkin.co.il
13
12
  :url-gem: https://badge.fury.io/rb/renamr
14
13
  :url-hoc: https://hitsofcode.com/view/github/rdavid/renamr?branch=master
@@ -18,7 +17,6 @@
18
17
  :url-rubocop: https://github.com/rdavid/renamr/actions/workflows/rubocop.yml
19
18
  :url-ruby: https://www.ruby-lang.org/en/documentation/installation
20
19
  :url-style: https://github.com/rubocop/rubocop
21
- :url-test: https://github.com/rdavid/renamr/actions/workflows/test.yml
22
20
  :url-vale: https://vale.sh
23
21
  :url-yamllint: https://github.com/adrienverge/yamllint
24
22
 
@@ -28,7 +26,6 @@ image:{img-rake}[rake,link={url-rake}]
28
26
  image:{img-rubocop}[rubocop,link={url-rubocop}]
29
27
  image:{img-gem}[gem version,link={url-gem}]
30
28
  image:{img-style}[code style,link={url-style}]
31
- image:{img-test}[test,link={url-test}]
32
29
  image:{img-hoc}[hits of code,link={url-hoc}]
33
30
  image:{img-license}[license,link={url-license}]
34
31
 
@@ -36,16 +33,17 @@ toc::[]
36
33
 
37
34
  == About
38
35
 
39
- `renamr` organizes file and directory names.
36
+ `renamr` normalizes file and directory names.
37
+ It rewrites them with lowercase English letters, digits, and hyphens in place
38
+ of spaces and other symbols.
40
39
 
41
40
  == Installation
42
- The tool is designed to operate on macOS, GNU/Linux, Windows, and Unix-like
43
- operating systems.
44
- It is packaged as a Gem and requires Ruby version 3.2 or later.
45
- If you do not have the appropriate version on your platform, refer to
46
- {url-ruby}[Installing Ruby].
41
+ The tool runs on macOS, GNU/Linux, and other Unix-like operating systems, as
42
+ well as Windows.
43
+ It is packaged as a Ruby gem and requires Ruby 3.2 or later.
44
+ If your platform lacks a suitable Ruby, see {url-ruby}[Installing Ruby].
47
45
 
48
- Utilize this command for installing the package:
46
+ Install the gem with:
49
47
 
50
48
  [,sh]
51
49
  ----
@@ -54,7 +52,7 @@ gem install renamr
54
52
 
55
53
  == Updating
56
54
 
57
- Utilize this command for updating the package:
55
+ Update the gem with:
58
56
 
59
57
  [,sh]
60
58
  ----
@@ -66,17 +64,17 @@ gem update renamr
66
64
  [,sh]
67
65
  ----
68
66
  renamr [options]
69
- -a, --act Real renaming.
70
- -r, --rec Passes recursively.
71
- -l, --lim Limits name length.
72
- -m, --mod Prepends modification time.
73
- -d, --dir dir Directory to rename.
74
- -s, --src src A string to substitute.
75
- -t, --dst dst A string to replace to.
76
- -w, --wid wid Width of the table.
77
- -p, --pre str,beg A string to prepend to started from beg.
78
- -c, --cut pos,len Removes len symbols from pos.
79
- -v, --version Shows version.
67
+ -a, --act Performs actual renaming.
68
+ -c, --cut pos,len Removes len characters starting at pos.
69
+ -d, --dir dir Directory to process.
70
+ -l, --lim Limits file name length.
71
+ -m, --mod Prepends file modification time.
72
+ -p, --prepend str,beg Prepends a string.
73
+ -r, --rec Processes directories recursively.
74
+ -s, --src src String to replace.
75
+ -t, --dst dst Replacement string.
76
+ -v, --version Shows the version.
77
+ -w, --wid wid Output table width.
80
78
  ----
81
79
 
82
80
  == Example
@@ -86,9 +84,12 @@ renamr [options]
86
84
  renamr -d <source>
87
85
  ----
88
86
 
89
- It renames all files in `source` by default pattern: 26 English letters, 10 numbers, minus for spaces and other symbols.
87
+ This previews new names for all files in `source` using the default character
88
+ set: the 26 English letters, 10 digits, and hyphens in place of spaces and
89
+ other symbols.
90
+ Adding `-a` performs the actual renaming.
90
91
 
91
92
  == License
92
93
 
93
- `renamr` is copyright {url-cv}[David Rabkin] and available under a
94
+ `renamr` is copyright {url-cv}[David Rabkin] and is available under the
94
95
  {url-license}[Zero-Clause BSD license].
data/bin/renamr CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # vi:ts=2 sw=2 tw=79 et lbr wrap
5
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
4
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
5
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
6
6
  # SPDX-License-Identifier: 0BSD
7
7
  #
8
- # This script renames files in given directory by specific rules.
8
+ # Renames files in a directory using configured rules.
9
9
 
10
10
  require_relative '../lib/renamr'
11
11
 
data/lib/renamr/action.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  module Renamr
8
- # An interface for actions implementation.
8
+ # Defines the interface for action implementations.
9
9
  class Action
10
10
  def do(src)
11
- raise "Undefined method Action.do is called with #{src}."
11
+ raise "Action.do must be overridden, called with #{src}."
12
12
  end
13
13
 
14
14
  def set(src) end
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # Checks if the resulted string has only ASCII symbols.
10
+ # Checks whether the resulting string contains only ASCII characters.
11
11
  class ASCIIValidatorAction < Action
12
12
  def do(src)
13
13
  ascii = src.chars.select(&:ascii_only?).join
14
- raise "String #{src} has non-ASCII symbols." if src != ascii
14
+ raise "String #{src} contains non-ASCII characters." if src != ascii
15
15
 
16
16
  src
17
17
  end
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require 'i18n'
8
8
  require_relative 'action'
9
9
 
10
10
  module Renamr
11
- # Automatic localization.
11
+ # Performs automatic localization using I18n transliteration.
12
12
  class AutoLocalizationAction < Action
13
13
  def initialize
14
- super()
14
+ super
15
15
  I18n.config.available_locales = :en
16
16
  end
17
17
 
data/lib/renamr/char.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # All special symbols besides some (., &, $) are replaced by minus.
10
+ # Replaces special symbols with hyphens, except `.`, `&`, and `$`.
11
11
  class CharAction < Action
12
12
  SYM = ' (){},~–\'![]_#@=„“”"`—+‘’;·‡«»%…'.chars.to_set.freeze
13
13
 
@@ -1,57 +1,66 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require 'optparse'
8
8
 
9
9
  module Renamr
10
- # Handles input parameters.
10
+ # Parses and validates command-line options.
11
11
  class Configurator
12
12
  DIC = [
13
- ['-a', '--act', 'Real renaming.', :act],
14
- ['-r', '--rec', 'Passes recursively.', :rec],
15
- ['-l', '--lim', 'Limits name length.', :lim],
16
- ['-m', '--mod', 'Prepends modification time.', :mod],
17
- ['-d', '--dir dir', 'Directory to rename.', :dir],
18
- ['-s', '--src src', 'A string to substitute.', :src],
19
- ['-t', '--dst dst', 'A string to replace to.', :dst],
20
- ['-w', '--wid wid', 'Width of the table.', :wid]
13
+ ['-a', '--act', 'Performs actual renaming.', :act],
14
+ ['-d', '--dir dir', 'Directory to process.', :dir],
15
+ ['-l', '--lim', 'Limits file name length.', :lim],
16
+ ['-m', '--mod', 'Prepends file modification time.', :mod],
17
+ ['-r', '--rec', 'Processes directories recursively.', :rec],
18
+ ['-s', '--src src', 'String to replace.', :src],
19
+ ['-t', '--dst dst', 'Replacement string.', :dst],
20
+ ['-w', '--wid wid', 'Output table width.', :wid]
21
21
  ].freeze
22
22
 
23
+ def add_simple(opt, key)
24
+ f, p, d = DIC.find { |_, _, _, k| k == key }
25
+ opt.on(f, p, d) { |i| @options[key] = i }
26
+ end
27
+
23
28
  def add_cut(opt)
24
- opt.on('-c', '--cut pos,len', Array, 'Removes symbols from pos.') do |l|
29
+ msg = 'Removes len characters starting at pos.'
30
+ opt.on('-c', '--cut pos,len', Array, msg) do |l|
25
31
  @options[:pos] = l[0]
26
32
  @options[:len] = l[1]
27
33
  end
28
34
  end
29
35
 
30
36
  def add_prepend(opt)
31
- opt.on('-p', '--prepend str,beg', Array, 'Prepend a string.') do |l|
37
+ opt.on('-p', '--prepend str,beg', Array, 'Prepends a string.') do |l|
32
38
  @options[:pre] = l[0]
33
39
  @options[:beg] = l[1].nil? ? 0 : l[1].to_i
34
40
  end
35
41
  end
36
42
 
37
43
  def add_version(opt)
38
- opt.on('-v', '--version', 'Show version.') do
44
+ opt.on('-v', '--version', 'Shows the version.') do
39
45
  puts "#{File.basename($PROGRAM_NAME)} #{VERSION} #{DATE}"
40
46
  exit
41
47
  end
42
48
  end
43
49
 
44
50
  def add(opt)
51
+ add_simple(opt, :act)
45
52
  add_cut(opt)
53
+ %i[dir lim mod].each { |k| add_simple(opt, k) }
46
54
  add_prepend(opt)
55
+ %i[rec src dst].each { |k| add_simple(opt, k) }
47
56
  add_version(opt)
57
+ add_simple(opt, :wid)
48
58
  end
49
59
 
50
60
  def initialize
51
61
  @options = {}
52
62
  OptionParser.new do |o|
53
63
  o.banner = "Usage: #{File.basename($PROGRAM_NAME)} [options]."
54
- DIC.each { |f, p, d, k| o.on(f, p, d) { |i| @options[k] = i } }
55
64
  add(o)
56
65
  end.parse!
57
66
  validate
@@ -65,7 +74,7 @@ module Renamr
65
74
 
66
75
  @options[:dir] = File.expand_path(dir)
67
76
  end
68
- raise "Width of the table should exceeds 14 symbols: #{wid}." if wid < 15
77
+ raise "Table width must be at least 15 characters: #{wid}." if wid < 15
69
78
  end
70
79
 
71
80
  def act?
@@ -114,7 +123,8 @@ module Renamr
114
123
 
115
124
  def wid
116
125
  if @options[:wid].nil?
117
- # Reads current terminal width.
126
+
127
+ # Reads the current terminal width.
118
128
  wid = `tput cols`
119
129
  wid.to_s.empty? ? 79 : wid.to_i
120
130
  else
data/lib/renamr/date.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require 'date'
8
8
  require_relative 'action'
9
9
 
10
10
  module Renamr
11
- # Replaces any valid date, e.g. 2020-11-02 or 02-11-2020 with 20201102.
11
+ # Replaces valid dates (for example, 2020-11-02 or 02-11-2020) with 20201102.
12
12
  class DateAction < Action
13
13
  REG = /(\d+)-(\d+)-(\d+)/
14
14
  PAT = ['%m-%d-%Y', '%d-%m-%Y', '%Y-%m-%d', '%Y-%d-%m'].freeze
@@ -25,7 +25,7 @@ module Renamr
25
25
  PAT.each do |pat|
26
26
  return Date.strptime(sub, pat)
27
27
  rescue ArgumentError
28
- # Nothing to do.
28
+ # Tries the next date pattern.
29
29
  end
30
30
  nil
31
31
  end
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # All names should be downcased.
10
+ # Converts names to lowercase.
11
11
  class DowncaseAction < Action
12
12
  def do(src)
13
13
  src.downcase
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'ascii_validator'
@@ -21,15 +21,15 @@ require_relative 'trim'
21
21
  require_relative 'truncate'
22
22
 
23
23
  module Renamr
24
- # Produces actions for certain directories.
24
+ # Builds an action pipeline for a directory.
25
25
  class ActionsFactory
26
- LIMIT = 143 # Synology eCryptfs limitation.
26
+ LIMIT = 143 # Matches the Synology eCryptfs limitation.
27
27
 
28
28
  def initialize(cfg)
29
29
  @cfg = cfg
30
30
  end
31
31
 
32
- def produce(dir) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
32
+ def produce(dir) # rubocop:disable Metrics/AbcSize
33
33
  if @cfg.lim?
34
34
  [
35
35
  OmitAction.new(LIMIT),
@@ -37,7 +37,7 @@ module Renamr
37
37
  ]
38
38
  else
39
39
  [
40
- PointAction.new(dir), # Should be the first.
40
+ PointAction.new(dir), # Runs first.
41
41
  @cfg.pos.nil? ? nil : RemoveAction.new(@cfg.pos, @cfg.len),
42
42
  @cfg.src.nil? ? nil : SubstituteAction.new(@cfg.src, @cfg.dst),
43
43
  ManualLocalizationAction.new,
@@ -1,25 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # Manual localization.
10
+ # Transliterates accented Latin characters to their ASCII equivalents.
11
11
  class ManualLocalizationAction < Action
12
- SRC = 'ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđ'\
13
- 'ÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏ'\
14
- 'ìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅ'\
15
- 'ņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝ'\
16
- 'ŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝ'\
12
+ SRC = 'ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđ' \
13
+ 'ÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏ' \
14
+ 'ìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅ' \
15
+ 'ņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝ' \
16
+ 'ŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝ' \
17
17
  'ýÿŶŷŸŹźŻżŽž'
18
- DST = 'AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDd'\
19
- 'EEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIII'\
20
- 'iiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnN'\
21
- 'nNnnNnOOOOOOooooooOoOoOoRrRrRrSsSs'\
22
- 'SsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwY'\
18
+ DST = 'AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDd' \
19
+ 'EEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIII' \
20
+ 'iiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnN' \
21
+ 'nNnnNnOOOOOOooooooOoOoOoRrRrRrSsSs' \
22
+ 'SsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwY' \
23
23
  'yyYyYZzZzZz'
24
24
 
25
25
  def do(src)
data/lib/renamr/omit.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # Omits file names shorter than limit.
10
+ # Skips file names shorter than the limit.
11
11
  class OmitAction < Action
12
12
  def initialize(lim)
13
13
  super()
data/lib/renamr/point.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # All points besides extension are replaced by minus.
10
+ # Replaces dots with hyphens, except for the file extension separator.
11
11
  class PointAction < Action
12
12
  def initialize(dir)
13
13
  super()
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # Prepends user patter.
10
+ # Inserts a user-provided string at the given position.
11
11
  class PrependAction < Action
12
12
  def initialize(beg, pre) # rubocop:disable Lint/MissingSuper
13
13
  raise 'beg cannot be nil.' if beg.nil?
14
- raise 'ins cannot be nil.' if pre.nil?
14
+ raise 'pre cannot be nil.' if pre.nil?
15
15
 
16
16
  @beg = beg
17
17
  @pre = pre
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # Prepends file modification datestamp.
10
+ # Prepends the file modification date.
11
11
  class PrependDateAction < Action
12
12
  def initialize(dir)
13
13
  super()
data/lib/renamr/remove.rb CHANGED
@@ -1,28 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # Removes symbols between left and right positions.
10
+ # Removes a substring by 1-based position and length.
11
11
  class RemoveAction < Action
12
12
  def initialize(pos, len)
13
13
  super()
14
- raise 'len cannot bi nil.' if len.nil?
14
+ raise 'len cannot be nil.' if len.nil?
15
+ raise 'len must be positive.' unless len.to_i.positive?
15
16
  raise 'pos cannot be nil.' if pos.nil?
16
- raise 'pos has to be positive.' unless pos.to_i.positive?
17
+ raise 'pos must be positive.' unless pos.to_i.positive?
17
18
 
18
19
  @pos = pos.to_i
19
20
  @len = len.to_i
20
21
  end
21
22
 
22
23
  def do(src)
23
- return src[@len..] if @pos == 1
24
-
25
- src[0..@pos - 1] + src[@pos + @len..]
24
+ src[0...(@pos - 1)] + (src[(@pos - 1 + @len)..] || '')
26
25
  end
27
26
  end
28
27
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require 'fileutils'
@@ -10,7 +10,7 @@ require_relative 'factory'
10
10
  require_relative 'reporter'
11
11
 
12
12
  module Renamr
13
- # Renames file by certain rules.
13
+ # Renames files using configured rules.
14
14
  class Renamer
15
15
  def initialize
16
16
  @cfg = Configurator.new
@@ -29,20 +29,21 @@ module Renamr
29
29
  rep.add(File.basename(src), File.basename(dst))
30
30
  rescue StandardError => e
31
31
  rep.add(File.basename(src), e)
32
- puts e.backtrace.join("\n\t")
33
- .sub("\n\t", ": #{e}#{e.class ? " (#{e.class})" : ''}\n\t")
32
+ msg = ": #{e}"
33
+ msg += " (#{e.class})" if e.class
34
+ msg += "\n\t#{e.backtrace.join("\n\t")}"
35
+ puts msg
34
36
  end
35
37
  end
36
38
  rep.do
37
39
  end
38
40
 
39
41
  def unique(dat, nme)
40
- dst = []
41
- dat.each { |_, d| dst << File.basename(d) } # rubocop:disable Style/HashEachMethods
42
+ dst = dat.map { |_, d| File.basename(d) }
42
43
  return nme unless dst.include?(nme)
43
44
 
44
45
  ext = File.extname(nme)
45
- 0.step do |i| # Infinitive loop with index.
46
+ 0.step do |i| # Iterates indefinitely with an index.
46
47
  n = ext.nil? ? "#{nme}-#{i}" : "#{File.basename(nme, ext)}-#{i}#{ext}"
47
48
  return n unless dst.include?(n)
48
49
  end
@@ -53,7 +54,8 @@ module Renamr
53
54
 
54
55
  dat = []
55
56
  act = @fac.produce(dir)
56
- # Doesn't include hidden files.
57
+
58
+ # Skips hidden files.
57
59
  Dir.entries(dir).reject { |f| f.start_with?('.') }.sort.each do |nme|
58
60
  src = File.join(dir, nme)
59
61
  do_dir(src) if @cfg.rec? && File.directory?(src)
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require 'terminal-table'
8
8
  require_relative 'action'
9
+ require_relative 'timer'
9
10
  require_relative 'utils'
10
11
 
11
12
  module Renamr
12
- # Formats and prints output data.
13
+ # Formats and prints rename results.
13
14
  # rubocop:disable Style/ClassVars
14
15
  class Reporter
15
16
  @@tim = Timer.new
data/lib/renamr/rutoen.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # Substitutes a string with a string.
10
+ # Replaces one string with another.
11
11
  class SubstituteAction < Action
12
12
  def initialize(src, dst)
13
13
  super()
14
14
  raise 'src cannot be nil.' if src.nil?
15
15
 
16
- # The action works after PointAction. All points are replaces with minus.
16
+ # This action runs after PointAction, so dots are already hyphens.
17
17
  @src = p2m(src)
18
18
  @dst = dst.nil? ? '-' : p2m(dst)
19
19
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2026 David Rabkin
5
+ # SPDX-License-Identifier: 0BSD
6
+
7
+ # Measures elapsed time and reports it in a human-readable form.
8
+ class Timer
9
+ DIC = [
10
+ [60, :seconds, :second],
11
+ [60, :minutes, :minute],
12
+ [24, :hours, :hour],
13
+ [1000, :days, :day]
14
+ ].freeze
15
+
16
+ def initialize
17
+ @sta = Time.now
18
+ end
19
+
20
+ def read
21
+ humanize(Time.now - @sta)
22
+ end
23
+
24
+ def humanize(sec)
25
+ return 'less than a second' if sec < 1
26
+
27
+ DIC.filter_map do |cnt, nms, nm1|
28
+ next if sec <= 0
29
+
30
+ sec, n = sec.divmod(cnt)
31
+ next if n.to_i.zero?
32
+
33
+ "#{n.to_i} #{n.to_i == 1 ? nm1 : nms}"
34
+ end.reverse.join(' ')
35
+ end
36
+ end
data/lib/renamr/trim.rb CHANGED
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # Replaces multiple minuses to single. Trims minuses.
10
+ # Collapses consecutive hyphens and removes hyphens next to dots and at
11
+ # the edges.
11
12
  class TrimAction < Action
12
13
  def do(src)
13
- src.gsub!(/-+/, '-')
14
+ src.squeeze!('-')
14
15
  src.gsub!('-.', '.')
15
16
  src.gsub!('.-', '.')
16
17
  src.gsub!(/^-|-$/, '') unless src == '-'
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'action'
8
8
 
9
9
  module Renamr
10
- # Limits file length.
10
+ # Truncates file names that exceed the length limit, preserving the
11
+ # extension.
11
12
  class TruncateAction < Action
12
13
  def initialize(lim)
13
14
  super()
@@ -21,7 +22,7 @@ module Renamr
21
22
 
22
23
  ext = File.extname(src)
23
24
  len = ext.length
24
- dst = len >= @lim ? ext[0..@lim - 1] : src[0..@lim - 1 - len] << ext
25
+ dst = len >= @lim ? ext[0..(@lim - 1)] : src[0..(@lim - 1 - len)] << ext
25
26
  dst.gsub!(/-$/, '')
26
27
  dst.gsub!('-.', '.')
27
28
  dst
data/lib/renamr/utils.rb CHANGED
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require 'ellipsized'
8
8
 
9
- # All methods are static.
9
+ # Provides utility methods.
10
10
  class Utils
11
11
  class << self
12
12
  def trim(src, lim)
@@ -14,32 +14,3 @@ class Utils
14
14
  end
15
15
  end
16
16
  end
17
-
18
- # Returns string with humanized time interval.
19
- class Timer
20
- DIC = [
21
- [60, :seconds, :second],
22
- [60, :minutes, :minute],
23
- [24, :hours, :hour],
24
- [1000, :days, :day]
25
- ].freeze
26
-
27
- def initialize
28
- @sta = Time.now
29
- end
30
-
31
- def read
32
- humanize(Time.now - @sta)
33
- end
34
-
35
- def humanize(sec)
36
- return 'less than a second' if sec < 1
37
-
38
- DIC.map do |cnt, nms, nm1|
39
- next if sec <= 0
40
-
41
- sec, n = sec.divmod(cnt)
42
- "#{n.to_i} #{n.to_i != 1 ? nms : nm1}"
43
- end.compact.reverse.join(' ')
44
- end
45
- end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2020-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2020-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  module Renamr
8
- VERSION = '1.0.15'
9
- DATE = '2025-07-23'
8
+ VERSION = '1.0.16'
9
+ DATE = '2026-07-12'
10
10
  end
data/lib/renamr.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2018-2025 David Rabkin
3
+ # vi: et lbr sw=2 ts=2 tw=79 wrap
4
+ # SPDX-FileCopyrightText: 2018-2026 David Rabkin
5
5
  # SPDX-License-Identifier: 0BSD
6
6
 
7
7
  require_relative 'renamr/renamer'
metadata CHANGED
@@ -1,15 +1,60 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renamr
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.15
4
+ version: 1.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Rabkin
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-07-23 00:00:00.000000000 Z
11
- dependencies: []
12
- description: " Renamr organises multiple files and directories.\n"
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ellipsized
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.3'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.3'
26
+ - !ruby/object:Gem::Dependency
27
+ name: i18n
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.15'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.15'
40
+ - !ruby/object:Gem::Dependency
41
+ name: terminal-table
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '4.0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '4.0'
54
+ description: |2
55
+ Renamr normalizes file and directory names. It rewrites them with
56
+ lowercase English letters, digits, and hyphens in place of spaces and
57
+ other symbols.
13
58
  email: david@rabkin.co.il
14
59
  executables:
15
60
  - renamr
@@ -18,19 +63,8 @@ extra_rdoc_files:
18
63
  - LICENSE
19
64
  - README.adoc
20
65
  files:
21
- - ".github/dependabot.yml"
22
- - ".github/workflows/actionlint.yml"
23
- - ".github/workflows/rake.yml"
24
- - ".github/workflows/rubocop.yml"
25
- - ".github/workflows/test.yml"
26
- - ".gitignore"
27
- - ".travis.yml"
28
- - Gemfile
29
66
  - LICENSE
30
- - LICENSES/0BSD.txt
31
67
  - README.adoc
32
- - REUSE.toml
33
- - Rakefile
34
68
  - bin/renamr
35
69
  - lib/renamr.rb
36
70
  - lib/renamr/action.rb
@@ -51,19 +85,19 @@ files:
51
85
  - lib/renamr/reporter.rb
52
86
  - lib/renamr/rutoen.rb
53
87
  - lib/renamr/substitute.rb
88
+ - lib/renamr/timer.rb
54
89
  - lib/renamr/trim.rb
55
90
  - lib/renamr/truncate.rb
56
91
  - lib/renamr/utils.rb
57
92
  - lib/renamr/version.rb
58
- - renamr.gemspec
59
- - test/test_char.rb
60
- - test/test_date.rb
61
- - test/test_trim.rb
62
93
  homepage: https://github.com/rdavid/renamr
63
94
  licenses:
64
95
  - 0BSD
65
96
  metadata:
97
+ bug_tracker_uri: https://github.com/rdavid/renamr/issues
98
+ homepage_uri: https://github.com/rdavid/renamr
66
99
  rubygems_mfa_required: 'true'
100
+ source_code_uri: https://github.com/rdavid/renamr
67
101
  rdoc_options: []
68
102
  require_paths:
69
103
  - lib
@@ -78,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
112
  - !ruby/object:Gem::Version
79
113
  version: '0'
80
114
  requirements: []
81
- rubygems_version: 3.6.9
115
+ rubygems_version: 4.0.4
82
116
  specification_version: 4
83
- summary: File and directory names organiser
117
+ summary: File and directory name normalizer
84
118
  test_files: []
@@ -1,13 +0,0 @@
1
- # SPDX-FileCopyrightText: 2023-2025 David Rabkin
2
- # SPDX-License-Identifier: 0BSD
3
- ---
4
- version: 2
5
- updates:
6
- - package-ecosystem: github-actions
7
- directory: /
8
- schedule:
9
- interval: daily
10
- - package-ecosystem: bundler
11
- directory: /
12
- schedule:
13
- interval: daily
@@ -1,25 +0,0 @@
1
- # SPDX-FileCopyrightText: 2025 David Rabkin
2
- # SPDX-License-Identifier: 0BSD
3
- ---
4
- name: actionlint
5
- # yamllint disable rule:line-length
6
- 'on':
7
- push:
8
- branches:
9
- - master
10
- pull_request:
11
- branches:
12
- - master
13
- jobs:
14
- actionlint:
15
- timeout-minutes: 15
16
- runs-on: ubuntu-24.04
17
- steps:
18
- - uses: actions/checkout@v4
19
- - name: Download actionlint
20
- id: get_actionlint
21
- run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
22
- shell: bash
23
- - name: Check workflow files
24
- run: ${{ steps.get_actionlint.outputs.executable }} -color
25
- shell: bash
@@ -1,27 +0,0 @@
1
- # SPDX-FileCopyrightText: 2025 David Rabkin
2
- # SPDX-License-Identifier: 0BSD
3
- ---
4
- name: rake
5
- 'on':
6
- push:
7
- branches:
8
- - master
9
- pull_request:
10
- branches:
11
- - master
12
- jobs:
13
- rake:
14
- strategy:
15
- matrix:
16
- os: [ubuntu-24.04, macos-15, windows-2022]
17
- ruby: [3.2, 3.3, 3.4]
18
- runs-on: ${{ matrix.os }}
19
- steps:
20
- - uses: actions/checkout@v4
21
- - uses: ruby/setup-ruby@v1
22
- with:
23
- ruby-version: ${{ matrix.ruby }}
24
- bundler-cache: true
25
- - run: bundle config set --global path "$(pwd)/vendor/bundle"
26
- - run: bundle install --no-color
27
- - run: bundle exec rake
@@ -1,34 +0,0 @@
1
- # SPDX-FileCopyrightText: 2023-2025 David Rabkin
2
- # SPDX-License-Identifier: 0BSD
3
- ---
4
- name: rubocop
5
- 'on':
6
- pull_request:
7
- branches: [master]
8
- jobs:
9
- rubocop:
10
- runs-on: ubuntu-latest
11
- strategy:
12
- fail-fast: false
13
- steps:
14
- - uses: actions/checkout@v4
15
- - uses: ruby/setup-ruby@472790540115ce5bd69d399a020189a8c87d641f
16
- with:
17
- ruby-version: 3.2
18
- - name: Install Code Scanning integration
19
- run: bundle add code-scanning-rubocop --version 0.6.1 --skip-install
20
- - name: Install dependencies
21
- run: bundle install
22
- - name: Rubocop run
23
- run: |
24
- bash -c "
25
- bundle exec rubocop \
26
- --require code_scanning \
27
- --format CodeScanning::SarifFormatter \
28
- -o rubocop.sarif
29
- [[ $? -ne 2 ]]
30
- "
31
- - name: Upload Sarif output
32
- uses: github/codeql-action/upload-sarif@v3
33
- with:
34
- sarif_file: rubocop.sarif
@@ -1,20 +0,0 @@
1
- # SPDX-FileCopyrightText: 2023-2025 David Rabkin
2
- # SPDX-License-Identifier: 0BSD
3
- ---
4
- name: test
5
- 'on': push
6
- jobs:
7
- lint:
8
- runs-on: ubuntu-latest
9
- steps:
10
- - uses: actions/checkout@v4
11
- - uses: docker://github/super-linter:v2.1.1
12
- env:
13
- VALIDATE_ALL_CODEBASE: true
14
- VALIDATE_ANSIBLE: false
15
- - uses: fsfe/reuse-action@v5
16
- - uses: crate-ci/typos@master
17
- - uses: ibiqlik/action-yamllint@v3
18
- with:
19
- file_or_dir: .github/*.yml .github/workflows/*.yml
20
- strict: true
data/.gitignore DELETED
@@ -1,7 +0,0 @@
1
- coverage/
2
- Gemfile.lock
3
- .idea/
4
- *.gem
5
- .bundle/
6
- .DS_Store
7
- rdoc/
data/.travis.yml DELETED
@@ -1,14 +0,0 @@
1
- # SPDX-FileCopyrightText: 2023-2025 David Rabkin
2
- # SPDX-License-Identifier: 0BSD
3
- ---
4
- language: ruby
5
- rvm:
6
- - ~>3.2
7
- branches:
8
- only:
9
- - master
10
- install:
11
- - bundle install
12
- script:
13
- - set -e
14
- - bundle exec rake
data/Gemfile DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2020-2025 David Rabkin
5
- # SPDX-License-Identifier: 0BSD
6
-
7
- source 'https://rubygems.org'
8
- gem 'date'
9
- gem 'ellipsized'
10
- gem 'fileutils'
11
- gem 'i18n'
12
- gem 'minitest'
13
- gem 'pidfile'
14
- gem 'rake'
15
- gem 'rubocop'
16
- gem 'terminal-table'
data/LICENSES/0BSD.txt DELETED
@@ -1,5 +0,0 @@
1
- Copyright 2020-2025 David Rabkin
2
-
3
- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
4
-
5
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
data/REUSE.toml DELETED
@@ -1,11 +0,0 @@
1
- # SPDX-FileCopyrightText: 2025 David Rabkin
2
- # SPDX-License-Identifier: 0BSD
3
- version = 1
4
- [[annotations]]
5
- path = [
6
- ".gitignore",
7
- "README.adoc",
8
- ]
9
- precedence = "override"
10
- SPDX-FileCopyrightText = "2025 David Rabkin"
11
- SPDX-License-Identifier = "0BSD"
data/Rakefile DELETED
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2020-2025 David Rabkin
5
- # SPDX-License-Identifier: 0BSD
6
-
7
- task default: %w[test]
8
-
9
- task :test do
10
- ruby 'test/test_char.rb'
11
- ruby 'test/test_date.rb'
12
- ruby 'test/test_trim.rb'
13
- end
data/renamr.gemspec DELETED
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2023-2025 David Rabkin
4
- # SPDX-License-Identifier: 0BSD
5
-
6
- $LOAD_PATH.unshift File.expand_path('lib', __dir__)
7
-
8
- require 'renamr'
9
-
10
- Gem::Specification.new do |s|
11
- s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
12
- s.required_ruby_version = '>=3.2'
13
- s.name = 'renamr'
14
- s.version = Renamr::VERSION
15
- s.date = Renamr::DATE
16
- s.summary = 'File and directory names organiser'
17
- s.description = <<-HERE
18
- Renamr organises multiple files and directories.
19
- HERE
20
- s.license = '0BSD'
21
- s.author = 'David Rabkin'
22
- s.email = 'david@rabkin.co.il'
23
- s.homepage = 'https://github.com/rdavid/renamr'
24
- s.files = `git ls-files`.split($RS)
25
- s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
26
- s.extra_rdoc_files = ['LICENSE', 'README.adoc']
27
- s.metadata['rubygems_mfa_required'] = 'true'
28
- end
data/test/test_char.rb DELETED
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2020-2025 David Rabkin
5
- # SPDX-License-Identifier: 0BSD
6
-
7
- require 'minitest/autorun'
8
- require_relative '../lib/renamr/char'
9
-
10
- class TestChar < Minitest::Test
11
- def setup
12
- @act = Renamr::CharAction.new
13
- end
14
-
15
- def test_act
16
- assert_equal('-' * 32,
17
- @act.do(' (){},~–\'![]_#@=„“”"`—+‘’;·‡«»%…'.dup))
18
- end
19
- end
data/test/test_date.rb DELETED
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2020-2025 David Rabkin
5
- # SPDX-License-Identifier: 0BSD
6
-
7
- require 'minitest/autorun'
8
- require_relative '../lib/renamr/date'
9
-
10
- # Test DateAction class.
11
- class TestChar < Minitest::Test
12
- def setup
13
- @act = Renamr::DateAction.new
14
- end
15
-
16
- def good
17
- assert_equal('1 20201031 bar', @act.do('1 31-10-2020 bar'.dup))
18
- assert_equal('2 20201031 bar', @act.do('2 10-31-2020 bar'.dup))
19
- assert_equal('3 20201031 bar', @act.do('3 2020-10-31 bar'.dup))
20
- assert_equal('4 20201031 bar', @act.do('4 2020-31-10 bar'.dup))
21
- end
22
-
23
- def bad
24
- assert_equal('5 2nd Nov 2020 bar', @act.do('5 2nd Nov 2020 bar'.dup))
25
- assert_equal('6 1-1-1-1 bar', @act.do('6 1-1-1-1 bar'.dup))
26
- end
27
-
28
- def test_act
29
- good
30
- bad
31
- end
32
- end
data/test/test_trim.rb DELETED
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # vi:ts=2 sw=2 tw=79 et lbr wrap
4
- # SPDX-FileCopyrightText: 2020-2025 David Rabkin
5
- # SPDX-License-Identifier: 0BSD
6
-
7
- require 'minitest/autorun'
8
- require_relative '../lib/renamr/trim'
9
-
10
- class TestTrim < Minitest::Test
11
- def setup
12
- @act = Renamr::TrimAction.new
13
- end
14
-
15
- def test_act
16
- assert_equal('-', @act.do('-'.dup))
17
- assert_equal('-', @act.do('--'.dup))
18
- assert_equal('1', @act.do('1-'.dup))
19
- assert_equal('1', @act.do('-1'.dup))
20
- assert_equal('1-1', @act.do('-1--1-'.dup))
21
- end
22
- end