Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
43 changes: 31 additions & 12 deletions cli/azd/pkg/environment/azdcontext/azdcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ const DotEnvFileName = ".env"
const ConfigFileName = "config.json"
const ConfigFileVersion = 1

// ProjectFileNames lists all valid project file names, in order of preference
var ProjectFileNames = []string{"azure.yaml", "azure.yml"}

type AzdContext struct {
projectDirectory string
projectFilePath string
}

func (c *AzdContext) ProjectDirectory() string {
Expand All @@ -32,7 +36,13 @@ func (c *AzdContext) SetProjectDirectory(dir string) {
c.projectDirectory = dir
}

// ProjectPath returns the path to the project file. If the context was created by searching
// for a project file, returns the actual file that was found. Otherwise, returns the default
// project file name joined with the project directory (useful when creating new projects).
func (c *AzdContext) ProjectPath() string {
if c.projectFilePath != "" {
return c.projectFilePath
}
return filepath.Join(c.ProjectDirectory(), ProjectFileName)
}

Expand Down Expand Up @@ -129,26 +139,35 @@ func NewAzdContextFromWd(wd string) (*AzdContext, error) {
return nil, fmt.Errorf("resolving path: %w", err)
}

var foundProjectFilePath string
for {
projectFilePath := filepath.Join(searchDir, ProjectFileName)
stat, err := os.Stat(projectFilePath)
if os.IsNotExist(err) || (err == nil && stat.IsDir()) {
parent := filepath.Dir(searchDir)
if parent == searchDir {
return nil, ErrNoProject
// Try all valid project file names in order of preference
for _, fileName := range ProjectFileNames {
projectFilePath := filepath.Join(searchDir, fileName)
stat, err := os.Stat(projectFilePath)
if err == nil && !stat.IsDir() {
// We found a valid project file
foundProjectFilePath = projectFilePath
break
}
searchDir = parent
} else if err == nil {
// We found our azure.yaml file, and searchDir is the directory
// that contains it.
}

if foundProjectFilePath != "" {
// We found our project file, and searchDir is the directory that contains it.
break
} else {
return nil, fmt.Errorf("searching for project file: %w", err)
}

// No project file found in this directory, move up to parent
parent := filepath.Dir(searchDir)
if parent == searchDir {
return nil, ErrNoProject
}
searchDir = parent
}

return &AzdContext{
projectDirectory: searchDir,
projectFilePath: foundProjectFilePath,
}, nil
}

Expand Down
30 changes: 17 additions & 13 deletions ext/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@
"explorer/context": [
{
"submenu": "azure-dev.explorer.submenu",
"when": "resourceFilename =~ /(azure.yaml|pom.xml)/i",
"when": "resourceFilename =~ /(azure.ya?ml|pom.xml)/i",
"group": "azure-dev"
}
],
Expand All @@ -205,62 +205,62 @@
"group": "10provision@10"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.provision",
"group": "10provision@10"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.deploy",
"group": "10provision@20"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.up",
"group": "10provision@30"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.down",
"group": "10provision@40"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.env-new",
"group": "20env@10"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.env-select",
"group": "20env@20"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.env-refresh",
"group": "20env@30"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.env-list",
"group": "20env@40"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.restore",
"group": "30develop@10"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.package",
"group": "30develop@20"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.pipeline-config",
"group": "30develop@30"
},
{
"when": "resourceFilename =~ /azure.yaml/i",
"when": "resourceFilename =~ /azure.ya?ml/i",
"command": "azure-dev.commands.cli.monitor",
"group": "40monitor@10"
}
Expand Down Expand Up @@ -500,6 +500,10 @@
{
"fileMatch": "azure.yaml",
"url": "https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json"
},
{
"fileMatch": "azure.yml",
"url": "https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json"
}
]
},
Expand Down
11 changes: 6 additions & 5 deletions ext/vscode/src/commands/cmdUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { createAzureDevCli } from '../utils/azureDevCli';
import { execAsync } from '../utils/execAsync';
import { fileExists } from '../utils/fileUtils';

const AzureYamlGlobPattern: vscode.GlobPattern = '**/[aA][zZ][uU][rR][eE].[yY][aA][mM][lL]';
const AzureYamlGlobPattern: vscode.GlobPattern = '**/[aA][zZ][uU][rR][eE].{[yY][aA][mM][lL],[yY][mM][lL]}';

// If the command was invoked with a specific file context, use the file context as the working directory for running Azure developer CLI commands.
// Otherwise search the workspace for "azure.yaml" files. If only one is found, use it (i.e. its folder). If more than one is found, ask the user which one to use.
// Otherwise search the workspace for "azure.yaml" or "azure.yml" files. If only one is found, use it (i.e. its folder). If more than one is found, ask the user which one to use.
// If at this point we still do not have a working directory, prompt the user to select one.
export async function getWorkingFolder(context: IActionContext, selectedFile?: vscode.Uri): Promise<string> {
let folderPath = selectedFile ? path.dirname(selectedFile.fsPath) : undefined;
Expand All @@ -39,10 +39,11 @@ export async function getWorkingFolder(context: IActionContext, selectedFile?: v

const folderUri = localFolderUris[0];
const azureYamlUri = vscode.Uri.joinPath(folderUri, 'azure.yaml');
const azureYmlUri = vscode.Uri.joinPath(folderUri, 'azure.yml');

if (!await fileExists(azureYamlUri)) {
if (!await fileExists(azureYamlUri) && !await fileExists(azureYmlUri)) {
context.errorHandling.suppressReportIssue = true;
throw new Error(vscode.l10n.t("The selected folder does not contain 'azure.yaml' file and cannot be used to run Azure Developer CLI commands"));
throw new Error(vscode.l10n.t("The selected folder does not contain 'azure.yaml' or 'azure.yml' file and cannot be used to run Azure Developer CLI commands"));
}

folderPath = folderUri.fsPath;
Expand All @@ -66,7 +67,7 @@ export async function pickAzureYamlFile(context: IActionContext): Promise<vscode
const chosenFile = await context.ui.showQuickPick(choices, {
canPickMany: false,
suppressPersistence: true,
placeHolder: vscode.l10n.t("Select configuration file ('azure.yaml') to use for running Azure developer CLI commands")
placeHolder: vscode.l10n.t("Select configuration file ('azure.yaml' or 'azure.yml') to use for running Azure developer CLI commands")
});

filePath = chosenFile.data;
Expand Down
Loading