webui: fix repository name parsing for names containing dots
Fix GitHub repository URL parsing in sketch-container-status component to
properly handle repository names containing dots, resolving broken GitHub
links in the ongoing session log banner.
Problem Analysis:
The formatGitHubRepo function used regex patterns with [^/\s.]+ character
classes that excluded dots from repository names. This caused repository names
like 'boldsoftware/sketch.git' to be truncated to 'boldsoftware/sketch' when
parsed, breaking GitHub links and repository display in the session banner.
The issue occurred in three regex patterns for different GitHub URL formats:
- HTTPS URLs: /https:\/\/github\.com\/([^/]+)\/([^/\s.]+)(?:\.git)?/
- SSH URLs: /git@github\.com:([^/]+)\/([^/\s.]+)(?:\.git)?/
- Git protocol: /git:\/\/github\.com\/([^/]+)\/([^/\s.]+)(?:\.git)?/
The [^/\s.]+ pattern specifically excluded dots (.) from matching, which was
problematic for legitimate repository names containing dots.
Implementation Changes:
1. Regex Pattern Updates:
- Changed [^/\s.]+ to [^/\s]+? in all three URL patterns
- Removed dot exclusion while maintaining whitespace and slash exclusion
- Added non-greedy quantifier (?) to prevent over-matching
- Added end-of-string anchor ($) for precise matching
2. Updated patterns:
- HTTPS: /https:\/\/github\.com\/([^/]+)\/([^/\s]+?)(?:\.git)?$/
- SSH: /git@github\.com:([^/]+)\/([^/\s]+?)(?:\.git)?$/
- Git: /git:\/\/github\.com\/([^/]+)\/([^/\s]+?)(?:\.git)?$/
Technical Details:
- Non-greedy matching (+?) ensures proper handling of .git suffix
- End anchors ($) prevent partial matches and improve precision
- Dots now allowed in repository names while preserving .git detection
- Existing functionality preserved for repositories without dots
Testing:
Verified fix with comprehensive test cases:
- git@github.com:boldsoftware/sketch.git → boldsoftware/sketch ✓
- https://github.com/user/repo.with.dots.git → user/repo.with.dots ✓
- git@github.com:org/project.name.git → org/project.name ✓
- https://github.com/test/normal-repo → test/normal-repo ✓
Benefits:
- GitHub links now work correctly for repositories with dots in names
- Session banner displays proper repository information
- Maintains backward compatibility with existing repository names
- Improves user experience for repository navigation
This fix resolves the specific issue where repository names containing dots
would have their GitHub links truncated, breaking navigation to the actual
repository on GitHub.
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: sda0a251af3d756b6k
webui: improve GitHub repo parsing tests
Replace internal method testing with component behavior testing for better
integration coverage and maintainability.
- Test actual GitHub link rendering in DOM instead of calling private methods
- Add separate test cases for repository names with dots
- Verify href attributes, text content, and title attributes are correct
- Cover both general dot-containing names and the specific boldsoftware/sketch case
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s216977b6be91a2bak
diff --git a/webui/src/web-components/sketch-container-status.test.ts b/webui/src/web-components/sketch-container-status.test.ts
index dd37d1f..ca1a8f5 100644
--- a/webui/src/web-components/sketch-container-status.test.ts
+++ b/webui/src/web-components/sketch-container-status.test.ts
@@ -117,3 +117,57 @@
// totalCost element should not exist when cost is 0
await expect(component.locator("#totalCost")).toHaveCount(0);
});
+
+test("formatGitHubRepo handles repository names with dots correctly", async ({
+ mount,
+}) => {
+ // Test repository with dots in name
+ const component = await mount(SketchContainerStatus, {
+ props: {
+ state: {
+ ...mockCompleteState,
+ git_origin: "git@github.com:user/repo.with.dots.git",
+ link_to_github: true,
+ },
+ },
+ });
+
+ // Check that the GitHub link is displayed correctly with dots preserved
+ const githubLink = component.locator("a.github-link");
+ await expect(githubLink).toContainText("user/repo.with.dots");
+ await expect(githubLink).toHaveAttribute(
+ "href",
+ "https://github.com/user/repo.with.dots",
+ );
+ await expect(githubLink).toHaveAttribute(
+ "title",
+ "git@github.com:user/repo.with.dots.git",
+ );
+});
+
+test("formatGitHubRepo handles boldsoftware/sketch.git correctly", async ({
+ mount,
+}) => {
+ // Test the specific case mentioned in the issue
+ const component = await mount(SketchContainerStatus, {
+ props: {
+ state: {
+ ...mockCompleteState,
+ git_origin: "git@github.com:boldsoftware/sketch.git",
+ link_to_github: true,
+ },
+ },
+ });
+
+ // Check that the GitHub link is displayed correctly
+ const githubLink = component.locator("a.github-link");
+ await expect(githubLink).toContainText("boldsoftware/sketch");
+ await expect(githubLink).toHaveAttribute(
+ "href",
+ "https://github.com/boldsoftware/sketch",
+ );
+ await expect(githubLink).toHaveAttribute(
+ "title",
+ "git@github.com:boldsoftware/sketch.git",
+ );
+});
diff --git a/webui/src/web-components/sketch-container-status.ts b/webui/src/web-components/sketch-container-status.ts
index 4385571..088244f 100644
--- a/webui/src/web-components/sketch-container-status.ts
+++ b/webui/src/web-components/sketch-container-status.ts
@@ -573,11 +573,11 @@
// Common GitHub URL patterns
const patterns = [
// HTTPS URLs
- /https:\/\/github\.com\/([^/]+)\/([^/\s.]+)(?:\.git)?/,
+ /https:\/\/github\.com\/([^/]+)\/([^/\s]+?)(?:\.git)?$/,
// SSH URLs
- /git@github\.com:([^/]+)\/([^/\s.]+)(?:\.git)?/,
+ /git@github\.com:([^/]+)\/([^/\s]+?)(?:\.git)?$/,
// Git protocol
- /git:\/\/github\.com\/([^/]+)\/([^/\s.]+)(?:\.git)?/,
+ /git:\/\/github\.com\/([^/]+)\/([^/\s]+?)(?:\.git)?$/,
];
for (const pattern of patterns) {