Skip to content

Instantly share code, notes, and snippets.

@xurizaemon
Last active May 26, 2023 02:53
Show Gist options
  • Save xurizaemon/4b1539fd2bbf570bd8149a933ad8fcbe to your computer and use it in GitHub Desktop.
Save xurizaemon/4b1539fd2bbf570bd8149a933ad8fcbe to your computer and use it in GitHub Desktop.
A very rough and untested initial stab at xurizaemon/patchwatch

xurizaemon/patchwatch

Eh, what's this?

A tool to parse several composer.patches.json (or composer.json) and output a report of patches which are found in all the files.

How?

  1. Put several patches in ./data/*.json
  2. Run ./quick.php (it's not quick once you have a lot of files to parse)
  3. Look at the output

Sheesh, this is pretty rough Chris!

I won't make excuses - this is pretty rough! It was the quickest path to getting some output to work from at a code sprint.

I should get better at jq ...

What's next?

  1. Read What patches are we running?
  2. Visit https://gitlab.com/xurizaemon/patchwatch and help me turn this into something!
#!/usr/bin/env php
<?php
// require 'vendor/autoload.php';
// This version has the class sitting at the bottom of the file.
// use xurizaemon\patchwatch\Drupal\Issue as DrupalIssue;
// Get the files in ./data as an array.
$files = glob('./data/*.json');
$found = [];
$drupalIssues = [];
foreach ($files as $file) {
$contents = file_get_contents($file);
$data = json_decode($contents, true);
$project = explode('.', basename($file))[0];
$filePatches = $data['patches'] ?: $data['extra']['patches'];
foreach ($filePatches as $component => $patches) {
if (stristr($component, 'drupal/')) {
foreach ($patches as $label => $url) {
if ($id = DrupalIssue::getIdFromLabel($label)) {
if (!isset($drupalIssues[$id])) {
$drupalIssues[$id] = new DrupalIssue($id);
$found[$component][$id]['label'] = $drupalIssues[$id]->getTitle();
$found[$component][$id]['status'] = $drupalIssues[$id]->getStatus();
}
$patchData = [
'url' => $url,
'origin' => $project,
];
$found[$component][$id][$url][] = $project;
}
}
}
}
}
print json_encode($found, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
// This lives in a namespaced class, but here I've dropped it direct into the script.
// It's an excerpt of some WIP code for https://gitlab.com/xurizaemon/patchwatch
class DrupalIssue {
protected string $id;
protected string $title;
protected object $data;
static $headers = [
'User-Agent' => 'patchwatch/0.0.1',
];
protected $statuses = [
1 => "Active",
2 => "Fixed",
3 => "Closed (duplicate)",
4 => "Postponed",
5 => "Closed (won't fix)",
6 => "Closed (works as designed)",
7 => "Closed (fixed)",
8 => "Needs review",
13 => "Needs work",
14 => "Reviewed & tested by the community",
15 => "Patch (to be ported)",
16 => "Postponed (maintainer needs more info)",
17 => "Closed (outdated)",
18 => "Closed (cannot reproduce)",
];
public function __construct($id) {
$this->id = $id;
$nodeUrl = "https://www.drupal.org/api-d7/node/${id}.json";
$data = file_get_contents($nodeUrl);
$this->data = json_decode($data);
}
static function getIdFromLabel($label) {
if (preg_match('/#([0-9]+)/', $label, $matches)) {
return $matches[1];
}
}
public function getTitle() {
if (!isset($this->data->title)) {
return 'Unknown - not an issue?';
}
return $this->data->title;
}
public function getProjectMachineName() {
return $this->data->field_project->machine_name;
}
public function getStatus() {
if (!isset($this->data->field_issue_status)) {
return 'No status - not an issue?';
}
if (!isset($this->statuses[$this->data->field_issue_status])) {
return "Unknown status value {$this->data->field_issue_status}";
}
return $this->statuses[$this->data->field_issue_status];
}
public function getPurl($short = false) {
if ($short) {
return "pkg:composer/drupal/{$this->getProjectMachineName()}?id={$this->id}";
}
else {
return "pkg:composer/drupal/{$this->getProjectMachineName()}?id={$this->id}&title={$this->title}";
}
}
public function getLink() {
return "https://www.drupal.org/project/{$this->getProjectMachineName()}/issues/{$this->id}";
}
public function getGitlabIssueTitle() {
return "{$this->getProjectMachineName()}: {$this->getGitlabIssueTitle()}";
}
public function getGitlabIssueDescription() {
return "- PURL: {$this->getPurl()}\n- Upstream link: {$this->getLink()}";
}
public function getInitialDetails() {
return [
'title' => $this->getGitlabIssueTitle(),
'description' => $this->getGitlabIssueDescription(),
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment