@@ -5,15 +5,16 @@ package project
5
5
6
6
import (
7
7
"context"
8
+ "errors"
8
9
"fmt"
9
10
"io/fs"
11
+ "log"
10
12
"os"
11
13
"path/filepath"
12
14
"slices"
13
15
"strings"
14
16
15
17
"github.com/azure/azure-dev/cli/azd/internal/scaffold"
16
- "github.com/azure/azure-dev/cli/azd/pkg/infra/provisioning"
17
18
"github.com/azure/azure-dev/cli/azd/pkg/osutil"
18
19
"github.com/psanford/memfs"
19
20
)
@@ -38,18 +39,10 @@ func infraFs(_ context.Context, prjConfig *ProjectConfig) (fs.FS, error) {
38
39
return files , nil
39
40
}
40
41
41
- // Returns the infrastructure configuration that points to a temporary, generated `infra` directory on the filesystem.
42
- func tempInfra (
43
- ctx context.Context ,
44
- prjConfig * ProjectConfig ) (* Infra , error ) {
45
- tmpDir , err := os .MkdirTemp ("" , "azd-infra" )
46
- if err != nil {
47
- return nil , fmt .Errorf ("creating temporary directory: %w" , err )
48
- }
49
-
42
+ func infraFsToDir (ctx context.Context , prjConfig * ProjectConfig , dir string ) error {
50
43
files , err := infraFs (ctx , prjConfig )
51
44
if err != nil {
52
- return nil , err
45
+ return err
53
46
}
54
47
55
48
err = fs .WalkDir (files , "." , func (path string , d fs.DirEntry , err error ) error {
@@ -61,7 +54,7 @@ func tempInfra(
61
54
return nil
62
55
}
63
56
64
- target := filepath .Join (tmpDir , path )
57
+ target := filepath .Join (dir , path )
65
58
if err := os .MkdirAll (filepath .Dir (target ), osutil .PermissionDirectoryOwnerOnly ); err != nil {
66
59
return err
67
60
}
@@ -74,17 +67,10 @@ func tempInfra(
74
67
return os .WriteFile (target , contents , d .Type ().Perm ())
75
68
})
76
69
if err != nil {
77
- return nil , fmt .Errorf ("writing infrastructure: %w" , err )
70
+ return fmt .Errorf ("writing infrastructure: %w" , err )
78
71
}
79
72
80
- return & Infra {
81
- Options : provisioning.Options {
82
- Provider : provisioning .Bicep ,
83
- Path : tmpDir ,
84
- Module : DefaultModule ,
85
- },
86
- cleanupDir : tmpDir ,
87
- }, nil
73
+ return nil
88
74
}
89
75
90
76
// Generates the filesystem of all infrastructure files to be placed, rooted at the project directory.
@@ -95,13 +81,33 @@ func infraFsForProject(ctx context.Context, prjConfig *ProjectConfig) (fs.FS, er
95
81
return nil , err
96
82
}
97
83
98
- infraPathPrefix := DefaultPath
84
+ infraPrefix := DefaultPath
99
85
if prjConfig .Infra .Path != "" {
100
- infraPathPrefix = prjConfig .Infra .Path
86
+ infraPrefix = prjConfig .Infra .Path
87
+ }
88
+
89
+ infraRoot := infraPrefix
90
+ if ! filepath .IsAbs (infraPrefix ) {
91
+ infraRoot = filepath .Join (prjConfig .Path , infraPrefix )
92
+ }
93
+
94
+ infraDir , err := os .Stat (infraRoot )
95
+ if ! errors .Is (err , os .ErrNotExist ) && err != nil {
96
+ return nil , fmt .Errorf ("error reading infra directory: %w" , err )
97
+ }
98
+
99
+ fi , err := os .Stat (filepath .Join (infraRoot , ".azure" ))
100
+ if ! errors .Is (err , os .ErrNotExist ) && err != nil {
101
+ return nil , fmt .Errorf ("error reading .azure file in infra: %w" , err )
102
+ }
103
+
104
+ if infraDir != nil && fi == nil { // if the infra directory is not managed by azd, generate it to infra/azd
105
+ infraPrefix = filepath .Join (infraPrefix , "azd" )
106
+ log .Println ("infrastructure directory is not managed by azd, generating to" , infraPrefix )
101
107
}
102
108
103
- // root the generated content at the project directory
104
109
generatedFS := memfs .New ()
110
+ // root the generated content at the project directory
105
111
err = fs .WalkDir (infraFS , "." , func (path string , d fs.DirEntry , err error ) error {
106
112
if err != nil {
107
113
return err
@@ -111,7 +117,7 @@ func infraFsForProject(ctx context.Context, prjConfig *ProjectConfig) (fs.FS, er
111
117
return nil
112
118
}
113
119
114
- err = generatedFS .MkdirAll (filepath .Join (infraPathPrefix , filepath .Dir (path )), osutil .PermissionDirectoryOwnerOnly )
120
+ err = generatedFS .MkdirAll (filepath .Join (infraPrefix , filepath .Dir (path )), osutil .PermissionDirectoryOwnerOnly )
115
121
if err != nil {
116
122
return err
117
123
}
@@ -121,10 +127,18 @@ func infraFsForProject(ctx context.Context, prjConfig *ProjectConfig) (fs.FS, er
121
127
return err
122
128
}
123
129
124
- return generatedFS .WriteFile (filepath .Join (infraPathPrefix , path ), contents , d .Type ().Perm ())
130
+ return generatedFS .WriteFile (filepath .Join (infraPrefix , path ), contents , d .Type ().Perm ())
125
131
})
126
132
if err != nil {
127
- return nil , err
133
+ return nil , fmt .Errorf ("generating: %w" , err )
134
+ }
135
+
136
+ if fi == nil {
137
+ // create a sentinel file to indicate that the infra directory is managed by azd
138
+ err = generatedFS .WriteFile (filepath .Join (infraPrefix , ".azure" ), []byte {}, osutil .PermissionFileOwnerOnly )
139
+ if err != nil {
140
+ return nil , fmt .Errorf ("writing sentinel: %w" , err )
141
+ }
128
142
}
129
143
130
144
return generatedFS , nil
0 commit comments