Class: CFF::File
- Inherits:
-
Object
- Object
- CFF::File
- Defined in:
- lib/cff/file.rb
Overview
File provides direct access to a CFF Index, with the addition of some filesystem utilities.
To be a fully compliant and valid CFF file its filename should be ‘CITATION.cff’. This class allows you to create files with any filename, and to validate the contents of those files independently of the preferred filename.
Constant Summary collapse
- YAML_HEADER =
:nodoc:
"---\n"- CFF_COMMENT =
[ "This CITATION.cff file was created by ruby-cff (v #{CFF::VERSION}).", 'Gem: https://rubygems.org/gems/cff', 'CFF: https://citation-file-format.github.io/' ].freeze
- CFF_VALID_FILENAME =
:nodoc:
'CITATION.cff'
Instance Attribute Summary collapse
-
#comment ⇒ Object
A comment to be inserted at the top of the resultant CFF file.
-
#filename ⇒ Object
readonly
The filename of this CFF file.
Class Method Summary collapse
-
.format_comment(comment) ⇒ Object
:nodoc:.
-
.open(file) ⇒ Object
:call-seq: open(filename) -> File open(filename) { |cff| block }.
-
.parse_comment(content) ⇒ Object
:nodoc:.
-
.read(file) ⇒ Object
:call-seq: read(filename) -> File.
-
.validate(file, fail_on_filename: true) ⇒ Object
:call-seq: validate(filename, fail_on_filename: true) -> Array.
-
.validate!(file, fail_on_filename: true) ⇒ Object
:call-seq: validate!(filename, fail_on_filename: true).
-
.write(file, cff, comment = '') ⇒ Object
:call-seq: write(filename, File) write(filename, Index) write(filename, yaml).
Instance Method Summary collapse
-
#initialize(filename, param, comment = CFF_COMMENT, create: false) ⇒ File
constructor
:call-seq: new(filename, title) -> File new(filename, index) -> File.
-
#method_missing(name, *args) ⇒ Object
:nodoc:.
-
#respond_to_missing?(name, *all) ⇒ Boolean
:nodoc:.
-
#to_yaml ⇒ Object
:nodoc:.
-
#validate(fail_fast: false, fail_on_filename: true) ⇒ Object
:call-seq: validate(fail_fast: false, fail_on_filename: true) -> Array.
-
#validate!(fail_fast: false, fail_on_filename: true) ⇒ Object
:call-seq: validate!(fail_fast: false, fail_on_filename: true).
-
#write(save_as: nil) ⇒ Object
:call-seq: write(save_as: filename).
Constructor Details
#initialize(filename, param, comment = CFF_COMMENT, create: false) ⇒ File
:call-seq:
new(filename, title) -> File
new(filename, index) -> File
Create a new File. Either a pre-existing Index can be passed in or, as with Index itself, a title can be supplied to initalize a new File.
All methods provided by Index are also available directly on File objects.
56 57 58 59 60 61 62 63 |
# File 'lib/cff/file.rb', line 56 def initialize(filename, param, comment = CFF_COMMENT, create: false) param = Index.new(param) unless param.is_a?(Index) @filename = filename @index = param @comment = comment @dirty = create end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
:nodoc:
226 227 228 229 230 231 232 233 |
# File 'lib/cff/file.rb', line 226 def method_missing(name, *args) # :nodoc: if @index.respond_to?(name) @dirty = true if name.to_s.end_with?('=') # Remove to_s when Ruby >2.6. @index.send(name, *args) else super end end |
Instance Attribute Details
#comment ⇒ Object
A comment to be inserted at the top of the resultant CFF file.
34 35 36 |
# File 'lib/cff/file.rb', line 34 def comment @comment end |
#filename ⇒ Object (readonly)
The filename of this CFF file.
37 38 39 |
# File 'lib/cff/file.rb', line 37 def filename @filename end |
Class Method Details
.format_comment(comment) ⇒ Object
:nodoc:
239 240 241 242 243 244 245 246 247 248 |
# File 'lib/cff/file.rb', line 239 def self.format_comment(comment) # :nodoc: return '' if comment.empty? comment = comment.scan(/.{1,75}/) if comment.is_a?(String) c = comment.map do |l| l.empty? ? '#' : "# #{l}" end.join("\n") "#{c}\n\n" end |
.open(file) ⇒ Object
:call-seq:
open(filename) -> File
open(filename) { |cff| block }
With no associated block, File.open is a synonym for ::read. If the optional code block is given, it will be passed the opened file as an argument and the File object will automatically be written (if edited) and closed when the block terminates.
File.open will create a new file if one does not already exist with the provided file name.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/cff/file.rb', line 87 def self.open(file) if ::File.exist?(file) content = ::File.read(file) comment = File.parse_comment(content) yaml = Util.parse_yaml(content) else comment = CFF_COMMENT yaml = '' end cff = new(file, yaml, comment, create: (yaml == '')) return cff unless block_given? begin yield cff ensure cff.write end end |
.parse_comment(content) ⇒ Object
:nodoc:
250 251 252 253 254 255 256 257 258 |
# File 'lib/cff/file.rb', line 250 def self.parse_comment(content) # :nodoc: content = content.split("\n") content.reduce([]) do |acc, line| break acc unless line.start_with?('#') acc << line.sub(/^#+/, '').strip end end |
.read(file) ⇒ Object
:call-seq:
read(filename) -> File
Read a file and parse it for subsequent manipulation.
69 70 71 72 73 74 |
# File 'lib/cff/file.rb', line 69 def self.read(file) content = ::File.read(file) comment = File.parse_comment(content) new(file, Util.parse_yaml(content), comment) end |
.validate(file, fail_on_filename: true) ⇒ Object
:call-seq:
validate(filename, fail_on_filename: true) -> Array
Read a file and return an array with the result. The result array is a three-element array, with true/false at index 0 to indicate pass/fail, an array of schema validation errors at index 1 (if any), and true/false at index 2 to indicate whether the filename passed/failed validation.
You can choose whether filename validation failure should cause overall validation failure with the fail_on_filename parameter (default: true).
118 119 120 |
# File 'lib/cff/file.rb', line 118 def self.validate(file, fail_on_filename: true) File.read(file).validate(fail_on_filename: fail_on_filename) end |
.validate!(file, fail_on_filename: true) ⇒ Object
:call-seq:
validate!(filename, fail_on_filename: true)
Read a file and raise a ValidationError upon failure. If an error is raised it will contain the detected validation failures for further inspection.
You can choose whether filename validation failure should cause overall validation failure with the fail_on_filename parameter (default: true).
131 132 133 |
# File 'lib/cff/file.rb', line 131 def self.validate!(file, fail_on_filename: true) File.read(file).validate!(fail_on_filename: fail_on_filename) end |
.write(file, cff, comment = '') ⇒ Object
141 142 143 144 145 146 147 |
# File 'lib/cff/file.rb', line 141 def self.write(file, cff, comment = '') comment = cff.comment if cff.respond_to?(:comment) cff = cff.to_yaml unless cff.is_a?(String) content = File.format_comment(comment) + cff[YAML_HEADER.length...-1] ::File.write(file, content) end |
Instance Method Details
#respond_to_missing?(name, *all) ⇒ Boolean
:nodoc:
235 236 237 |
# File 'lib/cff/file.rb', line 235 def respond_to_missing?(name, *all) # :nodoc: @index.respond_to?(name, *all) end |
#to_yaml ⇒ Object
:nodoc:
222 223 224 |
# File 'lib/cff/file.rb', line 222 def to_yaml # :nodoc: @index.to_yaml end |
#validate(fail_fast: false, fail_on_filename: true) ⇒ Object
:call-seq:
validate(fail_fast: false, fail_on_filename: true) -> Array
Validate this file and return an array with the result. The result array is a three-element array, with true/false at index 0 to indicate pass/fail, an array of schema validation errors at index 1 (if any), and true/false at index 2 to indicate whether the filename passed/failed validation.
You can choose whether filename validation failure should cause overall validation failure with the fail_on_filename parameter (default: true).
160 161 162 163 164 165 166 |
# File 'lib/cff/file.rb', line 160 def validate(fail_fast: false, fail_on_filename: true) valid_filename = (::File.basename(@filename) == CFF_VALID_FILENAME) result = (@index.validate(fail_fast: fail_fast) << valid_filename) result[0] &&= valid_filename if fail_on_filename result end |
#validate!(fail_fast: false, fail_on_filename: true) ⇒ Object
:call-seq:
validate!(fail_fast: false, fail_on_filename: true)
Validate this file and raise a ValidationError upon failure. If an error is raised it will contain the detected validation failures for further inspection.
You can choose whether filename validation failure should cause overall validation failure with the fail_on_filename parameter (default: true).
177 178 179 180 181 182 183 184 |
# File 'lib/cff/file.rb', line 177 def validate!(fail_fast: false, fail_on_filename: true) result = validate( fail_fast: fail_fast, fail_on_filename: fail_on_filename ) return if result[0] raise ValidationError.new(result[1], invalid_filename: !result[2]) end |
#write(save_as: nil) ⇒ Object
:call-seq:
write(save_as: filename)
Write this CFF File. The save_as parameter can be used to save a new copy of this CFF File under a different filename, leaving the original file untouched. If save_as is used then the internal filename of the File will be updated to the supplied filename.
193 194 195 196 197 198 199 200 201 |
# File 'lib/cff/file.rb', line 193 def write(save_as: nil) unless save_as.nil? @filename = save_as @dirty = true end File.write(@filename, @index, @comment) if @dirty @dirty = false end |