<feed xmlns='http://www.w3.org/2005/Atom'>
<title>duet/tests/test-duet-classify-path.el, branch main</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<id>https://git.cjennings.net/duet/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/duet/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/duet/'/>
<updated>2026-06-06T15:37:59+00:00</updated>
<entry>
<title>feat: add duet--classify-path</title>
<updated>2026-06-06T15:37:59+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-06T15:37:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/duet/commit/?id=04f9eb281529965c4aff9ca9176b549fac4ae30f'/>
<id>urn:sha1:04f9eb281529965c4aff9ca9176b549fac4ae30f</id>
<content type='text'>
duet--classify-path turns a path string into a plist describing where it lives and how to reach it: :locality (local or remote), :method, :user, :host, :port, :localname, and :hop for multi-hop paths. It's the pure foundation the transfer-spec and connection layers build on (Phase 1 in the design spec).

TRAMP does the dissection, so any path file-remote-p recognizes is remote and everything else is local. A local path is expanded, so a leading ~ resolves to the home directory. A remote localname is kept verbatim because a ~ there is the remote home, not this machine's. Classification never signals: an incomplete string like /ssh:host that TRAMP rejects as a remote name falls back to local, since validating raw TRAMP input belongs to the connection reader, not here.

I probed TRAMP's real contract before writing the tests (port comes back as a string, a multi-hop path reports the final host with the leading hops in :hop), so the Normal/Boundary/Error cases assert what TRAMP actually returns rather than what I'd have guessed.
</content>
</entry>
</feed>
