Skip to content

Commit ba04e09

Browse files
committed
Merge pull request Azure#1697 from arroyc/clu
Az --help generator and fix bug on buildpackage.ps1
2 parents ad50fd7 + f65d6fa commit ba04e09

File tree

7 files changed

+130
-24
lines changed

7 files changed

+130
-24
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
***Welcome to the azure management commands***
2+
3+
Run 'azure help' to get a list of all commands.

src/CLU/Microsoft.CLU/CommandBinder/CmdletBinderAndCommand.cs

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,18 +172,73 @@ public bool TryBindSwitch(string name)
172172
/// </summary>
173173
/// <param name="args">The command-line arguments to be considered in the help logic.</param>
174174
/// <returns>A list of lines containing help information.</returns>
175-
public IEnumerable<string> ListCommands(string[] args)
175+
public IEnumerable<string> ListCommands(string[] args, bool autoComplete)
176176
{
177177
#if PSCMDLET_HELP
178178
return CmdletHelp.Generate(parser.FormatParameterName, _discriminatorBinder.Modules, args, prefix);
179179
#else
180180
var commands = CommandDispatchHelper
181181
.CompleteCommands(new HelpPackageFinder(CLUEnvironment.GetPackagesRootPath()), args).ToArray();
182+
//
183+
string strCmdLine = string.Join(";", args);
184+
System.Collections.IDictionary commandPortion = new Dictionary<String, int>();
182185
if (commands.Length > 0)
183186
{
184187
foreach (var command in commands)
185188
{
186-
yield return command.Discriminators.Replace(';', ' ');
189+
if (!autoComplete) //--complete was not typed in commandline
190+
{
191+
yield return command.Discriminators.Replace(';', ' ');
192+
}
193+
else // "--complete" was typed in commandline
194+
{
195+
string strMatchedPart = command.Discriminators;
196+
string strUnmatchedPart = strMatchedPart.Substring(strCmdLine.Length);
197+
string result = "";
198+
int lastPosition, nextPosition;
199+
if (strUnmatchedPart.Length > 0)
200+
{
201+
bool isSemiColon = String.Equals(';', strUnmatchedPart.ElementAt(0));
202+
if (!isSemiColon)
203+
{
204+
//last command portion is incomplete, e.g "az vm c" so get back to previous position of ";"
205+
lastPosition = strCmdLine.LastIndexOf(";") + 1;
206+
nextPosition = strUnmatchedPart.IndexOf(";");
207+
if (nextPosition < 0)
208+
{
209+
result = strMatchedPart.Substring(lastPosition);//no command word portion left
210+
}
211+
else
212+
{
213+
//remaining command word
214+
result = strMatchedPart.Substring(lastPosition, nextPosition
215+
+ strCmdLine.Length - lastPosition);
216+
}
217+
}
218+
else
219+
{
220+
//last command portion is complete, e.g "az vm" so process next command word
221+
nextPosition = strUnmatchedPart.IndexOf(";", 1);
222+
if (nextPosition >= 0)
223+
{
224+
result = strUnmatchedPart.Substring(1, nextPosition - 1);//multiple command words exist
225+
}
226+
else
227+
{
228+
result = strUnmatchedPart.Substring(1); //only command word left
229+
}
230+
}
231+
}
232+
if (commandPortion.Contains(result))
233+
{
234+
continue;
235+
}
236+
else
237+
{
238+
commandPortion.Add(result, 1);
239+
yield return result.Replace(';', ' ');
240+
}
241+
}
187242
}
188243
}
189244
else
@@ -193,9 +248,9 @@ public IEnumerable<string> ListCommands(string[] args)
193248
#endif
194249
}
195250

196-
#endregion
251+
#endregion
197252

198-
#region ICommand implementation
253+
#region ICommand implementation
199254

200255
/// <summary>
201256
/// Tells whether the command is synchronous or asynchronous.
@@ -280,7 +335,7 @@ public Task InvokeAsync()
280335
throw new InvalidOperationException(Strings.CmdletBinderAndCommand_InvokeAsync_CmdletNotSupportAsyncInvoke);
281336
}
282337

283-
#endregion
338+
#endregion
284339

285340
public void MarkStaticParameterBindFinished()
286341
{
@@ -346,7 +401,7 @@ private Cmdlet CreateCmdlet(Type cmdletType, string assemblyLocation)
346401
/// <param name="cmdletType">The cmdlet types</param>
347402
private void InitCmdlet(Type cmdletType, string assemblyLocation)
348403
{
349-
_cmdlet = CreateCmdlet(cmdletType,assemblyLocation);
404+
_cmdlet = CreateCmdlet(cmdletType, assemblyLocation);
350405
_cmdletMetadata = CmdletMetadata.Load(_cmdlet);
351406
_staticParametersBindState = new ParameterBindState(_cmdletMetadata.Type);
352407
_staticParametersBindHandler = new BindHandler(_cmdlet, _staticParametersBindState);
@@ -665,6 +720,6 @@ private static bool MatchesParameterSet(ParameterMetadata parameter, string para
665720
/// </summary>
666721
private bool _positionalArgumentsBounded;
667722

668-
#endregion
723+
#endregion
669724
}
670725
}

src/CLU/Microsoft.CLU/CommandBinder/ICommandBinder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ public interface ICommandBinder
3838
/// <summary>
3939
/// List the set of possible command matches for the given set of commands
4040
/// </summary>
41-
IEnumerable<string> ListCommands(string[] args);
41+
IEnumerable<string> ListCommands(string[] args, bool autoComplete);
4242
}
4343
}

src/CLU/Microsoft.CLU/CommandLineParser/UnixCommandLineParser.cs

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ public bool Parse(ICommandBinder commandBinder, string[] arguments)
4747
}
4848

4949
int position = 0;
50-
for (; _positionIndicator < arguments.Length; _positionIndicator++)
50+
int argLength = arguments.Length;
51+
if (String.Equals(arguments[argLength - 1], "--complete"))
52+
{
53+
argLength = argLength - 1;
54+
}
55+
for (; _positionIndicator < argLength; _positionIndicator++)
5156
{
5257
var arg = arguments[_positionIndicator];
5358

@@ -122,8 +127,8 @@ public bool Parse(ICommandBinder commandBinder, string[] arguments)
122127
}
123128
else
124129
{
125-
if (position == 0 &&
126-
commandBinder.SupportsAutomaticHelp &&
130+
if (position == 0 &&
131+
commandBinder.SupportsAutomaticHelp &&
127132
arg.Equals("help", System.StringComparison.OrdinalIgnoreCase))
128133
{
129134
PresentCommandCompletion(arguments.Skip(position + 1).ToArray());
@@ -167,7 +172,7 @@ public void SeekBack(uint offset)
167172
/// </example>
168173
public string FormatParameterName(string name, string type, bool isMandatory, bool isPositional)
169174
{
170-
Func<string,string> nameFunc = n => n.Length == 1 ? "-" + n : "--" + n.ToLowerInvariant();
175+
Func<string, string> nameFunc = n => n.Length == 1 ? "-" + n : "--" + n.ToLowerInvariant();
171176

172177
var builder = new System.Text.StringBuilder();
173178
if (!isMandatory)
@@ -195,15 +200,39 @@ private void PresentCommandCompletion(string[] arguments)
195200

196201
private void PresentCommandHelp(string[] arguments)
197202
{
198-
// BUGBUG - NYI!
203+
// Static help implementation of "az --help"
199204
if (arguments.Length == 0)
200205
{
201-
// TODO
202-
Console.WriteLine("Present help for Azure itself...");
206+
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(CLUEnvironment.GetPackagesRootPath());
207+
String rootPath = CLUEnvironment.GetPackagesRootPath();
208+
try
209+
{
210+
var files = from file in System.IO.Directory.EnumerateFiles(@rootPath, "az.hlp",
211+
System.IO.SearchOption.AllDirectories)
212+
from line in System.IO.File.ReadLines(file)
213+
select new
214+
{
215+
File = file,
216+
Line = line
217+
};
218+
219+
foreach (var f in files)
220+
{
221+
Console.WriteLine(f.Line);
222+
}
223+
}
224+
catch (Exception e)
225+
{
226+
Console.WriteLine(e.Message);
227+
}
228+
229+
return;
230+
203231
}
204232
else
205-
{
206-
var helpFile = CommandDispatchHelper.FindBestHelp(new HelpPackageFinder(CLUEnvironment.GetPackagesRootPath()), arguments);
233+
{
234+
var helpFile = CommandDispatchHelper.FindBestHelp(new HelpPackageFinder
235+
(CLUEnvironment.GetPackagesRootPath()), arguments);
207236
if (helpFile != null)
208237
{
209238
// Found appropriate help...

src/CLU/Microsoft.CLU/CommandModel/CmdletCommandModel.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,16 @@ public CommandModelErrorCode Run(ConfigurationDictionary commandConfiguration, s
2323
{
2424
Debug.Assert(commandConfiguration != null);
2525
Debug.Assert(arguments != null);
26-
2726
if (arguments.Length < 1)
2827
{
2928
throw new ArgumentException(Strings.CmdletCommandModel_Run_MissingMinimalArguments);
3029
}
31-
30+
bool isComplete = false;
31+
//assuming --complete will always be typed at the end
32+
if (String.Equals(arguments[arguments.Length - 1], "--complete"))
33+
{
34+
isComplete = true;
35+
}
3236
Init(commandConfiguration);
3337
IPipe<string> pipe = new ConsolePipe(CLUEnvironment.Console);
3438
HostStreamInfo hostStreamInfo = new HostStreamInfo
@@ -92,10 +96,15 @@ public CommandModelErrorCode Run(ConfigurationDictionary commandConfiguration, s
9296
}
9397
catch (CommandNotFoundException)
9498
{
95-
var helplines = binderAndCommand.ListCommands(binderAndCommand.Discriminators.ToArray());
99+
var helplines = binderAndCommand.ListCommands(binderAndCommand.Discriminators.ToArray(), isComplete);
100+
string strNoCommand = string.Format(Strings.CmdletHelp_Generate_NoCommandAvailable,
101+
CLUEnvironment.ScriptName, String.Join(" ", binderAndCommand.Discriminators.ToArray()));
96102
foreach (var entry in helplines)
97103
{
98-
CLUEnvironment.Console.WriteLine(entry);
104+
if (!String.Equals(strNoCommand, entry))
105+
{
106+
System.Console.WriteLine(entry);
107+
}
99108
}
100109
return CommandModelErrorCode.CommandNotFound;
101110
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
_azcomp2()
2+
{
3+
export params=$(printf "%s " "${COMP_WORDS[@]:1}")
4+
COMPREPLY=( $(${1} ${params} --complete) )
5+
return 0
6+
}
7+
8+
complete -F _azcomp2 ./az

tools/CLU/BuildPackage.ps1

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ if ([string]::IsNullOrWhiteSpace($env:WORKSPACE) -or !(Test-Path $env:WORKSPACE)
1717
$packageSource = $packageSource.TrimEnd('\\')
1818
Write-Host "using package id: $packageId, package source: $packageSource, packageVersion: $packageVersion"
1919
dotnet publish $cmdletsDir -f dnxcore50 -r win7-x64 -o $packageSource
20-
Copy-Item -Path $cmdletsDir\content -Destination $packageSource\content -Recurse -Force
21-
Copy-Item -Path $cmdletsDir\*xml -Destination $packageSource\content -Force
20+
Write-Host "CMDLETSDIR is .."+$cmdletsDir
21+
Write-Host "packageSource is .."+$packageSource
22+
Copy-Item -Path $cmdletsDir\content -Destination $packageSource\ -Recurse -Force
23+
Copy-Item -Path $cmdletsDir\*xml -Destination $packageSource\ -Force
2224

2325
$nuSpecTemplate = (Get-ChildItem ([System.IO.Path]::Combine($cmdletsDir, ($packageId + ".nuspec.template"))))
2426
$nuSpecOutput = [System.IO.Path]::Combine($packageSource, ($packageId + ".nuspec"))
@@ -37,7 +39,7 @@ if ($packageId -ne "Microsoft.CLU.Commands")
3739
$contentFileText += " <file src=""content\*xml"" target=""content""/>`r`n"
3840
if (Test-Path "$packageSource\content\help")
3941
{
40-
$contentFileText += " <file src=""content\help\*.hlp"" target=""content\help""/>`r`n"
42+
$contentFileText += " <file src=""content\help\*hlp"" target=""content\help""/>`r`n"
4143
}
4244
}
4345
if ($renameFileExists)

0 commit comments

Comments
 (0)