Module: Pray::ManifestMethods::ParserHelpers

Included in:
BlockParser, PackageSpecParser::ParserHelpers
Defined in:
lib/pray/manifest_parser_helpers.rb

Class Method Summary collapse

Class Method Details

.apply_target_statement(target, statement) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/pray/manifest_parser_helpers.rb', line 190

def apply_target_statement(target, statement)
  case statement
  when /\Aoutput (.+)\z/
    target.outputs << string_from_literal(Regexp.last_match(1))
  when /\Afolder (.+)\z/, /\Askills (.+)\z/
    target.skills << string_from_literal(Regexp.last_match(1))
  when /\Acommands (.+)\z/
    target.commands << string_from_literal(Regexp.last_match(1))
  when /\Arules (.+)\z/
    target.rules << string_from_literal(Regexp.last_match(1))
  when /\Amax_bytes (.+)\z/
    target.max_bytes = Literal.parse_literal(Regexp.last_match(1).strip).as_integer
  else
    raise Error.parse("manifest", "unrecognized target statement: #{statement}")
  end
end

.infer_source_kind(url) ⇒ Object



83
84
85
86
87
88
# File 'lib/pray/manifest_parser_helpers.rb', line 83

def infer_source_kind(url)
  return "git" if url.start_with?("git+")
  return "pray_ssh" if url.start_with?("pray+ssh://", "ssh+pray://")

  "registry"
end

.keyword_array(keywords, key) ⇒ Object



36
37
38
# File 'lib/pray/manifest_parser_helpers.rb', line 36

def keyword_array(keywords, key)
  keywords[key]&.as_array&.filter_map(&:as_string) || []
end

.keyword_bool(keywords, key, default) ⇒ Object



183
184
185
186
187
188
# File 'lib/pray/manifest_parser_helpers.rb', line 183

def keyword_bool(keywords, key, default)
  value = keywords[key]
  return default if value.nil?

  value.as_bool
end

.keyword_string(keywords, key) ⇒ Object



90
91
92
# File 'lib/pray/manifest_parser_helpers.rb', line 90

def keyword_string(keywords, key)
  keywords[key]&.then { |value| string_from_value(value) }
end

.package_constraint(values) ⇒ Object



147
148
149
150
151
# File 'lib/pray/manifest_parser_helpers.rb', line 147

def package_constraint(values)
  return "*" unless values[1]

  Constraint.normalize_version_constraint(string_from_value(values[1]))
end

.package_exports(keywords) ⇒ Object



153
154
155
156
157
158
159
# File 'lib/pray/manifest_parser_helpers.rb', line 153

def package_exports(keywords)
  exports = keyword_array(keywords, "exports")
  if (export = keywords["export"]&.as_string)
    exports << export unless exports.include?(export)
  end
  exports
end

.parse_call(rest) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/pray/manifest_parser_helpers.rb', line 8

def parse_call(rest)
  positional = []
  keywords = {}
  Literal.split_top_level(rest.strip.sub(/,\z/, ""), ",").each do |segment|
    if (keyword = parse_keyword_segment(segment))
      keywords[keyword[0]] = keyword[1]
    elsif !segment.empty?
      positional << Literal.parse_literal(segment)
    end
  end
  [positional, keywords]
end

.parse_group_header(rest) ⇒ Object



112
113
114
115
116
117
118
119
120
# File 'lib/pray/manifest_parser_helpers.rb', line 112

def parse_group_header(rest)
  is_block = rest.rstrip.end_with?("do")
  header = rest.sub(/\s*do\z/, "").strip
  values, = parse_call(header)
  raise Error.parse("manifest", "group missing name") if values.empty?

  names = values.map { |value| string_from_value(value) }
  [names, is_block]
end

.parse_keyword_segment(segment) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/pray/manifest_parser_helpers.rb', line 21

def parse_keyword_segment(segment)
  if (index = Literal.find_top_level(segment, "=>"))
    key = string_from_literal(segment[0...index].strip)
    return [key, Literal.parse_literal(segment[(index + 2)..].strip)]
  end
  if (index = Literal.find_top_level(segment, ":"))
    left = segment[0...index].strip
    right = segment[(index + 1)..].strip
    return nil if left.empty?

    return [left.delete_prefix(":"), Literal.parse_literal(right)]
  end
  nil
end

.parse_local_decl(rest) ⇒ Object



161
162
163
164
165
166
167
168
169
# File 'lib/pray/manifest_parser_helpers.rb', line 161

def parse_local_decl(rest)
  values, keywords = parse_call(rest)
  ManifestLocal.new(
    path: string_from_value(values.first),
    position: keywords["position"]&.as_string || keywords["at"]&.as_string || "after",
    optional: keywords["optional"]&.as_bool || false,
    bound: false
  )
end

.parse_package_decl(rest) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/pray/manifest_parser_helpers.rb', line 122

def parse_package_decl(rest)
  values, keywords = parse_call(rest)
  raise Error.parse("manifest", "agent missing name") if values.empty?

  file = keywords["file"]&.as_string
  ManifestPackage.new(
    name: string_from_value(values[0]),
    constraint: package_constraint(values),
    source: keywords["source"]&.as_string,
    exports: package_exports(keywords),
    targets: keyword_array(keywords, "targets"),
    features: keyword_array(keywords, "features"),
    optional: keywords["optional"]&.as_bool || false,
    path: keywords["path"]&.as_string,
    git: keywords["git"]&.as_string,
    tag: keywords["tag"]&.as_string,
    rev: keywords["rev"]&.as_string,
    tarball: keywords["tarball"]&.as_string,
    oci: keywords["oci"]&.as_string,
    file: file,
    roles: file ? ["file"] : [],
    bound: false
  )
end

.parse_render_policy(rest) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/pray/manifest_parser_helpers.rb', line 171

def parse_render_policy(rest)
  _, keywords = parse_call(rest)
  RenderPolicy.new(
    mode: keywords["mode"]&.as_string || "managed",
    conflict: keywords["conflict"]&.as_string || "fail",
    churn: keywords["churn"]&.as_string || "minimal",
    header: keyword_bool(keywords, "header", true),
    section_markers: keyword_bool(keywords, "section_markers", true),
    line_endings: keywords["line_endings"]&.as_string || "lf"
  )
end

.parse_source(rest) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/pray/manifest_parser_helpers.rb', line 51

def parse_source(rest)
  values, keywords = parse_call(rest)
  raise Error.parse("manifest", "source requires a name") if values.empty?
  if values.length < 2 && !keywords.key?("path") && !keywords.key?("git")
    raise Error.parse("manifest", "source requires a name and url, path:, or git:")
  end

  kind, url = source_kind_and_url(values, keywords)
  ManifestSource.new(
    name: string_from_value(values.first),
    kind: kind,
    url: url,
    subdir: keyword_string(keywords, "subdir") || keyword_string(keywords, "distribution"),
    rev: keyword_string(keywords, "rev"),
    tag: keyword_string(keywords, "tag")
  )
end

.parse_target_header(rest) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/pray/manifest_parser_helpers.rb', line 94

def parse_target_header(rest)
  is_block = rest.rstrip.end_with?("do")
  header = rest.sub(/\s*do\z/, "").strip
  values, keywords = parse_call(header)
  name = string_from_value(values.first)
  outputs = keyword_array(keywords, "output")
  folders = keyword_array(keywords, "folder") + keyword_array(keywords, "skills")
  target = ManifestTarget.new(
    name: name,
    outputs: outputs,
    skills: folders,
    commands: keyword_array(keywords, "commands"),
    rules: keyword_array(keywords, "rules"),
    max_bytes: keywords["max_bytes"]&.as_integer
  )
  [target, is_block]
end

.source_kind_and_url(values, keywords) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/pray/manifest_parser_helpers.rb', line 69

def source_kind_and_url(values, keywords)
  if keywords["path"]
    return ["path", string_from_value(keywords["path"])]
  end
  if keywords["git"]
    url = string_from_value(keywords["git"])
    url = "git+#{url}" unless url.start_with?("git+")
    return ["git", url]
  end

  url = string_from_value(values[1])
  [infer_source_kind(url), url]
end

.string_from_literal(input) ⇒ Object



47
48
49
# File 'lib/pray/manifest_parser_helpers.rb', line 47

def string_from_literal(input)
  string_from_value(Literal.parse_literal(input))
end

.string_from_value(value) ⇒ Object



40
41
42
43
44
45
# File 'lib/pray/manifest_parser_helpers.rb', line 40

def string_from_value(value)
  text = value.as_string
  raise Error.parse("manifest", "expected string-like literal, found #{value.inspect}") unless text

  text
end