Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cli/azd/cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,13 @@ func (ba *buildAction) Run(ctx context.Context) (*actions.ActionResult, error) {
return nil, err
}

if err := ba.projectManager.EnsureFrameworkTools(ctx, ba.projectConfig, func(svc *project.ServiceConfig) bool {
return targetServiceName == "" || svc.Name == targetServiceName
}); err != nil {
if err := ba.projectManager.Initialize(ctx, ba.projectConfig); err != nil {
return nil, err
}

if err := ba.projectManager.Initialize(ctx, ba.projectConfig); err != nil {
if err := ba.projectManager.EnsureFrameworkTools(ctx, ba.projectConfig, func(svc *project.ServiceConfig) bool {
return targetServiceName == "" || svc.Name == targetServiceName
}); err != nil {
return nil, err
}

Expand Down
4 changes: 4 additions & 0 deletions cli/azd/cmd/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ func (ef *envRefreshAction) Run(ctx context.Context) (*actions.ActionResult, err
return nil, err
}

if err := ef.projectManager.EnsureAllTools(ctx, ef.projectConfig, nil); err != nil {
return nil, err
}

infra, err := ef.importManager.ProjectInfrastructure(ctx, ef.projectConfig)
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion cli/azd/cmd/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (ra *restoreAction) Run(ctx context.Context) (*actions.ActionResult, error)
return nil, err
}

if err := ra.projectManager.EnsureFrameworkTools(ctx, ra.projectConfig, func(svc *project.ServiceConfig) bool {
if err := ra.projectManager.EnsureRestoreTools(ctx, ra.projectConfig, func(svc *project.ServiceConfig) bool {
return targetServiceName == "" || svc.Name == targetServiceName
}); err != nil {
return nil, err
Expand Down
4 changes: 4 additions & 0 deletions cli/azd/internal/cmd/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ func (p *ProvisionAction) Run(ctx context.Context) (*actions.ActionResult, error
return nil, err
}

if err := p.projectManager.EnsureAllTools(ctx, p.projectConfig, nil); err != nil {
return nil, err
}

infra, err := p.importManager.ProjectInfrastructure(ctx, p.projectConfig)
if err != nil {
return nil, err
Expand Down
4 changes: 4 additions & 0 deletions cli/azd/internal/vsrpc/environment_service_refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ func (s *environmentService) refreshEnvironmentAsync(
return nil, err
}

if err := c.projectManager.EnsureAllTools(ctx, c.projectConfig, nil); err != nil {
return nil, err
}

infra, err := c.importManager.ProjectInfrastructure(ctx, c.projectConfig)
if err != nil {
return nil, err
Expand Down
59 changes: 44 additions & 15 deletions cli/azd/pkg/project/project_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ type ProjectManager interface {
// The initialization process will instantiate the framework & service target associated
// with the service config that enables the scenario for these components to add event
// handlers to participate in the lifecycle of an azd project
//
// The initialization process will also ensure that all required tools are installed
Initialize(ctx context.Context, projectConfig *ProjectConfig) error

// Returns the default service name to target based on the current working directory.
Expand All @@ -58,6 +56,11 @@ type ProjectManager interface {

// Ensures that all required service target tools are installed for the project and all child services
EnsureServiceTargetTools(ctx context.Context, projectConfig *ProjectConfig, serviceFilterFn ServiceFilterPredicate) error

// Ensures that all required tools for restore are installed for the project and all child services. This is like
// EnsureFrameworkTools but treats docker projects differently - it requires the tools for the inner project (i.e. npm)
// instead of needing docker tools themselves, since when doing a project restore, docker is not invoked.
EnsureRestoreTools(ctx context.Context, projectConfig *ProjectConfig, serviceFilterFn ServiceFilterPredicate) error
}

// ServiceFilterPredicate is a function that can be used to filter services that match a given criteria
Expand All @@ -84,8 +87,6 @@ func NewProjectManager(

// Initializes the project and all child services defined within the project configuration
func (pm *projectManager) Initialize(ctx context.Context, projectConfig *ProjectConfig) error {
var projectTools []tools.ExternalTool

servicesStable, err := pm.importManager.ServiceStable(ctx, projectConfig)
if err != nil {
return err
Expand All @@ -102,17 +103,6 @@ func (pm *projectManager) Initialize(ctx context.Context, projectConfig *Project
if err := pm.serviceManager.Initialize(ctx, svc); err != nil {
return fmt.Errorf("initializing service '%s', %w", svc.Name, err)
}

svcTools, err := pm.serviceManager.GetRequiredTools(ctx, svc)
if err != nil {
return fmt.Errorf("getting service required tools: %w", err)
}

projectTools = append(projectTools, svcTools...)
}

if err := tools.EnsureInstalled(ctx, tools.Unique(projectTools)...); err != nil {
return err
}

return nil
Expand Down Expand Up @@ -243,3 +233,42 @@ func (pm *projectManager) EnsureServiceTargetTools(

return nil
}

func (pm *projectManager) EnsureRestoreTools(
ctx context.Context,
projectConfig *ProjectConfig,
serviceFilterFn ServiceFilterPredicate,
) error {
var requiredTools []tools.ExternalTool

servicesStable, err := pm.importManager.ServiceStable(ctx, projectConfig)
if err != nil {
return err
}

for _, svc := range servicesStable {
if serviceFilterFn != nil && !serviceFilterFn(svc) {
continue
}

frameworkService, err := pm.serviceManager.GetFrameworkService(ctx, svc)
if err != nil {
return fmt.Errorf("getting framework service: %w", err)
}

var frameworkTools []tools.ExternalTool
if dp, ok := frameworkService.(*dockerProject); ok {
frameworkTools = dp.framework.RequiredExternalTools(ctx, svc)
} else {
frameworkTools = frameworkService.RequiredExternalTools(ctx, svc)
}

requiredTools = append(requiredTools, frameworkTools...)
}

if err := tools.EnsureInstalled(ctx, tools.Unique(requiredTools)...); err != nil {
return err
}

return nil
}
21 changes: 0 additions & 21 deletions cli/azd/test/functional/restore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"testing"

"github.com/azure/azure-dev/cli/azd/pkg/environment/azdcontext"
Expand All @@ -15,10 +14,6 @@ import (

// test for errors when running restore in invalid working directories
func Test_CLI_Restore_Err_WorkingDirectory(t *testing.T) {
if runtime.GOOS == "darwin" {
t.Skip("azure/azure-dev#4612")
}

t.Parallel()
ctx, cancel := newTestContext(t)
defer cancel()
Expand Down Expand Up @@ -84,10 +79,6 @@ func Test_CLI_Restore_Err_WorkingDirectory(t *testing.T) {

// test restore in a service directory
func Test_CLI_Restore_InServiceDirectory(t *testing.T) {
if runtime.GOOS == "darwin" {
t.Skip("azure/azure-dev#4612")
}

t.Parallel()
ctx, cancel := newTestContext(t)
defer cancel()
Expand Down Expand Up @@ -120,10 +111,6 @@ func Test_CLI_Restore_InServiceDirectory(t *testing.T) {

// test restore using a service name passed explicitly
func Test_CLI_Restore_UsingServiceName(t *testing.T) {
if runtime.GOOS == "darwin" {
t.Skip("azure/azure-dev#4612")
}

t.Parallel()
ctx, cancel := newTestContext(t)
defer cancel()
Expand Down Expand Up @@ -155,10 +142,6 @@ func Test_CLI_Restore_UsingServiceName(t *testing.T) {

// test restore all in the project directory
func Test_CLI_RestoreAll_InProjectDir(t *testing.T) {
if runtime.GOOS == "darwin" {
t.Skip("azure/azure-dev#4612")
}

t.Parallel()
ctx, cancel := newTestContext(t)
defer cancel()
Expand Down Expand Up @@ -193,10 +176,6 @@ func Test_CLI_RestoreAll_InProjectDir(t *testing.T) {

// test restore --all
func Test_CLI_RestoreAll_UsingFlags(t *testing.T) {
if runtime.GOOS == "darwin" {
t.Skip("azure/azure-dev#4612")
}

// running this test in parallel is ok as it uses a t.TempDir()
t.Parallel()
ctx, cancel := newTestContext(t)
Expand Down
5 changes: 0 additions & 5 deletions cli/azd/test/functional/telemetry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"os"
"path/filepath"
"regexp"
"runtime"
"strings"
"testing"

Expand Down Expand Up @@ -134,10 +133,6 @@ func Test_CLI_Telemetry_UsageData_Simple_Command(t *testing.T) {

// Verifies telemetry usage data generated when environments and projects are loaded.
func Test_CLI_Telemetry_UsageData_EnvProjectLoad(t *testing.T) {
if runtime.GOOS == "darwin" {
t.Skip("azure/azure-dev#4612")
}

// CLI process and working directory are isolated
ctx, cancel := newTestContext(t)
defer cancel()
Expand Down