Class: Dependabot::Python::FileParser::PyprojectDocument

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dependabot/python/file_parser/pyproject_document.rb

Defined Under Namespace

Classes: PoetrySource, ProjectMetadata

Constant Summary collapse

PoetryRequirement =
T.type_alias { PyprojectValueParser::PoetryRequirement }
PoetryDependencyMap =
T.type_alias { PyprojectValueParser::PoetryDependencyMap }
UNRESOLVABLE_UV_SOURCE_KEYS =

A name pinned to one of these says nothing about what a package index holds. A git source carrying a tag is left alone: the tag gives an ordering, so such a pin can be updated from the remote instead of being skipped.

%w(git url).freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ PyprojectDocument

Returns a new instance of PyprojectDocument.



107
108
109
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 107

def initialize(data)
  @data = data
end

Class Method Details

.from_content(content) ⇒ Object



119
120
121
122
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 119

def self.from_content(content)
  parsed = T.cast(TomlRB.parse(content), Object)
  new(PyprojectValueParser.object_hash(parsed, "pyproject.toml"))
end

.from_file(file) ⇒ Object



112
113
114
115
116
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 112

def self.from_file(file)
  from_content(T.must(file.content))
rescue TomlRB::ParseError, TomlRB::ValueOverwriteError
  raise Dependabot::DependencyFileNotParseable, file.path
end

Instance Method Details

#build_system_metadata ⇒ Object



145
146
147
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 145

def 
  (section(@data, "build-system", "build-system"), "build-system")
end

#dynamic_fields ⇒ Object



197
198
199
200
201
202
203
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 197

def dynamic_fields
  project = section(@data, "project", "project")
  value = project&.[]("dynamic")
  return [] if value.nil?

  PyprojectValueParser.string_array(value, "project.dynamic")
end

#optional_dependency_group?(name) ⇒ Boolean

Returns:

  • (Boolean)


206
207
208
209
210
211
212
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 206

def optional_dependency_group?(name)
  project = section(@data, "project", "project")
  value = project&.[]("optional-dependencies")
  return false if value.nil?

  PyprojectValueParser.object_hash(value, "project.optional-dependencies").key?(name)
end

#pep621? ⇒ Boolean

Returns:

  • (Boolean)


150
151
152
153
154
155
156
157
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 150

def pep621?
  project = section(@data, "project", "project")
  build_system = section(@data, "build-system", "build-system")

  !project&.[]("dependencies").nil? ||
    !project&.[]("optional-dependencies").nil? ||
    !build_system&.[]("requires").nil?
end

#pep735? ⇒ Boolean

Returns:

  • (Boolean)


160
161
162
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 160

def pep735?
  @data.key?("dependency-groups")
end

#poetry? ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 125

def poetry?
  !poetry_root.nil?
end

#poetry_dependencies(type) ⇒ Object



165
166
167
168
169
170
171
172
173
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 165

def poetry_dependencies(type)
  root = poetry_root
  return {} unless root

  value = root[type]
  return {} if value.nil?

  PyprojectValueParser.poetry_dependency_map(value, "tool.poetry.#{type}")
end

#poetry_groups ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 176

def poetry_groups
  root = poetry_root
  return {} unless root

  raw_groups = root["group"]
  return {} if raw_groups.nil?

  parsed_groups = PyprojectValueParser.object_hash(raw_groups, "tool.poetry.group")
  parsed_groups.each_with_object({}) do |(name, value), groups|
    group = PyprojectValueParser.object_hash(value, "tool.poetry.group.#{name}")
    dependencies = group["dependencies"]
    next if dependencies.nil?

    groups[name] = PyprojectValueParser.poetry_dependency_map(
      dependencies,
      "tool.poetry.group.#{name}.dependencies"
    )
  end
end

#poetry_metadata ⇒ Object



135
136
137
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 135

def 
  (poetry_root, "tool.poetry")
end

#poetry_source(name) ⇒ Object



215
216
217
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 215

def poetry_source(name)
  poetry_sources.find { |source| source.name == name }
end

#project? ⇒ Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 130

def project?
  !section(@data, "project", "project").nil?
end

#project_metadata ⇒ Object



140
141
142
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 140

def 
  (section(@data, "project", "project"), "project")
end

#unresolvable_uv_source_entry?(entry) ⇒ Boolean

Returns:

  • (Boolean)


241
242
243
244
245
246
247
248
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 241

def unresolvable_uv_source_entry?(entry)
  return false unless entry.is_a?(Hash)

  keys = entry.keys
  return false unless keys.intersect?(UNRESOLVABLE_UV_SOURCE_KEYS)

  !(keys.include?("git") && keys.include?("tag"))
end

#unresolvable_uv_source_names ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 225

def unresolvable_uv_source_names
  tool = section(@data, "tool", "tool")
  uv = tool && section(tool, "uv", "tool.uv")
  sources = uv && section(uv, "sources", "tool.uv.sources")
  return [] unless sources

  sources.filter_map do |name, config|
    # uv accepts either a single source or a list of them, each with its own markers.
    entries = T.let(config.is_a?(Array) ? config : [config], T::Array[Object])
    next unless entries.any? { |entry| unresolvable_uv_source_entry?(entry) }

    name
  end
end

#workspace_globs(key) ⇒ Object



251
252
253
254
255
256
257
258
259
# File 'lib/dependabot/python/file_parser/pyproject_document.rb', line 251

def workspace_globs(key)
  tool = section(@data, "tool", "tool")
  uv = tool && section(tool, "uv", "tool.uv")
  workspace = uv && section(uv, "workspace", "tool.uv.workspace")
  value = workspace&.[](key)
  return [] if value.nil?

  PyprojectValueParser.string_array(value, "tool.uv.workspace.#{key}")
end