Welcome to mirror list, hosted at ThFree Co, Russian Federation.

shared.rb « glfm « lib « scripts - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b529d9ba94ffed981fe72f794ed6048262a4aa5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
# frozen_string_literal: true
require 'fileutils'
require 'open3'
require 'active_support/core_ext/hash/keys'

module Glfm
  module Shared
    def write_file(file_path, file_content_string)
      FileUtils.mkdir_p(File.dirname(file_path))
      # NOTE: We don't use the block form of File.open because we want to be able to easily
      # mock it for testing.
      io = File.open(file_path, 'w')
      io.binmode
      io.write(file_content_string)
      # NOTE: We are using #fsync + #close_write instead of just #close`, in order to unit test
      # with a real StringIO and not just a mock object.
      io.fsync
      io.close_write
    end

    # All script output goes through this method. This makes it easy to mock in order to prevent
    # output from being printed to the console during tests. We don't want to directly mock
    # Kernel#puts, because that could interfere or cause spurious test failures when #puts is used
    # for debugging. And for some reason RuboCop says `rubocop:disable Rails/Output` would be
    # redundant here, so not including it.
    def output(string)
      puts string
    end

    def run_external_cmd(cmd)
      # noinspection RubyMismatchedArgumentType
      rails_root = File.expand_path('../../../', __dir__)

      # See https://stackoverflow.com/a/20001569/25192
      stdout_and_stderr_str, status = Open3.capture2e(cmd, chdir: rails_root)

      return stdout_and_stderr_str if status.success?

      warn("Error running command `#{cmd}`\n")
      warn(stdout_and_stderr_str)
      raise
    end

    # Construct an AST so we can control YAML formatting for
    # YAML block scalar literals and key quoting.
    #
    # Note that when Psych dumps the markdown to YAML, it will
    # automatically use the default "clip" behavior of the Block Chomping Indicator (`|`)
    # https://yaml.org/spec/1.2.2/#8112-block-chomping-indicator,
    # when the markdown strings contain a trailing newline. The type of
    # Block Chomping Indicator is automatically determined, you cannot specify it
    # manually.
    def dump_yaml_with_formatting(hash, literal_scalars: false)
      stringified_keys_hash = hash.deep_stringify_keys
      visitor = Psych::Visitors::YAMLTree.create
      visitor << stringified_keys_hash
      ast = visitor.tree

      # Force all scalars to have literal formatting (using Block Chomping Indicator instead of quotes)
      if literal_scalars
        ast.grep(Psych::Nodes::Scalar).each do |node|
          node.style = Psych::Nodes::Scalar::LITERAL
        end
      end

      # Do not quote the keys
      ast.grep(Psych::Nodes::Mapping).each do |node|
        node.children.each_slice(2) do |k, _|
          k.quoted = false
          k.style = Psych::Nodes::Scalar::PLAIN
        end
      end

      ast.to_yaml
    end
  end
end