') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Document image save and load stdout/stdin fallbacks. by anxkhn · Pull Request #1905 · apple/container · GitHub
Skip to content

Document image save and load stdout/stdin fallbacks. - #1905

Open
anxkhn wants to merge 1 commit into
apple:mainfrom
anxkhn:docs/image-save-load-optional-io
Open

Document image save and load stdout/stdin fallbacks.#1905
anxkhn wants to merge 1 commit into
apple:mainfrom
anxkhn:docs/image-save-load-optional-io

Conversation

@anxkhn

Copy link
Copy Markdown

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

The command reference documented container image save --output and
container image load --input as required flags, which hid the piping workflow.
Both options are optional: when --output is omitted, image save writes the OCI
archive to stdout, and when --input is omitted, image load reads the archive
from stdin. This is what the code already does:

  • ImageSave.swift declares var output: FilePath? (optional) and, when it is
    absent, streams the archive to FileHandle.standardOutput.
  • ImageLoad.swift declares var input: FilePath? (optional) and, when it is
    absent, reads the archive from FileHandle.standardInput.

The docs were never updated after that stdin/stdout support landed, so the
synopsis and prose still marked the flags as required. This change brings the
reference in line with the behavior and matches how the sibling container export
entry already documents its stdout fallback.

Specifically, for both image save and image load it:

  • brackets [--output <output>] / [--input <input>] in the synopsis so they read
    as optional,
  • reworks the description to note the stdout / stdin fallback (dropping the
    inaccurate "on disk" for save and "The tar file must be specified via --input."
    for load),
  • annotates the option bullets with "(defaults to stdout)" / "(defaults to stdin)",
  • adds a short Examples block showing both a file and a piped invocation.

No code changes; documentation only.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

Verified the documented behavior against the source in
Sources/ContainerCommands/Image/: the optional output / input options and
the stdout / stdin fallback branches. Reviewed the rendered Markdown for the
image save and image load sections; git diff --check is clean. No automated
test applies to a documentation-only change (the file is hand-maintained, not
generated).

stephenlclarke added a commit to stephenlclarke/container-compose that referenced this pull request Jul 12, 2026
Supports Docker Compose cp - archive streams for stdin-to-service and service-to-stdout copies by staging tar streams through the compose layer and existing Apple path-copy APIs.
Pins stephenlclarke/containerization@79b675d so the runtime carries the apple/container#1927 copy lifecycle regression coverage from apple/containerization#799.
Upstream scan found no direct Docker Compose copy-stream PR to import; adjacent Apple work reviewed: apple/container#963, apple/containerization#652, apple/container#1832, apple/container#1905.
Release-Highlight: Support Docker Compose cp - archive streams for stdin-to-service and service-to-stdout copies; includes apple/container#1927 copy lifecycle fix via apple/containerization#799.
The image save --output and image load --input options are optional: when
omitted, save writes the OCI archive to stdout and load reads it from stdin.
The command reference still presented both flags as required, which hid the
piping workflow. Bracket the options in the synopsis, note the stdout/stdin
defaults, and add piping examples, matching the container export entry.
@anxkhn
anxkhnforce-pushed the docs/image-save-load-optional-io branch from 069b524 to a977141CompareAugust 12, 2026 06:18
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@anxkhn