Skip to content

Commit 4e571e6

Browse files
authored
Merge pull request #1074 from Azure/dev
Update master with 2.0.12309
2 parents bd7756a + 7aee2de commit 4e571e6

File tree

17 files changed

+281
-27
lines changed

17 files changed

+281
-27
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,18 @@ brew install azure-functions-core-tools
6060
#### Ubuntu/Debian
6161

6262
1. Set up package feed
63-
##### Ubuntu 18.04
63+
64+
##### Ubuntu 18.10
6465

6566
```bash
66-
wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
67+
wget -q https://packages.microsoft.com/config/ubuntu/18.10/packages-microsoft-prod.deb
6768
sudo dpkg -i packages-microsoft-prod.deb
6869
```
6970

70-
##### Ubuntu 17.10
71+
##### Ubuntu 18.04
7172

7273
```bash
73-
wget -q https://packages.microsoft.com/config/ubuntu/17.10/packages-microsoft-prod.deb
74+
wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
7475
sudo dpkg -i packages-microsoft-prod.deb
7576
```
7677

build/Settings.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ private static string config(string @default = null, [CallerMemberName] string k
4242

4343
public const string DistLibUrl = "https://github.com/vsajip/distlib/archive/15dba58a827f56195b0fa0afe80a8925a92e8bf5.zip";
4444

45-
public const string PythonWorkerUrl = "https://raw.githubusercontent.com/Azure/azure-functions-python-worker/1.0.0b3/python/worker.py";
45+
public const string PythonWorkerUrl = "https://raw.githubusercontent.com/Azure/azure-functions-python-worker/1.0.0b4/python/worker.py";
4646

47-
public const string PythonWorkerConfigUrl = "https://raw.githubusercontent.com/Azure/azure-functions-python-worker/1.0.0b3/python/worker.config.json";
47+
public const string PythonWorkerConfigUrl = "https://raw.githubusercontent.com/Azure/azure-functions-python-worker/1.0.0b4/python/worker.config.json";
4848

4949
public static readonly string OutputDir = Path.Combine(Path.GetFullPath(".."), "artifacts");
5050

src/Azure.Functions.Cli/Actions/DeployActions/Platforms/Models/FunctionJson.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ public class FunctionJson
1515
{
1616
public bool disabled { get; set; }
1717
public List<Binding> bindings { get; set; }
18+
public string scriptFile { get; set; }
1819
}
1920
}

src/Azure.Functions.Cli/Actions/LocalActions/CreateFunctionAction.cs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
using System.IO;
44
using System.Linq;
55
using System.Threading.Tasks;
6+
using Azure.Functions.Cli.Actions.DeployActions.Platforms.Models;
67
using Azure.Functions.Cli.Common;
78
using Azure.Functions.Cli.Helpers;
89
using Azure.Functions.Cli.Interfaces;
910
using Colors.Net;
1011
using Fclp;
12+
using Newtonsoft.Json;
1113
using static Azure.Functions.Cli.Common.OutputTheme;
1214

1315
namespace Azure.Functions.Cli.Actions.LocalActions
@@ -76,11 +78,11 @@ public async override Task RunAsync()
7678
if (workerRuntime != WorkerRuntime.None && !string.IsNullOrWhiteSpace(Language))
7779
{
7880
// validate
79-
var language = WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(Language);
80-
if (workerRuntime != language)
81+
var workerRuntimeSelected = WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(Language);
82+
if (workerRuntime != workerRuntimeSelected)
8183
{
8284
throw new CliException("Selected language doesn't match worker set in local.settings.json." +
83-
$"Selected worker is: {workerRuntime} and selected language is: {language}");
85+
$"Selected worker is: {workerRuntime} and selected language is: {workerRuntimeSelected}");
8486
}
8587
}
8688
else if (string.IsNullOrWhiteSpace(Language))
@@ -103,7 +105,7 @@ public async override Task RunAsync()
103105
{
104106
Language = displayList.First();
105107
}
106-
else
108+
else if (!InferAndUpdateLanguage(workerRuntime))
107109
{
108110
ColoredConsole.Write("Select a language: ");
109111
Language = SelectionMenuHelper.DisplaySelectionWizard(displayList);
@@ -128,7 +130,16 @@ public async override Task RunAsync()
128130
else
129131
{
130132
ColoredConsole.Write("Select a template: ");
131-
var templateLanguage = WorkerRuntimeLanguageHelper.GetTemplateLanguageFromWorker(workerRuntime);
133+
string templateLanguage;
134+
try
135+
{
136+
templateLanguage = WorkerRuntimeLanguageHelper.NormalizeLanguage(Language);
137+
}
138+
catch (Exception)
139+
{
140+
// Ideally this should never happen.
141+
templateLanguage = WorkerRuntimeLanguageHelper.GetDefaultTemplateLanguageFromWorker(workerRuntime);
142+
}
132143
TemplateName = TemplateName ?? SelectionMenuHelper.DisplaySelectionWizard(templates.Where(t => t.Metadata.Language.Equals(templateLanguage, StringComparison.OrdinalIgnoreCase)).Select(t => t.Metadata.Name).Distinct());
133144
ColoredConsole.WriteLine(TitleColor(TemplateName));
134145

@@ -145,9 +156,34 @@ public async override Task RunAsync()
145156
FunctionName = FunctionName ?? Console.ReadLine();
146157
FunctionName = string.IsNullOrEmpty(FunctionName) ? template.Metadata.DefaultFunctionName : FunctionName;
147158
await _templatesManager.Deploy(FunctionName, template);
159+
PerformPostDeployTasks(FunctionName, Language);
148160
}
149161
}
150162
ColoredConsole.WriteLine($"The function \"{FunctionName}\" was created successfully from the \"{TemplateName}\" template.");
151163
}
164+
165+
private bool InferAndUpdateLanguage(WorkerRuntime workerRuntime)
166+
{
167+
// If there is a tsconfig.json present, we assume that the language is typescript
168+
if (workerRuntime == WorkerRuntime.node)
169+
{
170+
Language = FileSystemHelpers.FileExists(Path.Combine(Environment.CurrentDirectory, "tsconfig.json")) ? Constants.Languages.TypeScript : Constants.Languages.JavaScript;
171+
return true;
172+
}
173+
return false;
174+
}
175+
176+
private void PerformPostDeployTasks(string functionName, string language)
177+
{
178+
if (language == Constants.Languages.TypeScript)
179+
{
180+
// Update typescript function.json
181+
var funcJsonFile = Path.Combine(Environment.CurrentDirectory, functionName, Constants.FunctionJsonFileName);
182+
var jsonStr = FileSystemHelpers.ReadAllTextFromFile(funcJsonFile);
183+
var funcObj = JsonConvert.DeserializeObject<FunctionJson>(jsonStr);
184+
funcObj.scriptFile = $"../dist/{functionName}/index.js";
185+
FileSystemHelpers.WriteAllTextToFile(funcJsonFile, JsonConvert.SerializeObject(funcObj, Formatting.Indented));
186+
}
187+
}
152188
}
153189
}

src/Azure.Functions.Cli/Actions/LocalActions/InitAction.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ internal class InitAction : BaseAction
3232

3333
public bool Csx { get; set; }
3434

35+
public string Language { get; set; }
36+
3537
internal readonly Dictionary<Lazy<string>, Task<string>> fileToContentMap = new Dictionary<Lazy<string>, Task<string>>
3638
{
3739
{ new Lazy<string>(() => ".gitignore"), StaticResources.GitIgnore },
@@ -74,6 +76,12 @@ public override ICommandLineParserResult ParseArgs(string[] args)
7476
.WithDescription("use csx dotnet functions")
7577
.Callback(f => Csx = f);
7678

79+
Parser
80+
.Setup<string>("language")
81+
.SetDefault(null)
82+
.WithDescription("Initialize a language specific project. Currently supported when --worker-runtime set to node. Options are - \"typescript\" and \"javascript\"")
83+
.Callback(l => Language = l);
84+
7785
if (args.Any() && !args.First().StartsWith("-"))
7886
{
7987
FolderName = args.First();
@@ -109,10 +117,12 @@ public override async Task RunAsync()
109117
var workerRuntimeString = SelectionMenuHelper.DisplaySelectionWizard(workerRuntimeToDisplayString.Values);
110118
workerRuntime = workerRuntimeToDisplayString.FirstOrDefault(wr => wr.Value.Equals(workerRuntimeString)).Key;
111119
ColoredConsole.WriteLine(TitleColor(workerRuntime.ToString()));
120+
LanguageSelectionIfRelevant(workerRuntime);
112121
}
113122
else
114123
{
115124
workerRuntime = WorkerRuntimeLanguageHelper.NormalizeWorkerRuntime(WorkerRuntime);
125+
Language = Language ?? WorkerRuntimeLanguageHelper.NormalizeLanguage(WorkerRuntime);
116126
}
117127

118128
if (workerRuntime == Helpers.WorkerRuntime.dotnet && !Csx)
@@ -131,6 +141,20 @@ public override async Task RunAsync()
131141
await WriteDockerfile(workerRuntime);
132142
}
133143

144+
private void LanguageSelectionIfRelevant(WorkerRuntime workerRuntime)
145+
{
146+
if (workerRuntime == Helpers.WorkerRuntime.node)
147+
{
148+
if (WorkerRuntimeLanguageHelper.WorkerToSupportedLanguages.TryGetValue(workerRuntime, out IEnumerable<string> languages)
149+
&& languages.Count() != 0)
150+
{
151+
ColoredConsole.Write("Select a Language: ");
152+
Language = SelectionMenuHelper.DisplaySelectionWizard(languages);
153+
ColoredConsole.WriteLine(TitleColor(Language));
154+
}
155+
}
156+
}
157+
134158
private async Task InitLanguageSpecificArtifacts(WorkerRuntime workerRuntime)
135159
{
136160
if (workerRuntime == Helpers.WorkerRuntime.python)
@@ -141,6 +165,12 @@ private async Task InitLanguageSpecificArtifacts(WorkerRuntime workerRuntime)
141165
{
142166
await WriteFiles("profile.ps1", await StaticResources.PowerShellProfilePs1);
143167
}
168+
if (Language == Constants.Languages.TypeScript)
169+
{
170+
await WriteFiles(".funcignore", await StaticResources.FuncIgnore);
171+
await WriteFiles("package.json", await StaticResources.PackageJson);
172+
await WriteFiles("tsconfig.json", await StaticResources.TsConfig);
173+
}
144174
}
145175

146176
private async Task WriteLocalSettingsJson(WorkerRuntime workerRuntime)

src/Azure.Functions.Cli/Azure.Functions.Cli.csproj

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@
6363
<EmbeddedResource Include="StaticResources\templates.json">
6464
<LogicalName>$(AssemblyName).templates.json</LogicalName>
6565
</EmbeddedResource>
66+
<EmbeddedResource Include="StaticResources\package.json">
67+
<LogicalName>$(AssemblyName).package.json</LogicalName>
68+
</EmbeddedResource>
69+
<EmbeddedResource Include="StaticResources\tsconfig.json">
70+
<LogicalName>$(AssemblyName).tsconfig.json</LogicalName>
71+
</EmbeddedResource>
72+
<EmbeddedResource Include="StaticResources\funcignore">
73+
<LogicalName>$(AssemblyName).funcignore</LogicalName>
74+
</EmbeddedResource>
6675
</ItemGroup>
6776
<ItemGroup>
6877
<Content Include="..\..\tools\python\packapp\__main__.py">
@@ -81,7 +90,7 @@
8190
<PackageReference Include="Microsoft.Azure.Functions.JavaWorker" Version="1.3.0-SNAPSHOT" />
8291
<PackageReference Include="Microsoft.Azure.Functions.NodeJsWorker" Version="1.0.1" />
8392
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker" Version="0.1.63-preview" />
84-
<PackageReference Include="Microsoft.Azure.WebJobs.Script.WebHost" Version="2.0.12303" />
93+
<PackageReference Include="Microsoft.Azure.WebJobs.Script.WebHost" Version="2.0.12309" />
8594
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
8695
</ItemGroup>
8796
</Project>

src/Azure.Functions.Cli/Common/Constants.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ public static class Errors
4848
public const string ExtensionsNeedDotnet = "Extensions command requires dotnet on your path. Please make sure to install dotnet (.NET Core SDK) for your system from https://www.microsoft.com/net/download";
4949
}
5050

51+
public static class Languages
52+
{
53+
public const string JavaScript = "javascript";
54+
public const string TypeScript = "typescript";
55+
public const string Python = "python";
56+
public const string CSharp = "c#";
57+
public const string Powershell = "powershell";
58+
public const string Java = "java";
59+
}
60+
5161
public static class ArmConstants
5262
{
5363
public const string AADAuthorityBase = "https://login.microsoftonline.com";
@@ -59,7 +69,7 @@ public static class ArmConstants
5969

6070
public static class DockerImages
6171
{
62-
public const string LinuxPythonImageAmd64 = "mcr.microsoft.com/azure-functions/python:2.0.12285";
72+
public const string LinuxPythonImageAmd64 = "mcr.microsoft.com/azure-functions/python:2.0.12309";
6373
}
6474

6575
public static class StaticResourcesNames

src/Azure.Functions.Cli/Helpers/PythonHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Azure.Functions.Cli.Helpers
1313
{
1414
public static class PythonHelpers
1515
{
16-
private static readonly string[] _workerPackages = new[] { "azure-functions==1.0.0b3", "azure-functions-worker==1.0.0b3" };
16+
private static readonly string[] _workerPackages = new[] { "azure-functions==1.0.0b3", "azure-functions-worker==1.0.0b4" };
1717
private static bool InVirtualEnvironment => !string.IsNullOrEmpty(VirtualEnvironmentPath);
1818
public static string VirtualEnvironmentPath => Environment.GetEnvironmentVariable("VIRTUAL_ENV");
1919

src/Azure.Functions.Cli/Helpers/WorkerRuntimeLanguageHelper.cs

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public static class WorkerRuntimeLanguageHelper
2323
private static readonly IDictionary<WorkerRuntime, IEnumerable<string>> availableWorkersRuntime = new Dictionary<WorkerRuntime, IEnumerable<string>>
2424
{
2525
{ WorkerRuntime.dotnet, new [] { "c#", "csharp", "f#", "fsharp" } },
26-
{ WorkerRuntime.node, new [] { "js", "javascript" } },
26+
{ WorkerRuntime.node, new [] { "js", "javascript", "typescript", "ts" } },
2727
{ WorkerRuntime.python, new [] { "py" } },
2828
{ WorkerRuntime.java, new string[] { } },
2929
{ WorkerRuntime.powershell, new [] { "pwsh" } }
@@ -34,12 +34,33 @@ public static class WorkerRuntimeLanguageHelper
3434
.SelectMany(i => i)
3535
.ToDictionary(k => k.key, v => v.value, StringComparer.OrdinalIgnoreCase);
3636

37-
private static readonly IDictionary<WorkerRuntime, string> workerToLanguageMap = new Dictionary<WorkerRuntime, string>
37+
private static readonly IDictionary<WorkerRuntime, string> workerToDefaultLanguageMap = new Dictionary<WorkerRuntime, string>
3838
{
39-
{ WorkerRuntime.dotnet, "c#" },
40-
{ WorkerRuntime.node, "javascript" },
41-
{ WorkerRuntime.python, "python" },
42-
{ WorkerRuntime.powershell, "powershell" }
39+
{ WorkerRuntime.dotnet, Constants.Languages.CSharp },
40+
{ WorkerRuntime.node, Constants.Languages.JavaScript },
41+
{ WorkerRuntime.python, Constants.Languages.Python },
42+
{ WorkerRuntime.powershell, Constants.Languages.Powershell }
43+
};
44+
45+
private static readonly IDictionary<string, IEnumerable<string>> languageToAlias = new Dictionary<string, IEnumerable<string>>
46+
{
47+
// By default node should map to javascript
48+
{ Constants.Languages.JavaScript, new [] { "js", "node" } },
49+
{ Constants.Languages.TypeScript, new [] { "ts" } },
50+
{ Constants.Languages.Python, new [] { "py" } },
51+
{ Constants.Languages.Powershell, new [] { "pwsh" } },
52+
{ Constants.Languages.CSharp, new [] { "csharp", "dotnet" } },
53+
{ Constants.Languages.Java, new string[] { } }
54+
};
55+
56+
public static readonly IDictionary<string, string> WorkerRuntimeStringToLanguage = languageToAlias
57+
.Select(p => p.Value.Select(v => new { key = v, value = p.Key }).Append(new { key = p.Key.ToString(), value = p.Key }))
58+
.SelectMany(i => i)
59+
.ToDictionary(k => k.key, v => v.value, StringComparer.OrdinalIgnoreCase);
60+
61+
public static readonly IDictionary<WorkerRuntime, IEnumerable<string>> WorkerToSupportedLanguages = new Dictionary<WorkerRuntime, IEnumerable<string>>
62+
{
63+
{ WorkerRuntime.node, new [] { Constants.Languages.JavaScript, Constants.Languages.TypeScript } }
4364
};
4465

4566
public static string AvailableWorkersRuntimeString =>
@@ -86,6 +107,22 @@ public static WorkerRuntime NormalizeWorkerRuntime(string workerRuntime)
86107
}
87108
}
88109

110+
public static string NormalizeLanguage(string languageString)
111+
{
112+
if (string.IsNullOrWhiteSpace(languageString))
113+
{
114+
throw new ArgumentNullException(nameof(languageString), "language can't be empty");
115+
}
116+
else if (normalizeMap.ContainsKey(languageString))
117+
{
118+
return WorkerRuntimeStringToLanguage[languageString];
119+
}
120+
else
121+
{
122+
throw new ArgumentException($"Language '{languageString}' is not available. Available language strings are {WorkerRuntimeStringToLanguage.Keys}");
123+
}
124+
}
125+
89126
public static IEnumerable<string> LanguagesForWorker(WorkerRuntime worker)
90127
{
91128
return normalizeMap.Where(p => p.Value == worker).Select(p => p.Key);
@@ -116,13 +153,13 @@ internal static WorkerRuntime SetWorkerRuntime(ISecretsManager secretsManager, s
116153
return worker;
117154
}
118155

119-
public static string GetTemplateLanguageFromWorker(WorkerRuntime worker)
156+
public static string GetDefaultTemplateLanguageFromWorker(WorkerRuntime worker)
120157
{
121-
if (!workerToLanguageMap.ContainsKey(worker))
158+
if (!workerToDefaultLanguageMap.ContainsKey(worker))
122159
{
123160
throw new ArgumentException($"Worker runtime '{worker}' is not a valid worker for a template.");
124161
}
125-
return workerToLanguageMap[worker];
162+
return workerToDefaultLanguageMap[worker];
126163
}
127164
}
128165
}

src/Azure.Functions.Cli/StaticResources/StaticResources.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,11 @@ private static async Task<string> GetValue(string name)
5050
public static Task<string> PowerShellProfilePs1 => GetValue("profile.ps1");
5151

5252
public static Task<string> TemplatesJson => GetValue("templates.json");
53+
54+
public static Task<string> FuncIgnore => GetValue("funcignore");
55+
56+
public static Task<string> PackageJson => GetValue("package.json");
57+
58+
public static Task<string> TsConfig => GetValue("tsconfig.json");
5359
}
5460
}

0 commit comments

Comments
 (0)