allow relative path from pacakge items to outside of packages directory

This commit is contained in:
Smartsheet-JB-Brown 2025-04-20 20:56:53 -07:00
parent 5eaf8ba876
commit 2c6ef8a184
2 changed files with 70 additions and 2 deletions

View file

@ -311,9 +311,37 @@ export class MetadataScanner {
parentPath: string = "", parentPath: string = "",
): Promise<void> { ): Promise<void> {
try { try {
const entries = await fs.readdir(packageDir, { withFileTypes: true }) // First check for explicitly listed items in package metadata
const metadataPath = path.join(packageDir, "metadata.en.yml")
try {
const content = await fs.readFile(metadataPath, "utf-8")
const parsed = yaml.load(content) as PackageMetadata
// Process directories sequentially if (parsed.items) {
for (const item of parsed.items) {
// For relative paths starting with ../, resolve from package directory
const itemPath = path.join(packageDir, item.path)
const subMetadata = await this.loadComponentMetadata(itemPath)
if (subMetadata) {
const localizedSubMetadata = this.getLocalizedMetadata(subMetadata)
if (localizedSubMetadata) {
packageItem.items = packageItem.items || []
packageItem.items.push({
type: localizedSubMetadata.type,
path: item.path,
metadata: localizedSubMetadata,
lastUpdated: await this.getLastModifiedDate(itemPath),
})
}
}
}
}
} catch (error) {
// Ignore errors reading metadata.en.yml - we'll still scan subdirectories
}
// Then scan subdirectories for implicit components
const entries = await fs.readdir(packageDir, { withFileTypes: true })
for (const entry of entries) { for (const entry of entries) {
if (!entry.isDirectory()) continue if (!entry.isDirectory()) continue

View file

@ -0,0 +1,40 @@
import * as path from "path"
import { MetadataScanner } from "../MetadataScanner"
import { GitFetcher } from "../GitFetcher"
import * as vscode from "vscode"
describe("MetadataScanner External References", () => {
it("should find all subcomponents in Project Manager package including external references", async () => {
// Create a GitFetcher instance using the project's mock settings directory
const mockContext = {
globalStorageUri: { fsPath: path.resolve(__dirname, "../../../../mock/settings") },
} as vscode.ExtensionContext
const gitFetcher = new GitFetcher(mockContext)
// Fetch the marketplace repository
const repoUrl = "https://github.com/RooVetGit/Roo-Code-Marketplace"
const repo = await gitFetcher.fetchRepository(repoUrl)
// Find the Project Manager package
const projectManager = repo.items.find((item) => item.name === "Project Manager Package")
expect(projectManager).toBeDefined()
expect(projectManager?.type).toBe("package")
// Verify it has exactly 2 subcomponents
expect(projectManager?.items).toBeDefined()
expect(projectManager?.items?.length).toBe(2)
// Verify one is a mode and one is an MCP server
const hasMode = projectManager?.items?.some((item) => item.type === "mode")
const hasMcpServer = projectManager?.items?.some((item) => item.type === "mcp server")
expect(hasMode).toBe(true)
expect(hasMcpServer).toBe(true)
// Verify the MCP server is the Smartsheet component
const smartsheet = projectManager?.items?.find(
(item) => item.metadata?.name === "Smartsheet MCP - Project Management",
)
expect(smartsheet).toBeDefined()
expect(smartsheet?.type).toBe("mcp server")
})
})