~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
109 lines · 3.5 KB Raw History
<script lang="ts">
	import type { StepViewDetailed } from '#lib/lexicons/dev/knotless/defs.ts';
	import Icon from '#lib/atoms/Icon.svelte';
	import Sha from '#lib/atoms/Sha.svelte';
	import Command from '#lib/molecules/Command.svelte';
	import Empty from '#lib/molecules/Empty.svelte';
	import RepoLink from '#lib/molecules/RepoLink.svelte';
	import { plural, repoHref } from '#lib/format.ts';
	import { prerelease } from '#lib/releases.ts';
	import { usesLines } from '#lib/steps.ts';
	/**
	 * What a shared step takes and asks for, and how a workflow uses it:
	 * the lines to paste, its inputs, its secrets and the commands it needs;
	 * beside them its versions, each at its commit linked, and the repositories
	 * that pin it.
	 */
	let { step: s }: { step: StepViewDetailed } = $props();
	const commit = (sha: string) => repoHref(s.repo.handle, s.repo.name, `/commit/${sha}`);
	// Names in a sentence: a, b and c.
	const listed = (names: string[]) =>
		names.length > 1 ? `${names.slice(0, -1).join(', ')} and ${names.at(-1)}` : (names[0] ?? '');
	const secrets = $derived(listed(s.secrets.map((x) => x.name)));
	const needs = $derived(listed(s.needs.map((x) => x.name)));
	const more = $derived(s.useCount - s.usedBy.length);
</script>

<div class="step-cols">
	<div class="step-main">
		<h2>Use it</h2>
		<Command text={usesLines(s)} />
		<p class="hint">
			Then <code>knotless workflow pin</code> pins it in <code>.knotless/uses.lock</code>.
		</p>

		<h2>Inputs</h2>
		<div class="box">
			<ul class="list">
				{#each s.inputs as i (i.name)}
					<li>
						<div class="grow">
							<code class="input-name">{i.name}</code>{#if i.required}{' '}<span class="tag"
									>Required</span
								>{/if}
							<div class="meta">{i.description ?? 'No description'}</div>
							{#if i.default !== undefined}<div class="meta">
									{`Default ${i.default === '' ? 'empty' : i.default}`}
								</div>{/if}
						</div>
					</li>
				{:else}
					<li class="blank">
						<Empty title="No inputs">It takes nothing from <code>with</code>.</Empty>
					</li>
				{/each}
			</ul>
		</div>

		<h2>What it asks for</h2>
		<ul class="asks">
			<li>
				<Icon name="key" /><span
					>{s.secrets.length
						? `Asks for ${s.secrets.length === 1 ? 'the secret' : 'the secrets'} ${secrets}`
						: 'Asks for no secrets'}</span
				>
			</li>
			<li>
				<Icon name="package" /><span
					>{s.needs.length ? `Needs ${needs} in the image` : 'Needs no command in the image'}</span
				>
			</li>
		</ul>
	</div>

	<aside class="step-side">
		<h2>Versions</h2>
		<div class="box">
			<ul class="list">
				{#each s.versions as v (v.uri)}
					<li>
						<span class="grow version"
							><b>{v.version}</b>{#if v.version === s.version}{' '}<span class="tag latest"
									>Latest</span
								>{:else if prerelease(v.version)}{' '}<span class="tag">Pre-release</span
								>{/if}</span
						>
						<span class="mute"><Sha sha={v.commit} href={commit(v.commit)} /></span>
					</li>
				{/each}
			</ul>
		</div>

		<h2>
			{s.useCount ? `Used by ${plural(s.useCount, 'repository', 'repositories')}` : 'Used by'}
		</h2>
		<div class="box">
			<ul class="list">
				{#each s.usedBy as r (`${r.did}/${r.name}`)}
					<li><RepoLink owner={r.handle} name={r.name} /></li>
				{:else}
					<li class="blank">
						<Empty title="Not used yet">A repository that pins it in its lock shows here.</Empty>
					</li>
				{/each}
			</ul>
		</div>
		{#if more > 0}<p class="hint">{`And ${plural(more, 'other', 'others')}`}</p>{/if}
	</aside>
</div>