in cli/azd/pkg/project/dotnet_importer.go [200:369]
func (ai *DotNetImporter) Services(
ctx context.Context, p *ProjectConfig, svcConfig *ServiceConfig,
) (map[string]*ServiceConfig, error) {
services := make(map[string]*ServiceConfig)
manifest, err := ai.ReadManifest(ctx, svcConfig)
if err != nil {
return nil, fmt.Errorf("generating app host manifest: %w", err)
}
projects := apphost.ProjectPaths(manifest)
for name, path := range projects {
relPath, err := filepath.Rel(p.Path, path)
if err != nil {
return nil, err
}
// TODO(ellismg): Some of this code is duplicated from project.Parse, we should centralize this logic long term.
svc := &ServiceConfig{
RelativePath: relPath,
Language: ServiceLanguageDotNet,
Host: DotNetContainerAppTarget,
}
svc.Name = name
svc.Project = p
svc.EventDispatcher = ext.NewEventDispatcher[ServiceLifecycleEventArgs]()
svc.Infra.Provider, err = provisioning.ParseProvider(svc.Infra.Provider)
if err != nil {
return nil, fmt.Errorf("parsing service %s: %w", svc.Name, err)
}
svc.DotNetContainerApp = &DotNetContainerAppOptions{
Manifest: manifest,
ProjectName: name,
AppHostPath: svcConfig.Path(),
}
services[svc.Name] = svc
}
dockerfiles := apphost.Dockerfiles(manifest)
for name, dockerfile := range dockerfiles {
relPath, err := filepath.Rel(p.Path, filepath.Dir(dockerfile.Path))
if err != nil {
return nil, err
}
// TODO(ellismg): Some of this code is duplicated from project.Parse, we should centralize this logic long term.
svc := &ServiceConfig{
RelativePath: relPath,
Language: ServiceLanguageDocker,
Host: DotNetContainerAppTarget,
Docker: DockerProjectOptions{
Path: dockerfile.Path,
Context: dockerfile.Context,
BuildArgs: mapToExpandableStringSlice(dockerfile.BuildArgs, "="),
},
}
svc.Name = name
svc.Project = p
svc.EventDispatcher = ext.NewEventDispatcher[ServiceLifecycleEventArgs]()
svc.Infra.Provider, err = provisioning.ParseProvider(svc.Infra.Provider)
if err != nil {
return nil, fmt.Errorf("parsing service %s: %w", svc.Name, err)
}
svc.DotNetContainerApp = &DotNetContainerAppOptions{
Manifest: manifest,
ProjectName: name,
AppHostPath: svcConfig.Path(),
}
services[svc.Name] = svc
}
containers := apphost.Containers(manifest)
for name, container := range containers {
// TODO(ellismg): Some of this code is duplicated from project.Parse, we should centralize this logic long term.
svc := &ServiceConfig{
RelativePath: svcConfig.RelativePath,
Language: ServiceLanguageDotNet,
Host: DotNetContainerAppTarget,
}
svc.Name = name
svc.Project = p
svc.EventDispatcher = ext.NewEventDispatcher[ServiceLifecycleEventArgs]()
svc.Infra.Provider, err = provisioning.ParseProvider(svc.Infra.Provider)
if err != nil {
return nil, fmt.Errorf("parsing service %s: %w", svc.Name, err)
}
svc.DotNetContainerApp = &DotNetContainerAppOptions{
ContainerImage: container.Image,
Manifest: manifest,
ProjectName: name,
AppHostPath: svcConfig.Path(),
}
services[svc.Name] = svc
}
buildContainers, err := apphost.BuildContainers(manifest)
if err != nil {
return nil, err
}
for name, bContainer := range buildContainers {
defaultLanguage := ServiceLanguageDotNet
relativePath := svcConfig.RelativePath
var dOptions DockerProjectOptions
if bContainer.Build != nil {
defaultLanguage = ServiceLanguageDocker
relPath, err := filepath.Rel(p.Path, filepath.Dir(bContainer.Build.Dockerfile))
if err != nil {
return nil, err
}
relativePath = relPath
bArgs, err := evaluateArgsWithConfig(*manifest, bContainer.Build.Args)
if err != nil {
return nil, fmt.Errorf("evaluating build args for service %s: %w", name, err)
}
bArgsArray, reqEnv, err := buildArgsArrayAndEnv(*manifest, bContainer.Build.Secrets)
if err != nil {
return nil, fmt.Errorf("converting build args to array for service %s: %w", name, err)
}
dOptions = DockerProjectOptions{
Path: bContainer.Build.Dockerfile,
Context: bContainer.Build.Context,
BuildArgs: mapToExpandableStringSlice(bArgs, "="),
BuildSecrets: bArgsArray,
BuildEnv: reqEnv,
}
}
svc := &ServiceConfig{
RelativePath: relativePath,
Language: defaultLanguage,
Host: DotNetContainerAppTarget,
Docker: dOptions,
}
svc.Name = name
svc.Project = p
svc.EventDispatcher = ext.NewEventDispatcher[ServiceLifecycleEventArgs]()
svc.Infra.Provider, err = provisioning.ParseProvider(svc.Infra.Provider)
if err != nil {
return nil, fmt.Errorf("parsing service %s: %w", svc.Name, err)
}
svc.DotNetContainerApp = &DotNetContainerAppOptions{
ContainerImage: bContainer.Image,
Manifest: manifest,
ProjectName: name,
AppHostPath: svcConfig.Path(),
}
services[svc.Name] = svc
}
return services, nil
}