sevgi-function 1.0.0 → 1.1.1
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/CHANGELOG.md +26 -0
- data/lib/sevgi/function/file.rb +34 -0
- data/lib/sevgi/function/shell.rb +17 -7
- data/lib/sevgi/function/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cdb33b0136955f83cc59d68d1bf5f316debfcc20dd6f798d077c38ead8a9143b
|
|
4
|
+
data.tar.gz: c6500ab4812b1c6bac6dd1e61574baa2f6ca0d0344114124f39f915aa6179f7c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e7eebdc538779ead3fd4e1df77e1215a97aad59774c357828a435a35633472265458ed6a2070a2cd141538570e592dac9794847513ebf9c7e812124fb73dd93
|
|
7
|
+
data.tar.gz: c48b0c56d4f6d92c0e9650714c363e91acc201ff599268d7f57dd5129ba450b4443dbdb5b3037d25d683bdd20d4167d0e5632333e5f5f830a9d1617ae37b2b99
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,32 @@
|
|
|
3
3
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and follows
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
5
|
|
|
6
|
+
## Unreleased
|
|
7
|
+
|
|
8
|
+
## 1.1.1 - 2026-10-29
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Pass the configuration flag after the pdfcpu subcommand so A5-on-A4 export works.
|
|
13
|
+
|
|
14
|
+
## 1.1.0 - 2026-10-29
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `Classes` returns an element's distinct CSS class names without changing the element; `Classify` shares its attribute normalization.
|
|
19
|
+
- Generic document-local Style declarations with `Target`, `Param`, `Group`, and `Profiles`, and optional prepared PDF export through the native Mainz CLI.
|
|
20
|
+
- Backend-independent `fallback: false` for export failures and `F.executable` for executable path lookup.
|
|
21
|
+
- `F.path` for path validation and expansion, and `F.output_path` for default output names and directory targets.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Moved Graphics XML validation into auxiliary helpers and kept built-in paper dimensions in `Paper`.
|
|
26
|
+
- Shared path validation between Graphics writers and Sundries exports while preserving output paths and error messages.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Stamp code placeholders in nested and shared PDF Forms, with cycle-safe resource traversal.
|
|
31
|
+
|
|
6
32
|
## 1.0.0 - 2026-09-16
|
|
7
33
|
|
|
8
34
|
### Added
|
data/lib/sevgi/function/file.rb
CHANGED
|
@@ -93,6 +93,40 @@ module Sevgi
|
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
+
# Resolves an output path, using the default when value is nil or an existing directory.
|
|
97
|
+
# The default is validated only when used. This method does not create files or directories.
|
|
98
|
+
# @param value [String, #to_path, nil] explicit output path or directory
|
|
99
|
+
# @param default [String, #to_path] default output path; its basename is used for a directory target
|
|
100
|
+
# @param context [String] public operation named in errors
|
|
101
|
+
# @return [String] expanded output path
|
|
102
|
+
# @raise [Sevgi::ArgumentError] when a selected path/default is blank, invalid, or cannot be converted
|
|
103
|
+
def output_path(value, default:, context: "Output")
|
|
104
|
+
return path(default, context: "#{context} default") if value.nil?
|
|
105
|
+
|
|
106
|
+
output = path(value, context: "#{context} path")
|
|
107
|
+
return output unless ::File.directory?(output)
|
|
108
|
+
|
|
109
|
+
default = path(default, context: "#{context} default")
|
|
110
|
+
::File.join(output, ::File.basename(default))
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Converts a non-blank path to an expanded String without requiring it to exist.
|
|
114
|
+
# @param value [String, #to_path] raw path value
|
|
115
|
+
# @param context [String] error-message subject
|
|
116
|
+
# @return [String] expanded path
|
|
117
|
+
# @raise [Sevgi::ArgumentError] when value is blank, has an invalid type, or path conversion fails
|
|
118
|
+
def path(value, context: "Path")
|
|
119
|
+
path = value.respond_to?(:to_path) ? value.to_path : value
|
|
120
|
+
ArgumentError.("#{context} must be a String or path-like object") unless path.is_a?(::String)
|
|
121
|
+
ArgumentError.("#{context} must be provided") if path.strip.empty?
|
|
122
|
+
|
|
123
|
+
::File.expand_path(path)
|
|
124
|
+
rescue ::Sevgi::ArgumentError
|
|
125
|
+
raise
|
|
126
|
+
rescue ::StandardError => e
|
|
127
|
+
ArgumentError.("#{context} must be a String or path-like object: #{e.message}")
|
|
128
|
+
end
|
|
129
|
+
|
|
96
130
|
# Adds a default extension when a path has no extension.
|
|
97
131
|
# @param file [String] file path
|
|
98
132
|
# @param default_extension [String] extension to append without a leading dot
|
data/lib/sevgi/function/shell.rb
CHANGED
|
@@ -8,20 +8,30 @@ module Sevgi
|
|
|
8
8
|
# Command methods promoted to {Sevgi::F}. This module owns the public immutable {Shell::Result} value but is not
|
|
9
9
|
# otherwise a consumer mixin contract.
|
|
10
10
|
module Shell
|
|
11
|
-
#
|
|
11
|
+
# Returns the absolute path of the first executable regular file, or nil.
|
|
12
12
|
# @param program [Object] program name, absolute path, or relative slash-containing path
|
|
13
|
-
# @return [
|
|
13
|
+
# @return [String, nil] absolute executable path, preserving a selected symlink
|
|
14
14
|
# @note PATH is evaluated on every call. Empty PATH segments mean the current directory.
|
|
15
|
-
def executable
|
|
15
|
+
def executable(program)
|
|
16
16
|
program = program.to_s
|
|
17
|
-
return
|
|
18
|
-
|
|
17
|
+
return if program.empty?
|
|
18
|
+
if slash_path?(program)
|
|
19
|
+
return executable_file?(program) ? ::File.expand_path(program) : nil
|
|
20
|
+
end
|
|
19
21
|
|
|
20
|
-
ENV.fetch("PATH", "").split(::File::PATH_SEPARATOR, -1).
|
|
21
|
-
|
|
22
|
+
ENV.fetch("PATH", "").split(::File::PATH_SEPARATOR, -1).each do |dir|
|
|
23
|
+
path = ::File.expand_path(program, dir.empty? ? "." : dir)
|
|
24
|
+
return path if executable_file?(path)
|
|
22
25
|
end
|
|
26
|
+
nil
|
|
23
27
|
end
|
|
24
28
|
|
|
29
|
+
# Checks whether a program exists and is executable.
|
|
30
|
+
# @param program [Object] program name, absolute path, or relative slash-containing path
|
|
31
|
+
# @return [Boolean] true when an executable regular file is found
|
|
32
|
+
# @see #executable
|
|
33
|
+
def executable?(program) = !executable(program).nil?
|
|
34
|
+
|
|
25
35
|
# Requires the first command argument to name an executable program.
|
|
26
36
|
# @param args [Array<Object>] command arguments
|
|
27
37
|
# @return [nil]
|