Something went wrong. Try again.
WIP: A simple cli for daily tangled use cases and AI integration. This is for my personal use right now, but happy if others get mileage fro
Something went wrong. Try again.
5.4 kB · 148 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149import { describe, expect, it } from 'vitest';import { isTangledRemote, parseTangledRemote } from '../../src/utils/git.js';
describe('Git Utilities', () => { describe('isTangledRemote', () => { it('should detect SSH tangled remotes', () => { expect(isTangledRemote('git@tangled.org:did:plc:abc123/repo.git')).toBe(true); expect(isTangledRemote('ssh://git@tangled.org/did:plc:abc123/repo.git')).toBe(true); });
it('should detect HTTPS tangled remotes', () => { expect(isTangledRemote('https://tangled.org/markbennett.ca/tangled-cli')).toBe(true); expect(isTangledRemote('https://tangled.org/user.bsky.social/repo')).toBe(true); });
it('should reject non-tangled remotes', () => { expect(isTangledRemote('git@github.com:user/repo.git')).toBe(false); expect(isTangledRemote('https://github.com/user/repo')).toBe(false); expect(isTangledRemote('https://gitlab.com/user/repo')).toBe(false); expect(isTangledRemote('')).toBe(false); }); });
describe('parseTangledRemote', () => { describe('SSH URLs with DIDs', () => { it('should parse git@tangled.org:did:plc:xxx/repo.git format', () => { const result = parseTangledRemote( 'git@tangled.org:did:plc:b2mcbcamkwyznc5fkplwlxbf/tangled-cli.git' ); expect(result).toEqual({ owner: 'did:plc:b2mcbcamkwyznc5fkplwlxbf', ownerType: 'did', name: 'tangled-cli', protocol: 'ssh', }); });
it('should parse ssh://git@tangled.org/did:plc:xxx/repo.git format', () => { const result = parseTangledRemote( 'ssh://git@tangled.org/did:plc:b2mcbcamkwyznc5fkplwlxbf/tangled-cli.git' ); expect(result).toEqual({ owner: 'did:plc:b2mcbcamkwyznc5fkplwlxbf', ownerType: 'did', name: 'tangled-cli', protocol: 'ssh', }); });
it('should handle SSH URLs without .git extension', () => { const result = parseTangledRemote('git@tangled.org:did:plc:abc123/repo'); expect(result).toEqual({ owner: 'did:plc:abc123', ownerType: 'did', name: 'repo', protocol: 'ssh', }); }); });
describe('SSH URLs with handles', () => { it('should parse SSH URL with handle instead of DID', () => { const result = parseTangledRemote('git@tangled.org:markbennett.ca/tangled-cli.git'); expect(result).toEqual({ owner: 'markbennett.ca', ownerType: 'handle', name: 'tangled-cli', protocol: 'ssh', }); }); });
describe('HTTPS URLs with handles', () => { it('should parse https://tangled.org/handle/repo format', () => { const result = parseTangledRemote('https://tangled.org/markbennett.ca/tangled-cli'); expect(result).toEqual({ owner: 'markbennett.ca', ownerType: 'handle', name: 'tangled-cli', protocol: 'https', }); });
it('should parse HTTPS with user.bsky.social handle', () => { const result = parseTangledRemote('https://tangled.org/user.bsky.social/repo'); expect(result).toEqual({ owner: 'user.bsky.social', ownerType: 'handle', name: 'repo', protocol: 'https', }); });
it('should handle HTTPS URLs without .git extension', () => { const result = parseTangledRemote('https://tangled.org/markbennett.ca/repo'); expect(result?.name).toBe('repo'); }); });
describe('HTTPS URLs with DIDs', () => { it('should parse HTTPS URL with DID instead of handle', () => { const result = parseTangledRemote( 'https://tangled.org/did:plc:b2mcbcamkwyznc5fkplwlxbf/repo' ); expect(result).toEqual({ owner: 'did:plc:b2mcbcamkwyznc5fkplwlxbf', ownerType: 'did', name: 'repo', protocol: 'https', }); }); });
describe('edge cases', () => { it('should handle trailing slashes', () => { const result = parseTangledRemote('https://tangled.org/markbennett.ca/repo/'); expect(result?.name).toBe('repo'); });
it('should handle .git extension in various positions', () => { const result1 = parseTangledRemote('git@tangled.org:did:plc:abc123/repo.git'); const result2 = parseTangledRemote('https://tangled.org/markbennett.ca/repo.git'); expect(result1?.name).toBe('repo'); expect(result2?.name).toBe('repo'); });
it('should return null for invalid DID format', () => { const result = parseTangledRemote('git@tangled.org:did:plc:INVALID/repo.git'); expect(result).toBeNull(); });
it('should return null for invalid handle format', () => { const result = parseTangledRemote('https://tangled.org/invalid/repo'); expect(result).toBeNull(); });
it('should return null for missing repo name', () => { const result = parseTangledRemote('git@tangled.org:did:plc:abc123'); expect(result).toBeNull(); });
it('should return null for non-tangled URLs', () => { expect(parseTangledRemote('git@github.com:user/repo.git')).toBeNull(); expect(parseTangledRemote('https://github.com/user/repo')).toBeNull(); }); }); });});