johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
<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>