-
Notifications
You must be signed in to change notification settings - Fork 202
/
packagist.rb
114 lines (94 loc) · 3.94 KB
/
packagist.rb
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# frozen_string_literal: true
module PackageManager
class Packagist < MultipleSourcesBase
REPOSITORY_SOURCE_NAME = "Main"
HAS_VERSIONS = true
HAS_DEPENDENCIES = true
BIBLIOTHECARY_SUPPORT = true
SECURITY_PLANNED = true
URL = "https://packagist.org"
COLOR = "#4F5D95"
ENTIRE_PACKAGE_CAN_BE_DEPRECATED = true
# TODO: rename PackageManager::Packagist -> PackageManager::Composer, and then PackageManager::Packagist::Main => PackageManager::Composer::Packagist
PROVIDER_MAP = ProviderMap.new(prioritized_provider_infos: [
ProviderInfo.new(identifier: "Main", default: true, provider_class: Main),
ProviderInfo.new(identifier: "Packagist", provider_class: Main),
ProviderInfo.new(identifier: "Drupal", provider_class: Drupal),
])
def self.formatted_name
"Packagist"
end
def self.db_platform
"Packagist"
end
def self.download_url(_db_project, _version = nil)
nil
end
def self.check_status_url(db_project)
package_link(db_project)
end
def self.repository_base
nil
end
def self.project_names
get("https://packagist.org/packages/list.json")["packageNames"]
end
def self.recent_names
u = "https://packagist.org/feeds/releases.rss"
updated = SimpleRSS.parse(get_raw(u)).items.map(&:title)
u = "https://packagist.org/feeds/packages.rss"
new_packages = SimpleRSS.parse(get_raw(u)).items.map(&:title)
(updated.map { |t| t.split.first } + new_packages).uniq
end
def self.project(name)
# The main v2 endpoint only returns a list of versions (no single source-of-truth for the project)
# and excludes dev versions, so if that list of versions is empty, fallback to the dev list of versions.
get("https://repo.packagist.org/p2/#{name}.json")&.dig("packages", name).presence ||
get("https://repo.packagist.org/p2/#{name}~dev.json")&.dig("packages", name)
end
def self.deprecation_info(db_project)
is_deprecated = project(db_project.name)&.first&.dig("abandoned") || ""
{
is_deprecated: is_deprecated != "",
message: is_deprecated.is_a?(String) && is_deprecated.present? ? "Replacement: #{is_deprecated}" : "",
}
end
def self.mapping(raw_project)
return nil unless raw_project.any?
# In V2 API, it looks like the first version is the one with all the metadata (name, etc)
# (This might not necessarily be the version with the highest "time" value)
latest_version = raw_project.first
return if latest_version.nil?
MappingBuilder.build_hash(
name: latest_version["name"],
description: latest_version["description"],
homepage: latest_version["homepage"],
keywords_array: Array.wrap(latest_version["keywords"]),
licenses: latest_version["license"]&.join(","),
repository_url: repo_fallback(latest_version["source"]&.fetch("url"), latest_version["homepage"]),
versions: raw_project # packagist has the list of versions as raw_project and this then lets us pull dependencies in self.dependencies
)
end
def self.versions(raw_project, _name)
acceptable_versions(raw_project).map do |version|
VersionBuilder.build_hash(
number: version["version"],
published_at: version["time"],
original_license: version["license"]
)
end
end
def self.acceptable_versions(versions)
versions.select do |v|
# See: https://getcomposer.org/doc/articles/versions.md#branches
(v["version"] =~ /^dev-.*/i).nil? && (v["version"] =~ /\.x-dev$/i).nil?
end
end
def self.dependencies(_name, version, mapped_project)
vers = mapped_project[:versions].find { |v| v["version"] == version }
return [] if vers.nil?
map_dependencies(vers.fetch("require", {}).except("php"), "runtime") +
map_dependencies(vers.fetch("require-dev", {}).except("php"), "Development")
end
end
end