Skip to content

Project file discovery for language hooks #7437

Description

@wbreza

Project File Discovery

Part of #7435 — Multi-Language Hook Support

User Story

As a template consumer, I want azd to automatically find my hook's dependency files (requirements.txt, package.json, etc.) so that dependencies are installed without me configuring anything extra.

Solution Approach

Create pkg/tools/language/project_discovery.go (NEW):

  • Implement DiscoverProjectFile(scriptDir, boundaryDir string, fileNames []string) (string, error):
    • Walk up parent directories from scriptDir looking for any file in fileNames.
    • Stop at boundaryDir (inclusive) — never escape the project/service root.
    • Return the directory containing the first match, or empty string if not found.
    • Return error only for filesystem errors, not for "not found".
  • Define helper constants:
    • PythonProjectFiles = []string{"requirements.txt", "pyproject.toml"}
    • NodeProjectFiles = []string{"package.json"} (future)
    • DotNetProjectFilePattern = "*.csproj" (future, needs glob)

Create pkg/tools/language/project_discovery_test.go (NEW):

  • Use t.TempDir() for isolated filesystem fixtures.
  • Table-driven tests (follow pkg/tools/python/python_test.go pattern):
    • Project file at script directory level
    • Project file one level up
    • Project file at boundary directory (root)
    • No project file found → returns empty string
    • Script outside boundary → returns error
    • Both requirements.txt and pyproject.toml present → first match wins per slice order
    • Empty directory tree

Files: pkg/tools/language/project_discovery.go (NEW), pkg/tools/language/project_discovery_test.go (NEW)

Acceptance Criteria

  • All unit tests pass
  • Discovery respects boundary directory (never walks above it)
  • Returns directory path (not file path) — caller decides which file to use
  • Works on both Windows and Unix path separators
  • scriptDir == boundaryDir edge case handled correctly

References

Metadata

Metadata

Assignees

Labels

area/hooksLifecycle hooksarea/toolsExternal tools (Docker, npm, Python)featureFeature request

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions