pdfh 4.0.2 → 4.0.3
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 +4 -4
- data/.pre-commit-config.yaml +0 -6
- data/AGENTS.md +15 -2
- data/CHANGELOG.md +13 -0
- data/Gemfile.lock +17 -17
- data/lib/pdfh/services/document_manager.rb +5 -6
- data/lib/pdfh/utils/file_info.rb +6 -2
- data/lib/pdfh/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a5ef9e4932b73970339e621800eaadd8de7c0bbc07c4536ea4f360fc5227c27a
|
|
4
|
+
data.tar.gz: 9b02deb23b1522d0debb7a9b480b82b7e69c3bedf286743cd3e7a4c065bc6e97
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f694edb6bbe90f5cccb66d94bdf901983b9824f9de71e444065fa98aab75da4ab951965aed0b18de2246c60768e223035294b34d2c3459c251a5a7df2f13678
|
|
7
|
+
data.tar.gz: e2253c53cf4936b9422465ba0bbdf5a7a59b0fc8c0ec8b4bbb63e0bac5d613d80d8ccb490c218d6f7efc09eb16b077e9d13e65c958e6c3ce099cd0b905bf2280
|
data/.pre-commit-config.yaml
CHANGED
data/AGENTS.md
CHANGED
|
@@ -43,10 +43,18 @@ Useful `mise` tasks (`mise.toml`):
|
|
|
43
43
|
- `mise run test` (runs `bundle exec rspec --order random --format documentation`)
|
|
44
44
|
- `mise run check` (runs lint + test)
|
|
45
45
|
- `mise run bump[major|minor|tiny]`
|
|
46
|
-
- `mise run pre` (runs `pre-commit run --all-files`)
|
|
46
|
+
- `mise run pre` (runs `pre-commit run --all-files`; also runs `gitleaks` and `codespell`, which can block a commit independently of RuboCop/tests)
|
|
47
47
|
- `mise run update` (runs `bundle update`)
|
|
48
48
|
- `mise run release` (builds gem + pushes to RubyGems)
|
|
49
49
|
|
|
50
|
+
Equivalent `just` recipes (`justfile`) are also available and wrap the same commands:
|
|
51
|
+
|
|
52
|
+
- `just check` (lint + test)
|
|
53
|
+
- `just test` / `just test-file spec/path_spec.rb:42`
|
|
54
|
+
- `just lint` (runs `rubocop -a`, auto-fixes)
|
|
55
|
+
- `just bump [major|minor|tiny]`
|
|
56
|
+
- `just release`
|
|
57
|
+
|
|
50
58
|
## Repository Layout
|
|
51
59
|
|
|
52
60
|
- `exe/pdfh` CLI entrypoint
|
|
@@ -82,7 +90,7 @@ Key service objects in `lib/pdfh/services/`:
|
|
|
82
90
|
- `DocumentManager` — creates dest dir, copies/renames PDF, copies companion files
|
|
83
91
|
- `SettingsBuilder` — resolves config from env/known locations (`.yml`/`.yaml`), validates, and builds `Settings`
|
|
84
92
|
- `SettingsValidator` — validates settings; raises `ArgumentError` on fatal errors, warns and skips on soft errors (e.g. missing lookup dirs)
|
|
85
|
-
- `OptParser` — parses `ARGV` into `RunOptions`; supports `--list-types
|
|
93
|
+
- `OptParser` — parses `ARGV` into `RunOptions`; supports `--list-types`, `-v/--verbose`, `-d/--dry`, `-V/--version`, `-h/--help`
|
|
86
94
|
|
|
87
95
|
## Code Style and Conventions
|
|
88
96
|
|
|
@@ -159,6 +167,7 @@ Testing:
|
|
|
159
167
|
- **First run side effect**: Missing config does not fail fast; it auto-creates `~/pdfh.yml` and continues from that template.
|
|
160
168
|
- **Dependency mismatch risk**: `qpdf` is still checked at startup (`exe/pdfh`) even though normal v4 processing does not call it directly.
|
|
161
169
|
- **Colorize in tests**: Logging output is colored via `colorize`; specs mock `Console` with shared context `"with silent console"` to suppress output.
|
|
170
|
+
- **CI only lints, not tests**: `.github/workflows/rubocop-analysis.yml` is the only CI workflow and runs RuboCop only (via CodeQL/SARIF upload); RSpec is not run in CI. Always run `mise run test` locally — a green CI check does not mean tests pass.
|
|
162
171
|
|
|
163
172
|
## Suggested Workflow for Agents
|
|
164
173
|
|
|
@@ -167,6 +176,10 @@ Testing:
|
|
|
167
176
|
- Run `mise run lint` and `mise run test` before finalizing changes.
|
|
168
177
|
- Keep changes localized; avoid touching unrelated files.
|
|
169
178
|
|
|
179
|
+
## Repo Etiquette
|
|
180
|
+
|
|
181
|
+
- Commit messages must follow Conventional Commits format (e.g. `fix:`, `feat:`, `chore:`) — enforced by the `conventional-pre-commit` `commit-msg` hook in `.pre-commit-config.yaml`. Non-conforming messages are rejected.
|
|
182
|
+
|
|
170
183
|
## Examples
|
|
171
184
|
|
|
172
185
|
Run a single spec:
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v4.0.3 - 2026-09-21
|
|
4
|
+
|
|
5
|
+
- Centralize `_unlocked` suffix handling in `FileInfo#stem`
|
|
6
|
+
- Upgrade gems
|
|
7
|
+
|
|
8
|
+
## v4.0.2 - 2026-08-03
|
|
9
|
+
|
|
10
|
+
- Skip `.bkp` files when copying companion files
|
|
11
|
+
|
|
12
|
+
## v4.0.1 - 2026-03-24
|
|
13
|
+
|
|
14
|
+
- Fix incorrect `require`
|
|
15
|
+
|
|
3
16
|
## v4.0.0 - 2026-03-21
|
|
4
17
|
|
|
5
18
|
### Breaking
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
pdfh (4.0.
|
|
4
|
+
pdfh (4.0.3)
|
|
5
5
|
colorize (~> 1.1.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -22,7 +22,7 @@ GEM
|
|
|
22
22
|
uri (>= 0.13.1)
|
|
23
23
|
ast (2.4.3)
|
|
24
24
|
base64 (0.3.0)
|
|
25
|
-
bigdecimal (4.1.
|
|
25
|
+
bigdecimal (4.1.3)
|
|
26
26
|
code-scanning-rubocop (0.6.1)
|
|
27
27
|
rubocop (~> 1.0)
|
|
28
28
|
colorize (1.1.0)
|
|
@@ -34,25 +34,25 @@ GEM
|
|
|
34
34
|
diff-lcs (1.6.2)
|
|
35
35
|
docile (1.4.1)
|
|
36
36
|
drb (2.2.3)
|
|
37
|
-
erb (6.0.
|
|
37
|
+
erb (6.0.7)
|
|
38
38
|
factory_bot (6.6.0)
|
|
39
39
|
activesupport (>= 6.1.0)
|
|
40
40
|
i18n (1.15.2)
|
|
41
41
|
concurrent-ruby (~> 1.0)
|
|
42
|
-
io-console (0.
|
|
42
|
+
io-console (0.9.4)
|
|
43
43
|
irb (1.18.0)
|
|
44
44
|
pp (>= 0.6.0)
|
|
45
45
|
prism (>= 1.3.0)
|
|
46
46
|
rdoc (>= 4.0.0)
|
|
47
47
|
reline (>= 0.4.2)
|
|
48
|
-
json (
|
|
48
|
+
json (3.0.2)
|
|
49
49
|
language_server-protocol (3.17.0.6)
|
|
50
50
|
lint_roller (1.1.0)
|
|
51
51
|
logger (1.7.0)
|
|
52
52
|
minitest (6.0.6)
|
|
53
53
|
drb (~> 2.0)
|
|
54
54
|
prism (~> 1.5)
|
|
55
|
-
parallel (2.
|
|
55
|
+
parallel (2.2.0)
|
|
56
56
|
parser (3.3.12.0)
|
|
57
57
|
ast (~> 2.4.1)
|
|
58
58
|
racc
|
|
@@ -63,7 +63,7 @@ GEM
|
|
|
63
63
|
racc (1.8.1)
|
|
64
64
|
rainbow (3.1.1)
|
|
65
65
|
rake (13.4.2)
|
|
66
|
-
rbs (4.
|
|
66
|
+
rbs (4.2.0)
|
|
67
67
|
logger
|
|
68
68
|
prism (>= 1.6.0)
|
|
69
69
|
tsort
|
|
@@ -72,8 +72,8 @@ GEM
|
|
|
72
72
|
prism (>= 1.6.0)
|
|
73
73
|
rbs (>= 4.0.0)
|
|
74
74
|
tsort
|
|
75
|
-
regexp_parser (2.
|
|
76
|
-
reline (0.
|
|
75
|
+
regexp_parser (2.13.0)
|
|
76
|
+
reline (0.7.0)
|
|
77
77
|
io-console (~> 0.5)
|
|
78
78
|
rspec (3.13.2)
|
|
79
79
|
rspec-core (~> 3.13.0)
|
|
@@ -88,8 +88,8 @@ GEM
|
|
|
88
88
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
89
89
|
rspec-support (~> 3.13.0)
|
|
90
90
|
rspec-support (3.13.7)
|
|
91
|
-
rubocop (1.
|
|
92
|
-
json (
|
|
91
|
+
rubocop (1.91.0)
|
|
92
|
+
json (>= 2.3)
|
|
93
93
|
language_server-protocol (~> 3.17.0.2)
|
|
94
94
|
lint_roller (~> 1.1.0)
|
|
95
95
|
parallel (>= 1.10)
|
|
@@ -105,9 +105,9 @@ GEM
|
|
|
105
105
|
rubocop-factory_bot (2.28.0)
|
|
106
106
|
lint_roller (~> 1.1)
|
|
107
107
|
rubocop (~> 1.72, >= 1.72.1)
|
|
108
|
-
rubocop-performance (1.
|
|
108
|
+
rubocop-performance (1.27.0)
|
|
109
109
|
lint_roller (~> 1.1)
|
|
110
|
-
rubocop (>= 1.
|
|
110
|
+
rubocop (>= 1.89.0, < 2.0)
|
|
111
111
|
rubocop-ast (>= 1.47.1, < 2.0)
|
|
112
112
|
rubocop-rake (0.7.1)
|
|
113
113
|
lint_roller (~> 1.1)
|
|
@@ -127,9 +127,9 @@ GEM
|
|
|
127
127
|
tsort (0.2.0)
|
|
128
128
|
tzinfo (2.0.6)
|
|
129
129
|
concurrent-ruby (~> 1.0)
|
|
130
|
-
unicode-display_width (3.
|
|
131
|
-
unicode-emoji (~> 4.
|
|
132
|
-
unicode-emoji (4.
|
|
130
|
+
unicode-display_width (3.3.0)
|
|
131
|
+
unicode-emoji (~> 4.3)
|
|
132
|
+
unicode-emoji (4.3.0)
|
|
133
133
|
uri (1.1.1)
|
|
134
134
|
|
|
135
135
|
PLATFORMS
|
|
@@ -151,4 +151,4 @@ DEPENDENCIES
|
|
|
151
151
|
simplecov (~> 0.22)
|
|
152
152
|
|
|
153
153
|
BUNDLED WITH
|
|
154
|
-
4.0.
|
|
154
|
+
4.0.21
|
|
@@ -4,8 +4,6 @@ module Pdfh
|
|
|
4
4
|
module Services
|
|
5
5
|
# Manages the documents, rename, move, etc.
|
|
6
6
|
class DocumentManager
|
|
7
|
-
PDF_UNLOCKED_MAGIC_SUFFIX = "_unlocked"
|
|
8
|
-
|
|
9
7
|
# @param document [Document]
|
|
10
8
|
# @param base_path [String]
|
|
11
9
|
# @param dry_run [Boolean]
|
|
@@ -86,9 +84,10 @@ module Pdfh
|
|
|
86
84
|
FileUtils.mv(source_file, backup_file) unless dry_run?
|
|
87
85
|
end
|
|
88
86
|
|
|
89
|
-
# Finds companion files by
|
|
90
|
-
#
|
|
91
|
-
#
|
|
87
|
+
# Finds companion files by using the document's clean stem, which already has the
|
|
88
|
+
# `_unlocked` suffix removed (see Pdfh::FileInfo#stem). This allows PDFs unlocked by
|
|
89
|
+
# qpdf to locate their original companion files (e.g., .xml, .txt) that were never
|
|
90
|
+
# renamed with the `_unlocked` suffix.
|
|
92
91
|
# Excludes PDF files and `.bkp` backup files (already-processed PDFs renamed by +backup_original+).
|
|
93
92
|
#
|
|
94
93
|
# @return [Array<String>] array of non-PDF, non-backup files with the same base name
|
|
@@ -97,7 +96,7 @@ module Pdfh
|
|
|
97
96
|
# # Returns ["cuenta.xml", "cuenta.txt"] (excluding "cuenta.pdf" and "cuenta.pdf.bkp")
|
|
98
97
|
def companion_files
|
|
99
98
|
@companion_files ||= begin
|
|
100
|
-
base_name = document.file_info.stem
|
|
99
|
+
base_name = document.file_info.stem
|
|
101
100
|
Dir.glob(File.join(document.file_info.dir, "#{base_name}.*")).reject do |file|
|
|
102
101
|
ext = File.extname(file)
|
|
103
102
|
ext == ".pdf" || file.end_with?(".bkp")
|
data/lib/pdfh/utils/file_info.rb
CHANGED
|
@@ -4,6 +4,10 @@ module Pdfh
|
|
|
4
4
|
# Encapsulates file system metadata for a PDF file path.
|
|
5
5
|
# Responsible for all file name derivations (extension, base name, backup name, etc.).
|
|
6
6
|
class FileInfo
|
|
7
|
+
# Magic suffix added by qpdf when unlocking a PDF. Treated as noise: it is
|
|
8
|
+
# never part of the real document name.
|
|
9
|
+
PDF_UNLOCKED_MAGIC_SUFFIX = "_unlocked"
|
|
10
|
+
|
|
7
11
|
# @param file_path [String] Absolute or relative path to the PDF file
|
|
8
12
|
# @return [self]
|
|
9
13
|
def initialize(file_path)
|
|
@@ -13,9 +17,9 @@ module Pdfh
|
|
|
13
17
|
# @return [String] Full path to the file
|
|
14
18
|
attr_reader :path
|
|
15
19
|
|
|
16
|
-
# @return [String] File name without extension (e.g., "cuenta")
|
|
20
|
+
# @return [String] File name without extension or the `_unlocked` magic suffix (e.g., "cuenta")
|
|
17
21
|
def stem
|
|
18
|
-
File.basename(@path, extension)
|
|
22
|
+
File.basename(@path, extension).delete_suffix(PDF_UNLOCKED_MAGIC_SUFFIX)
|
|
19
23
|
end
|
|
20
24
|
alias name_only stem
|
|
21
25
|
|
data/lib/pdfh/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pdfh
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Isaias Piña
|
|
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
98
|
- !ruby/object:Gem::Version
|
|
99
99
|
version: '0'
|
|
100
100
|
requirements: []
|
|
101
|
-
rubygems_version: 4.0.
|
|
101
|
+
rubygems_version: 4.0.21
|
|
102
102
|
specification_version: 4
|
|
103
103
|
summary: Organize PDF files
|
|
104
104
|
test_files: []
|