class CFF::File
File
provides direct access to a CFF
Model
, 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.
Attributes
A comment to be inserted at the top of the resultant CFF
file.
The filename of this CFF
file.
Public Class Methods
Create a new File
. Either a pre-existing Model
can be passed in or, as with Model
itself, a title can be supplied to initalize a new File
.
All methods provided by Model
are also available directly on File
objects.
# File lib/cff/file.rb, line 52 def initialize(filename, param, comment = CFF_COMMENT, create: false) param = Model.new(param) unless param.is_a?(Model) @filename = filename @model = param @comment = comment @dirty = create end
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.
# File lib/cff/file.rb, line 85 def self.open(file) if ::File.exist?(file) content = ::File.read(file) comment = File.parse_comment(content) yaml = YAML.safe_load(content, permitted_classes: [Date, Time]) 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
Read a file and parse it for subsequent manipulation.
# File lib/cff/file.rb, line 65 def self.read(file) content = ::File.read(file) comment = File.parse_comment(content) new( file, YAML.safe_load(content, permitted_classes: [Date, Time]), comment ) end
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).
# File lib/cff/file.rb, line 116 def self.validate(file, fail_on_filename: true) File.read(file).validate(fail_on_filename: fail_on_filename) end
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).
# File lib/cff/file.rb, line 129 def self.validate!(file, fail_on_filename: true) File.read(file).validate!(fail_on_filename: fail_on_filename) end
Write the supplied File
, Model
or yaml string to `file`.
# File lib/cff/file.rb, line 139 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
Public Instance Methods
A comment to be inserted at the top of the resultant CFF
file. This can be supplied as a simple string or an array of strings. When the file is saved this comment is formatted as follows:
-
a simple string is split into 75 character lines and `'# '` is prepended
to each line;
-
an array of strings is joined into a single string with `'n'` and
`'# '` is prepended to each line;
If you care about formatting, use an array of strings for your comment, if not, use a single string.
# File lib/cff/file.rb, line 215 def comment=(comment) @dirty = true @comment = comment end
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).
# File lib/cff/file.rb, line 158 def validate(fail_fast: false, fail_on_filename: true) valid_filename = (::File.basename(@filename) == CFF_VALID_FILENAME) result = (@model.validate(fail_fast: fail_fast) << valid_filename) result[0] &&= valid_filename if fail_on_filename result end
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).
# File lib/cff/file.rb, line 175 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 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.
# File lib/cff/file.rb, line 191 def write(save_as: nil) unless save_as.nil? @filename = save_as @dirty = true end File.write(@filename, @model, @comment) if @dirty @dirty = false end