GitHub-userscripts icon indicating copy to clipboard operation
GitHub-userscripts copied to clipboard

Add support for sorting GitHub checks

Open koppor opened this issue 3 years ago • 4 comments

When having hundreds of tests, it is difficult to switch to the failing ones.

Example:

grafik

My solution proposal: Sort the list of check outputs by "priority": failing, running, queued, cancelled. Therein by name. This is done with this PR (accepting that currently the status is more or less randomly sorted).

After applying this PR:

grafik

I also increase the "minor" version, because a new functionality is added with this PR.

Alternatively, a filter showing the failing tests only would be helpful, too.

Fixes https://github.com/sindresorhus/refined-github/issues/3791

After a merge, https://github.com/Mottie/GitHub-userscripts/wiki/GitHub-sort-content neesd to be updated.

koppor avatar Dec 05 '20 22:12 koppor

I'd like to have sort by status and stort by title as at the file listing. However, I do not know (yet) how to do it.

grafik

When sorting for status, the second criteria should be the check title. When sorting for the check title, the second sort criteria should be the status

koppor avatar Dec 06 '20 11:12 koppor

Hi @koppor!

I was thinking it might be better to add a filter to filter out unwanted checks.

My idea is to changing the "212 cancelled, 140 queued, 21 failing, 52 in progress, and 7 successful checks" into a sentence with 5 links. Click the link to filter out the check in the list below. What do you think? The only thing I don't know is what octicon is being used for "queued" and "in progress", and if there are more than 5 states.

Mottie avatar Dec 07 '20 05:12 Mottie

Try out this userscript... it filters the checks for you:

// ==UserScript==
// @name        GitHub Filter PR checks
// @version     0.1.0
// @description A userscript that filters PR checks
// @license     MIT
// @author      Rob Garrison
// @namespace   https://github.com/Mottie
// @include     https://github.com/*
// @run-at      document-idle
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_addStyle
// @require     https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=878498
// @require     https://greasyfork.org/scripts/398877-utils-js/code/utilsjs.js?version=877686
// @icon        https://github.githubassets.com/pinned-octocat.svg
// ==/UserScript==
/* global $ $$ on off debounce */
(() => {
	"use strict";

	GM_addStyle(`
		.status-meta .is-visible {}
		.status-meta .is-hidden { text-decoration: line-through; }
	`);

	const defaultTypes = {
		cancelled: {
			icon: "octicon-stop",
			isHidden: false
		},
		errored: {
			icon: "octicon-x",
			text: "error",
			isHidden: false
		},
		expected: {
			icon: "octicon-dot-fill",
			text: "expected",
			isHidden: false,
		},
		failing: {
			icon: "octicon-x",
			text: "failing",
			isHidden: false
		},
		// Found in https://github.com/ruby/ruby/pull/3845
		neutral: {
			icon: "octicon-square-fill",
			isHidden: false
		},
		pending: {
			icon: "octicon-dot-fill",
			text: "pending",
			isHidden: false,
		},
		progress: {
			icon: "octicon-dot-fill",
			text: "in progress",
			isHidden: false
		},
		queued: {
			icon: "octicon-dot-fill",
			text: "queued",
			isHidden: false
		},
		successful: {
			icon: "octicon-check",
			isHidden: false
		}
	};
	const types = Object.assign({}, defaultTypes, GM_getValue("ghfc", {}));

	const metaRegexp = /(?:,|\s*and)\s*/;
	const typeKeys = Object.keys(types);

	const setVisibility = block => {
		$$(".merge-status-item", block).forEach(row => {
			const svgClass = $(".merge-status-icon .octicon", row)?.getAttribute("class") || "---";
			const rowType = typeKeys.find(key => {
				const type = types[key];
				const matchingIcon = svgClass.includes(types[key].icon);
				// only a few icons are unique
				if (matchingIcon && type.text) {
					return (row.textContent || "").toLowerCase().includes(type.text);
				}
				return matchingIcon;
			});
			const isHidden = types[rowType]?.isHidden;
			if (rowType && row.classList.contains("d-none") !== isHidden) {
				row.classList.toggle("d-none", isHidden);
			}
		});
	};

	const toggleVisibility = event => {
		const target = event.target;
		if (target.classList.contains("ghfc")) {
			event.preventDefault();
			event.stopPropagation();
			const type = target.dataset.type;
			const isHidden = !types[type].isHidden;
			types[type].isHidden = isHidden;
			target.className = `ghfc ${isHidden ? "is-hidden" : "is-visible"}`;
			GM_setValue("ghfc", types);
			setVisibility();
		}
	};

	const createLinks = block => {
		const meta = $(".status-meta", block);
		if (!$("a", meta)) {
			const links = meta.textContent.trim().split(metaRegexp).filter(t => t);
			// Don't add clickable links if only 1 type is visible
			if (links.length > 1) {
				const last = links.length - 2;
				// ## cancelled, ## queed, ## failing, ## in progress, ## neutral, and ##
				// successful checks
				meta.innerHTML = links.reduce((html, text, index) => {
					const separator = index === last ? " and " : index > last ? "" : ", ";
					const isType = typeKeys.find(type => text.includes(type));
					if (isType) {
						const isHidden = types[isType].isHidden;
						html.push(`
							<a
								href="#"
								data-type="${isType}"
								aria-label="${isHidden ? "hidden" : "visible"}"
								class="ghfc ${isHidden ? "is-hidden" : "is-visible"}"
							>${text}</a>${separator}`);
					}
					return html;
				}, []).join("");
			}
		}
	};

	// At least 3 branch-action-item blocks: reviewers, checks & merge state
	const getChecksBlock = () => $$(".branch-action-item").find(block =>
		$(".statuses-toggle-opened", block)?.textContent?.includes("checks")
	);

	function init() {
		if (
			location.pathname.includes("/pull") &&
			$(".mergeability-details .status-meta")
		) {
			const block = getChecksBlock();
			if (block) {
				createLinks(block);
				off(block, "click", toggleVisibility);
				on(block, "click", toggleVisibility);
				setVisibility(block);
			}
		}
	}

	on(document, "ghmo:updatable ghmo:container", debounce(init));
	init();

})();

Mottie avatar Dec 22 '20 04:12 Mottie

This one (adapted on Mottie's above) focuses on a certain selection at a time: https://gist.github.com/turadg/a6871cafba99d6b3fc281f407cd64e55

turadg avatar Sep 16 '23 00:09 turadg