Module: ImmosquareYaml

Extended by:
SharedMethods
Defined in:
lib/immosquare-yaml.rb,
lib/immosquare-yaml/railtie.rb,
lib/immosquare-yaml/version.rb,
lib/immosquare-yaml/translate.rb,
lib/immosquare-yaml/configuration.rb,
lib/immosquare-yaml/shared_methods.rb

Overview

##

Importing the ‘English’ library allows us to use more human-readable global variables, such as $INPUT_RECORD_SEPARATOR instead of $/, which enhances code clarity and makes it easier to understand the purpose of these variables in our code.

##

Defined Under Namespace

Modules: SharedMethods, Translate Classes: Configuration, Railtie

Constant Summary collapse

VERSION =
"0.1.23".freeze

Constants included from SharedMethods

SharedMethods::CUSTOM_SEPARATOR, SharedMethods::DOUBLE_QUOTE, SharedMethods::DOUBLE_SIMPLE_QUOTE, SharedMethods::INDENT_SIZE, SharedMethods::NEWLINE, SharedMethods::NOTHING, SharedMethods::RESERVED_KEYS, SharedMethods::SIMPLE_QUOTE, SharedMethods::SPACE, SharedMethods::WEIRD_QUOTES_REGEX, SharedMethods::YML_SPECIAL_CHARS

Class Attribute Summary collapse

Class Method Summary collapse

Methods included from SharedMethods

deep_transform_values

Class Attribute Details

.configurationObject



25
26
27
# File 'lib/immosquare-yaml.rb', line 25

def configuration
  @configuration ||= Configuration.new
end

Class Method Details

.clean(file_path, **options) ⇒ Object

##

This method cleans a specified YAML file by processing it line by line. It executes a comprehensive cleaning routine, which involves parsing the YAML content to a hash, optionally sorting it, and then dumping it back to a YAML format.

Params:

file_path

Path to the YAML file that needs to be cleaned.

options

A hash of options where :sort controls whether the output should be sorted (default is true).

Returns: Boolean indicating the success (true) or failure (false) of the operation.

##


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/immosquare-yaml.rb', line 46

def clean(file_path, **options)
  ##============================================================##
  ## Default options
  ##============================================================##
  options = {
    :sort   => true,
    :output => file_path
  }.merge(options)

  begin
    output_file_path = nil
    raise("File not found") if !File.exist?(file_path)

    ##===========================================================================##
    ## Setup variables
    ##===========================================================================##
    output_file_path = options[:output]

    ##===========================================================================##
    ## Backup original content for restoration after parsing if necessary
    ##===========================================================================##
    original_content = File.read(file_path) if output_file_path != file_path

    ##===========================================================================##
    ## The cleaning procedure is initialized with a comprehensive clean, transforming
    ## the YAML content to a hash to facilitate optional sorting, before
    ## rewriting it to the YAML file in its cleaned and optionally sorted state.
    ##===========================================================================##
    clean_yml(file_path)
    parsed_yml = parse(file_path)
    parsed_yml = parsed_yml.sort_by_key
    parsed_yml = dump(parsed_yml)

    ##===========================================================================##
    ## Restore original content if necessary
    ##===========================================================================##
    File.write(file_path, original_content) if output_file_path != file_path

    ##===========================================================================##
    ## Write the cleaned YAML content to the specified output file
    ##===========================================================================##
    FileUtils.mkdir_p(File.dirname(output_file_path))
    File.write(output_file_path, parsed_yml)
    true
  rescue StandardError => e
    ##===========================================================================##
    ## Restore original content if necessary
    ##===========================================================================##
    File.write(file_path, original_content) if output_file_path != file_path && !original_content.nil?
    puts(e.message)
    puts(e.backtrace)
    false
  end
end

.config {|configuration| ... } ⇒ Object

Yields:



29
30
31
# File 'lib/immosquare-yaml.rb', line 29

def config
  yield(configuration)
end

.dump(hash, lines = [], indent = 0) ⇒ Object

##

This method performs a dump operation to obtain a well-structured YAML file from a hash input. It iterates through each key-value pair in the hash and constructs a series of lines representing the YAML file, with appropriate indentations and handling of various value types including strings with newline characters.

Params:

hash

The input hash to be converted into a YAML representation.

lines

An array to hold the constructed lines (default is an empty array).

indent

The current indentation level (default is 0).

Returns: A string representing the YAML representation of the input hash.

##


172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/immosquare-yaml.rb', line 172

def dump(hash, lines = [], indent = 0)
  hash.each do |key, value|
    ##===========================================================================##
    ## Preparing the key with the proper indentation before identifying
    ## the type of the value to handle it appropriately in the YAML representation.
    ##===========================================================================##
    line = "#{SPACE * indent}#{clean_key(key)}:"

    case value
    when nil
      lines << "#{line} null"
    when String
      if value.include?(NEWLINE) || value.include?('\n')
        ##=============================================================##
        ## We display the line with the key
        ## then the indentation if necessary
        ## then - if necessary (the + is not displayed because it is
        ## the default behavior)
        ##=============================================================##
        line        += "#{SPACE}|"
        indent_level = value[/\A */].size
        line        += (indent_level + INDENT_SIZE).to_s if indent_level > 0
        line        += "-" if !value.end_with?(NEWLINE)
        lines << line

        ##============================================================##
        ## Remove quotes surrounding the value if they are present.
        ## They are not necessary in this case after | or |-
        ##============================================================##
        value = value[1..-2] while (value.start_with?(DOUBLE_QUOTE) && value.end_with?(DOUBLE_QUOTE)) || (value.start_with?(SIMPLE_QUOTE) && value.end_with?(SIMPLE_QUOTE))


        ##=============================================================##
        ## We parse on the 2 types of line breaks
        ##=============================================================##
        value.split(/\\n|\n/).each do |subline|
          lines << "#{SPACE * (indent + INDENT_SIZE)}#{subline}"
        end
      else
        line += "#{SPACE}#{value}"
        lines << line
      end
    when Hash
      lines << line
      dump(value, lines, indent + INDENT_SIZE)
    when Array
      formated_value = Psych.dump(value)
      if formated_value == "--- []\n"
        lines << "#{line} []"
      else
        formated_value = formated_value.gsub("---#{NEWLINE}", NOTHING)
          .split(NEWLINE).map {|l| "#{SPACE * (INDENT_SIZE + indent)}#{l}" }
          .join(NEWLINE)
        lines << line
        lines << formated_value
      end
    end
  end

  ##===========================================================================##
  ## Finalizing the construction by adding a newline at the end and
  ## removing whitespace from empty lines.
  ##===========================================================================##
  lines += [NOTHING]
  lines = lines.map {|l| l.strip.empty? ? NOTHING : l }
  lines.join("\n")
end

.parse(file_path, **options) ⇒ Object

##

This method parses a specified YAML file, carrying out a preliminary cleaning operation to ensure a smooth parsing process. Following this, the cleaned file is transformed into a hash, which can optionally be sorted. It operates under the assumption that the file is properly structured.

Params:

file_path

Path to the YAML file that needs to be parsed.

options

A hash of options where :sort controls whether the output should be sorted (default is true).

Returns: A hash representation of the YAML file or false if an error occurs.

##


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/immosquare-yaml.rb', line 114

def parse(file_path, **options)
  options = {:sort => true}.merge(options)

  begin
    original_content = nil
    raise("File not found") if !File.exist?(file_path)

    ##===========================================================================##
    ## Backup original content for restoration after parsing
    ##===========================================================================##
    original_content = File.read(file_path)

    ##===========================================================================##
    ## clean the file
    ##===========================================================================##
    clean_yml(file_path)

    ##===========================================================================##
    ## parse the file & sort if necessary
    ##===========================================================================##
    parsed_xml = parse_xml(file_path)
    parsed_xml = parsed_xml.sort_by_key if options[:sort]

    ##===========================================================================##
    ## Restore original content
    ##===========================================================================##
    File.write(file_path, original_content) if !original_content.nil?

    ##===========================================================================##
    ## Return the parsed YAML file
    ##===========================================================================##
    parsed_xml
  rescue StandardError => e
    ##===========================================================================##
    ## Restore original content
    ##===========================================================================##
    File.write(file_path, original_content) if !original_content.nil?
    puts(e.message)
    puts(e.backtrace)
    false
  end
end