-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathupdate-composer-json.php
More file actions
137 lines (119 loc) · 5.27 KB
/
Copy pathupdate-composer-json.php
File metadata and controls
137 lines (119 loc) · 5.27 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
// Load the composer.json and composer.lock files
$composerJsonPath = 'composer.json';
$composerLockPath = 'composer.lock';
// Check if the files exist
if (!file_exists($composerJsonPath) || !file_exists($composerLockPath)) {
echo "composer.json or composer.lock file is missing!";
exit(1);
}
// Read and decode the composer.json file
$composerJson = json_decode(file_get_contents($composerJsonPath), true);
if ($composerJson === null) {
echo "Error reading composer.json!";
exit(1);
}
// Read and decode the composer.lock file
$composerLock = json_decode(file_get_contents($composerLockPath), true);
if ($composerLock === null) {
echo "Error reading composer.lock!";
exit(1);
}
// Check if "repositories" exists in composer.json; if not, create it
if (!isset($composerJson['repositories'])) {
$composerJson['repositories'] = [];
}
// Prepare to track any newly pinned packages
$pinnedPackages = [];
// Function to convert exact version to a range (caret operator with full version)
function convertToVersionRange($version) {
// If version looks like an exact version (e.g., "2.0.53"), convert it to a range with caret
if (preg_match('/^(\d+)\.(\d+)\.(\d+)$/', $version, $matches)) {
return "^" . $matches[1] . "." . $matches[2] . "." . $matches[3]; // Convert to ^X.Y.Z (e.g., ^2.0.53)
}
// If already a version range (like "^2.0" or "~2.0"), just return it
return $version;
}
// Iterate through the packages in composer.lock
foreach ($composerLock['packages'] as $package) {
$packageName = $package['name'];
$packageVersion = $package['version'];
// Convert exact version to a range using the convertToVersionRange function
$packageVersionRange = convertToVersionRange($packageVersion);
// Update the versions in the "require" section if the package exists
if (isset($composerJson['require'][$packageName])) {
$composerJson['require'][$packageName] = $packageVersionRange;
}
// If the package exists in "require-dev", update that as well
if (isset($composerJson['require-dev'][$packageName])) {
$composerJson['require-dev'][$packageName] = $packageVersionRange;
}
// Get the repository URL and dist type from composer.lock (either from 'dist' or 'source')
$repositoryUrl = null;
$packageHash = null;
$distType = 'tar'; // Default to 'tar' if no type is specified
if (isset($package['dist']['url'])) {
$repositoryUrl = $package['dist']['url'];
$packageHash = isset($package['dist']['reference']) ? $package['dist']['reference'] : null;
// Set the dist type based on the 'dist' section in composer.lock
if (isset($package['dist']['type'])) {
$distType = $package['dist']['type']; // Use the dist type from composer.lock
}
} elseif (isset($package['source']['url'])) {
$repositoryUrl = $package['source']['url'];
$packageHash = isset($package['source']['reference']) ? $package['source']['reference'] : null;
// If the package comes from a VCS, we can set type as 'vcs'
$distType = 'vcs';
}
// If no URL found, skip this package (you can handle this case as needed)
if (!$repositoryUrl) {
echo "No repository URL found for package: $packageName\n";
continue;
}
// Pin the package in the "repositories" section if it's not already pinned
$repositoryExists = false;
foreach ($composerJson['repositories'] as &$repo) {
if (isset($repo['package']) && $repo['package']['name'] === $packageName) {
// Update existing repository entry with the new version, URL, hash, and dist type
$repo['package']['version'] = $packageVersionRange;
$repo['package']['dist']['url'] = $repositoryUrl;
if ($packageHash) {
$repo['package']['dist']['reference'] = $packageHash;
}
$repo['package']['dist']['type'] = $distType;
$repositoryExists = true;
break;
}
}
// If repository entry does not exist, add a new one
if (!$repositoryExists) {
$composerJson['repositories'][] = [
'type' => 'package', // The type is at the root level of the repository entry
'package' => [
'name' => $packageName,
'version' => $packageVersionRange,
'type' => 'library', // Default type, you can adjust this if needed
'dist' => [
'url' => $repositoryUrl,
'type' => $distType, // Use the dynamically derived dist type
'reference' => $packageHash // Adding the hash (reference) if available
]
]
];
// Track pinned package
$pinnedPackages[] = $packageName;
}
}
// Write the updated composer.json back to the file
if (file_put_contents($composerJsonPath, json_encode($composerJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL)) {
echo "composer.json has been updated with the versions from composer.lock.\n";
if (count($pinnedPackages) > 0) {
echo "The following packages were pinned to repositories:\n";
foreach ($pinnedPackages as $packageName) {
echo " - $packageName\n";
}
}
} else {
echo "Failed to update composer.json.\n";
exit(1);
}