You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2017/07/11 07:42:29 UTC
[04/22] lucenenet git commit: Added lucene-cli + tests - a wrapper
console application so we can run the various utilities and demos in .NET on
the command line.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/Lucene.Net.Tests.Cli/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/tools/Lucene.Net.Tests.Cli/Properties/AssemblyInfo.cs b/src/tools/Lucene.Net.Tests.Cli/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a5b2792
--- /dev/null
+++ b/src/tools/Lucene.Net.Tests.Cli/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Lucene.Net.Tests.Cli")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("495b65f0-0b01-40fe-9dc8-5a82c49e07ef")]
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/Lucene.Net.Tests.Cli/SourceCode/SourceCodeParserTest.cs
----------------------------------------------------------------------
diff --git a/src/tools/Lucene.Net.Tests.Cli/SourceCode/SourceCodeParserTest.cs b/src/tools/Lucene.Net.Tests.Cli/SourceCode/SourceCodeParserTest.cs
new file mode 100644
index 0000000..23ae032
--- /dev/null
+++ b/src/tools/Lucene.Net.Tests.Cli/SourceCode/SourceCodeParserTest.cs
@@ -0,0 +1,72 @@
+using Lucene.Net.Support;
+using NUnit.Framework;
+using System.IO;
+using System.Reflection;
+
+namespace Lucene.Net.Cli.SourceCode
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class SourceCodeParserTest
+ {
+ [Test]
+ public void TestSourceCodeSectionParser()
+ {
+ var parser = new SourceCodeSectionParser();
+ var thisAssembly = this.GetType().GetTypeInfo().Assembly;
+
+ using (var output = new MemoryStream())
+ {
+ using (var input = thisAssembly.FindAndGetManifestResourceStream(this.GetType(), "TestInputForParser.cs"))
+ {
+ parser.ParseSourceCodeFiles(input, output);
+ }
+
+ output.Seek(0, SeekOrigin.Begin);
+
+ using (var reader = new StreamReader(output, SourceCodeSectionParser.ENCODING))
+ {
+ Assert.AreEqual("using System;", reader.ReadLine());
+ Assert.AreEqual("using System.Collections.Generic;", reader.ReadLine());
+ Assert.AreEqual("using System.Linq;", reader.ReadLine());
+ Assert.AreEqual("using System.Threading.Tasks;", reader.ReadLine());
+ Assert.AreEqual("using System.Reflection;", reader.ReadLine());
+ Assert.AreEqual("using System.Xml;", reader.ReadLine());
+ Assert.AreEqual("", reader.ReadLine());
+ Assert.AreEqual("namespace Lucene.Net.Cli.SourceCode", reader.ReadLine());
+ Assert.AreEqual("{", reader.ReadLine());
+ Assert.AreEqual(" public class TestInputForParser", reader.ReadLine());
+ Assert.AreEqual(" {", reader.ReadLine());
+ Assert.AreEqual(" public void Foo()", reader.ReadLine());
+ Assert.AreEqual(" {", reader.ReadLine());
+ Assert.AreEqual(" Console.WriteLine(\"Foo\");", reader.ReadLine());
+ Assert.AreEqual(" }", reader.ReadLine());
+ Assert.AreEqual("", reader.ReadLine());
+ Assert.AreEqual(" public void Bar()", reader.ReadLine());
+ Assert.AreEqual(" {", reader.ReadLine());
+ Assert.AreEqual(" Console.WriteLine(\"Bar2\");", reader.ReadLine());
+ Assert.AreEqual(" }", reader.ReadLine());
+ Assert.AreEqual(" }", reader.ReadLine());
+ Assert.AreEqual("}", reader.ReadLine());
+ Assert.AreEqual(null, reader.ReadLine());
+ Assert.AreEqual(null, reader.ReadLine());
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/Lucene.Net.Tests.Cli/SourceCode/TestInputForParser.cs
----------------------------------------------------------------------
diff --git a/src/tools/Lucene.Net.Tests.Cli/SourceCode/TestInputForParser.cs b/src/tools/Lucene.Net.Tests.Cli/SourceCode/TestInputForParser.cs
new file mode 100644
index 0000000..280fc1c
--- /dev/null
+++ b/src/tools/Lucene.Net.Tests.Cli/SourceCode/TestInputForParser.cs
@@ -0,0 +1,53 @@
+// <comment>
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// DO NOT ALTER THIS FILE, it is for testing purposes
+
+// </comment>
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+// <include>
+////using System.Reflection;
+////using System.Xml;
+// </include>
+
+namespace Lucene.Net.Cli.SourceCode
+{
+ public class TestInputForParser
+ {
+ public void Foo()
+ {
+ Console.WriteLine("Foo");
+ }
+
+ // <comment>
+ public void Bar()
+ {
+ Console.WriteLine("Bar1");
+ }
+ // </comment>
+ // <include>
+ ////public void Bar()
+ ////{
+ //// Console.WriteLine("Bar2");
+ ////}
+ // </include>
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/Lucene.Net.Tests.Cli/StringExtensions.cs
----------------------------------------------------------------------
diff --git a/src/tools/Lucene.Net.Tests.Cli/StringExtensions.cs b/src/tools/Lucene.Net.Tests.Cli/StringExtensions.cs
new file mode 100644
index 0000000..eeb4e80
--- /dev/null
+++ b/src/tools/Lucene.Net.Tests.Cli/StringExtensions.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace Lucene.Net.Cli
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public static class StringExtensions
+ {
+ public static string[] ToArgs(this string input)
+ {
+ return Regex.Replace(input.Trim(), @"\s+", " ").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
+ }
+
+ public static string OptionValue(this IEnumerable<string> args, string option)
+ {
+ return args.SkipWhile(a => a != option).Skip(1).FirstOrDefault();
+ }
+
+ public static IList<string> OptionValues(this IEnumerable<string> args, string option)
+ {
+ var argsList = new List<string>(args);
+ var result = new List<string>();
+ for (int i = 0; i < argsList.Count; i++)
+ {
+ string current = argsList[i];
+ if (current == option)
+ {
+ if (i == argsList.Count - 1)
+ {
+ result.Add(null);
+ }
+ else
+ {
+ current = argsList[i + 1];
+ if (current != option)
+ {
+ result.Add(current);
+ i++;
+ }
+ else
+ {
+ result.Add(null);
+ }
+ }
+ }
+ }
+ return result;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/Lucene.Net.Tests.Cli/project.json
----------------------------------------------------------------------
diff --git a/src/tools/Lucene.Net.Tests.Cli/project.json b/src/tools/Lucene.Net.Tests.Cli/project.json
new file mode 100644
index 0000000..9ff17e3
--- /dev/null
+++ b/src/tools/Lucene.Net.Tests.Cli/project.json
@@ -0,0 +1,35 @@
+{
+ "version": "4.8.0",
+ "title": "Lucene.Net.Tests.Cli",
+ "dependencies": {
+ "dotnet-test-nunit-teamcity": "3.4.0-beta-3",
+ "lucene-cli": "4.8.0",
+ "Lucene.Net": "4.8.0",
+ "Lucene.Net.TestFramework": "4.8.0",
+ "NUnit": "3.5.0"
+ },
+ "testRunner": "nunit-teamcity",
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports": "dnxcore50",
+ "buildOptions": {
+ "debugType": "portable",
+ "define": [ "NETSTANDARD" ],
+ "compile": {
+ "excludeFiles": [
+ "SourceCode/TestInputForParser.cs"
+ ]
+ },
+ "embed": {
+ "includeFiles": [
+ "SourceCode/TestInputForParser.cs"
+ ]
+ }
+ }
+ }
+ },
+ "runtimes": {
+ "win7-x86": {},
+ "win7-x64": {}
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/CommandLine/CommandArgument.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/CommandLine/CommandArgument.cs b/src/tools/lucene-cli/CommandLine/CommandArgument.cs
new file mode 100644
index 0000000..b7081e0
--- /dev/null
+++ b/src/tools/lucene-cli/CommandLine/CommandArgument.cs
@@ -0,0 +1,30 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Lucene.Net.Cli.CommandLine
+{
+ public class CommandArgument
+ {
+ public CommandArgument()
+ {
+ Values = new List<string>();
+ }
+
+ //public string Id { get; set; } // used to identify a command in the list
+ public virtual string Name { get; set; }
+ public bool ShowInHelpText { get; set; } = true;
+ public virtual string Description { get; set; }
+ public List<string> Values { get; private set; }
+ public bool MultipleValues { get; set; }
+ public virtual string Value
+ {
+ get
+ {
+ return Values.FirstOrDefault();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/CommandLine/CommandLineApplication.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/CommandLine/CommandLineApplication.cs b/src/tools/lucene-cli/CommandLine/CommandLineApplication.cs
new file mode 100644
index 0000000..978edad
--- /dev/null
+++ b/src/tools/lucene-cli/CommandLine/CommandLineApplication.cs
@@ -0,0 +1,563 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.Cli.CommandLine
+{
+ public class CommandLineApplication
+ {
+ // Indicates whether the parser should throw an exception when it runs into an unexpected argument.
+ // If this field is set to false, the parser will stop parsing when it sees an unexpected argument, and all
+ // remaining arguments, including the first unexpected argument, will be stored in RemainingArguments property.
+ private readonly bool _throwOnUnexpectedArg;
+
+ public CommandLineApplication(bool throwOnUnexpectedArg = true)
+ {
+ _throwOnUnexpectedArg = throwOnUnexpectedArg;
+ Options = new List<CommandOption>();
+ Arguments = new List<CommandArgument>();
+ Commands = new List<CommandLineApplication>();
+ RemainingArguments = new List<string>();
+ Invoke = () => 0;
+ }
+
+ public CommandLineApplication Parent { get; set; }
+ public virtual string Name { get; set; }
+ public string FullName { get; set; }
+ public string Syntax { get; set; }
+ public virtual string Description { get; set; }
+ public bool ShowInHelpText { get; set; } = true;
+ public string ExtendedHelpText { get; set; }
+ public readonly List<CommandOption> Options;
+ public CommandOption OptionHelp { get; private set; }
+ public CommandOption OptionVersion { get; private set; }
+ public readonly List<CommandArgument> Arguments;
+ public readonly List<string> RemainingArguments;
+ public bool IsShowingInformation { get; protected set; } // Is showing help or version?
+ public Func<int> Invoke { get; set; }
+ public Func<string> LongVersionGetter { get; set; }
+ public Func<string> ShortVersionGetter { get; set; }
+ public readonly List<CommandLineApplication> Commands;
+ public bool AllowArgumentSeparator { get; set; }
+ public TextWriter Out { get; set; } = Console.Out;
+ public TextWriter Error { get; set; } = Console.Error;
+
+ public IEnumerable<CommandOption> GetOptions()
+ {
+ var expr = Options.AsEnumerable();
+ var rootNode = this;
+ while (rootNode.Parent != null)
+ {
+ rootNode = rootNode.Parent;
+ expr = expr.Concat(rootNode.Options.Where(o => o.Inherited));
+ }
+
+ return expr;
+ }
+
+ public virtual CommandLineApplication Command(string name, Action<CommandLineApplication> configuration,
+ bool throwOnUnexpectedArg = true)
+ {
+ var command = new CommandLineApplication(throwOnUnexpectedArg) { Name = name, Parent = this };
+ Commands.Add(command);
+ configuration(command);
+ return command;
+ }
+
+ public virtual CommandOption Option(string template, string description, CommandOptionType optionType)
+ => Option(template, description, optionType, _ => { }, inherited: false);
+
+ public virtual CommandOption Option(string template, string description, CommandOptionType optionType, bool inherited)
+ => Option(template, description, optionType, _ => { }, inherited);
+
+ public virtual CommandOption Option(string template, string description, CommandOptionType optionType, Action<CommandOption> configuration)
+ => Option(template, description, optionType, configuration, inherited: false);
+
+ public virtual CommandOption Option(string template, string description, CommandOptionType optionType, Action<CommandOption> configuration, bool inherited)
+ {
+ var option = new CommandOption(template, optionType)
+ {
+ Description = description,
+ Inherited = inherited
+ };
+ Options.Add(option);
+ configuration(option);
+ return option;
+ }
+
+ public virtual CommandArgument Argument(string name, string description, bool multipleValues = false)
+ {
+ return Argument(name, description, _ => { }, multipleValues);
+ }
+
+ public virtual CommandArgument Argument(string name, string description, Action<CommandArgument> configuration, bool multipleValues = false)
+ {
+ var lastArg = Arguments.LastOrDefault();
+ if (lastArg != null && lastArg.MultipleValues)
+ {
+ var message = string.Format("The last argument '{0}' accepts multiple values. No more argument can be added.",
+ lastArg.Name);
+ throw new InvalidOperationException(message);
+ }
+
+ var argument = new CommandArgument { Name = name, Description = description, MultipleValues = multipleValues };
+ Arguments.Add(argument);
+ configuration(argument);
+ return argument;
+ }
+
+ public virtual void OnExecute(Func<int> invoke)
+ {
+ Invoke = invoke;
+ }
+
+ public virtual void OnExecute(Func<Task<int>> invoke)
+ {
+ Invoke = () => invoke().Result;
+ }
+ public virtual int Execute(params string[] args)
+ {
+ CommandLineApplication command = this;
+ CommandOption option = null;
+ IEnumerator<CommandArgument> arguments = null;
+
+ for (var index = 0; index < args.Length; index++)
+ {
+ var arg = args[index];
+ var processed = false;
+ if (!processed && option == null)
+ {
+ string[] longOption = null;
+ string[] shortOption = null;
+
+ if (arg.StartsWith("--"))
+ {
+ longOption = arg.Substring(2).Split(new[] { ':', '=' }, 2);
+ }
+ else if (arg.StartsWith("-"))
+ {
+ shortOption = arg.Substring(1).Split(new[] { ':', '=' }, 2);
+ }
+ else // Look for symbols (such as help option)
+ {
+ var symbolOption = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.SymbolName, arg, StringComparison.Ordinal));
+ if (symbolOption != null)
+ {
+ shortOption = new string[] { symbolOption.SymbolName, "" };
+ }
+ }
+ if (longOption != null)
+ {
+ processed = true;
+ var longOptionName = longOption[0];
+ option = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.LongName, longOptionName, StringComparison.Ordinal));
+
+ if (option == null)
+ {
+ if (string.IsNullOrEmpty(longOptionName) && !command._throwOnUnexpectedArg && AllowArgumentSeparator)
+ {
+ // skip over the '--' argument separator
+ index++;
+ }
+
+ HandleUnexpectedArg(command, args, index, argTypeName: "option");
+ break;
+ }
+
+ // If we find a help/version option, show information and stop parsing
+ if (command.OptionHelp == option)
+ {
+ command.ShowHelp();
+ return 0;
+ }
+ else if (command.OptionVersion == option)
+ {
+ command.ShowVersion();
+ return 0;
+ }
+
+ if (longOption.Length == 2)
+ {
+ if (!option.TryParse(longOption[1]))
+ {
+ command.ShowHint();
+ throw new CommandParsingException(command, $"Unexpected value '{longOption[1]}' for option '{option.LongName}'");
+ }
+ option = null;
+ }
+ else if (option.OptionType == CommandOptionType.NoValue)
+ {
+ // No value is needed for this option
+ option.TryParse(null);
+ option = null;
+ }
+ }
+ if (shortOption != null)
+ {
+ processed = true;
+ option = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.ShortName, shortOption[0], StringComparison.Ordinal));
+
+ // If not a short option, try symbol option
+ if (option == null)
+ {
+ option = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.SymbolName, shortOption[0], StringComparison.Ordinal));
+ }
+
+ if (option == null)
+ {
+ HandleUnexpectedArg(command, args, index, argTypeName: "option");
+ break;
+ }
+
+ // If we find a help/version option, show information and stop parsing
+ if (command.OptionHelp == option)
+ {
+ command.ShowHelp();
+ return 0;
+ }
+ else if (command.OptionVersion == option)
+ {
+ command.ShowVersion();
+ return 0;
+ }
+
+ if (shortOption.Length == 2)
+ {
+ if (!option.TryParse(shortOption[1]))
+ {
+ command.ShowHint();
+ throw new CommandParsingException(command, $"Unexpected value '{shortOption[1]}' for option '{option.LongName}'");
+ }
+ option = null;
+ }
+ else if (option.OptionType == CommandOptionType.NoValue)
+ {
+ // No value is needed for this option
+ option.TryParse(null);
+ option = null;
+ }
+ }
+ }
+
+ if (!processed && option != null)
+ {
+ processed = true;
+ if (!option.TryParse(arg))
+ {
+ command.ShowHint();
+ throw new CommandParsingException(command, $"Unexpected value '{arg}' for option '{option.LongName}'");
+ }
+ option = null;
+ }
+
+ if (!processed && arguments == null)
+ {
+ var currentCommand = command;
+ foreach (var subcommand in command.Commands)
+ {
+ if (string.Equals(subcommand.Name, arg, StringComparison.OrdinalIgnoreCase))
+ {
+ processed = true;
+ command = subcommand;
+ break;
+ }
+ }
+
+ // If we detect a subcommand
+ if (command != currentCommand)
+ {
+ processed = true;
+ }
+ }
+ if (!processed)
+ {
+ if (arguments == null)
+ {
+ arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator());
+ }
+ if (arguments.MoveNext())
+ {
+ processed = true;
+ arguments.Current.Values.Add(arg);
+ }
+ }
+ if (!processed)
+ {
+ HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
+ break;
+ }
+ }
+
+ if (option != null)
+ {
+ command.ShowHint();
+ throw new CommandParsingException(command, $"Missing value for option '{option.LongName}'");
+ }
+
+ return command.Invoke();
+ }
+
+ // Helper method that adds a help option
+ public virtual CommandOption HelpOption(string template)
+ {
+ // Help option is special because we stop parsing once we see it
+ // So we store it separately for further use
+ OptionHelp = Option(template, "Show help information", CommandOptionType.NoValue);
+
+ return OptionHelp;
+ }
+
+ public virtual CommandOption VersionOption(string template,
+ string shortFormVersion,
+ string longFormVersion = null)
+ {
+ if (longFormVersion == null)
+ {
+ return VersionOption(template, () => shortFormVersion);
+ }
+ else
+ {
+ return VersionOption(template, () => shortFormVersion, () => longFormVersion);
+ }
+ }
+
+ // Helper method that adds a version option
+ public virtual CommandOption VersionOption(string template,
+ Func<string> shortFormVersionGetter,
+ Func<string> longFormVersionGetter = null)
+ {
+ // Version option is special because we stop parsing once we see it
+ // So we store it separately for further use
+ OptionVersion = Option(template, "Show version information", CommandOptionType.NoValue);
+ ShortVersionGetter = shortFormVersionGetter;
+ LongVersionGetter = longFormVersionGetter ?? shortFormVersionGetter;
+
+ return OptionVersion;
+ }
+
+ // Show short hint that reminds users to use help option
+ public virtual void ShowHint()
+ {
+ if (OptionHelp != null)
+ {
+ Out.WriteLine(string.Format("Specify --{0} for a list of available options and commands.", OptionHelp.LongName));
+ }
+ }
+
+ // Show full help
+ public virtual void ShowHelp(string commandName = null)
+ {
+ for (var cmd = this; cmd != null; cmd = cmd.Parent)
+ {
+ cmd.IsShowingInformation = true;
+ }
+
+ Out.WriteLine(GetHelpText(commandName));
+ }
+
+ public virtual string GetHelpText(string commandName = null)
+ {
+ var headerBuilder = new StringBuilder("Usage:");
+ for (var cmd = this; cmd != null; cmd = cmd.Parent)
+ {
+ headerBuilder.Insert(6, string.Format(" {0}", cmd.Name));
+ }
+
+ CommandLineApplication target;
+
+ if (commandName == null || string.Equals(Name, commandName, StringComparison.OrdinalIgnoreCase))
+ {
+ target = this;
+ }
+ else
+ {
+ target = Commands.SingleOrDefault(cmd => string.Equals(cmd.Name, commandName, StringComparison.OrdinalIgnoreCase));
+
+ if (target != null)
+ {
+ headerBuilder.AppendFormat(" {0}", commandName);
+ }
+ else
+ {
+ // The command name is invalid so don't try to show help for something that doesn't exist
+ target = this;
+ }
+
+ }
+
+ var optionsBuilder = new StringBuilder();
+ var commandsBuilder = new StringBuilder();
+ var argumentsBuilder = new StringBuilder();
+
+ var arguments = target.Arguments.Where(a => a.ShowInHelpText).ToList();
+ if (arguments.Any())
+ {
+ headerBuilder.Append(" [arguments]");
+
+ argumentsBuilder.AppendLine();
+ argumentsBuilder.AppendLine("Arguments:");
+ var maxArgLen = arguments.Max(a => a.Name.Length);
+ var outputFormat = string.Format(" {{0, -{0}}}{{1}}", maxArgLen + 2);
+ foreach (var arg in arguments)
+ {
+ argumentsBuilder.AppendFormat(outputFormat, arg.Name, arg.Description);
+ argumentsBuilder.AppendLine();
+ }
+ }
+
+ var options = target.GetOptions().Where(o => o.ShowInHelpText).ToList();
+ if (options.Any())
+ {
+ headerBuilder.Append(" [options]");
+
+ optionsBuilder.AppendLine();
+ optionsBuilder.AppendLine("Options:");
+ var maxOptLen = options.Max(o => o.Template.Length);
+ var outputFormat = string.Format(" {{0, -{0}}}{{1}}", maxOptLen + 2);
+ foreach (var opt in options)
+ {
+ optionsBuilder.AppendFormat(outputFormat, opt.Template, opt.Description);
+ optionsBuilder.AppendLine();
+ }
+ }
+
+ var commands = target.Commands.Where(c => c.ShowInHelpText).ToList();
+ if (commands.Any())
+ {
+ headerBuilder.Append(" [command]");
+
+ commandsBuilder.AppendLine();
+ commandsBuilder.AppendLine("Commands:");
+ var maxCmdLen = commands.Max(c => c.Name.Length);
+ var outputFormat = string.Format(" {{0, -{0}}}{{1}}", maxCmdLen + 2);
+ foreach (var cmd in commands.OrderBy(c => c.Name))
+ {
+ commandsBuilder.AppendFormat(outputFormat, cmd.Name, cmd.Description);
+ commandsBuilder.AppendLine();
+ }
+
+ if (OptionHelp != null)
+ {
+ commandsBuilder.AppendLine();
+ commandsBuilder.AppendFormat($"Use \"{target.Name} [command] --{OptionHelp.LongName}\" for more information about a command.");
+ commandsBuilder.AppendLine();
+ }
+ }
+
+ if (target.AllowArgumentSeparator)
+ {
+ headerBuilder.Append(" [[--] <arg>...]");
+ }
+
+ headerBuilder.AppendLine();
+
+ var nameAndVersion = new StringBuilder();
+ nameAndVersion.AppendLine(GetFullNameAndVersion());
+ nameAndVersion.AppendLine();
+
+ return nameAndVersion.ToString()
+ + headerBuilder.ToString()
+ + argumentsBuilder.ToString()
+ + optionsBuilder.ToString()
+ + commandsBuilder.ToString()
+ + (string.IsNullOrEmpty(target.ExtendedHelpText) ? "" : Environment.NewLine + target.ExtendedHelpText);
+ }
+
+ public virtual void ShowVersion()
+ {
+ for (var cmd = this; cmd != null; cmd = cmd.Parent)
+ {
+ cmd.IsShowingInformation = true;
+ }
+
+ Out.WriteLine(FullName);
+ Out.WriteLine(LongVersionGetter());
+ }
+
+ public virtual string GetFullNameAndVersion()
+ {
+ return ShortVersionGetter == null ? FullName : string.Format("{0} {1}", FullName, ShortVersionGetter());
+ }
+
+ public virtual void ShowRootCommandFullNameAndVersion()
+ {
+ var rootCmd = this;
+ while (rootCmd.Parent != null)
+ {
+ rootCmd = rootCmd.Parent;
+ }
+
+ Out.WriteLine(rootCmd.GetFullNameAndVersion());
+ Out.WriteLine();
+ }
+
+ private void HandleUnexpectedArg(CommandLineApplication command, string[] args, int index, string argTypeName)
+ {
+ if (command._throwOnUnexpectedArg)
+ {
+ command.ShowHint();
+ throw new CommandParsingException(command, $"Unrecognized {argTypeName} '{args[index]}'");
+ }
+ else
+ {
+ // All remaining arguments are stored for further use
+ command.RemainingArguments.AddRange(new ArraySegment<string>(args, index, args.Length - index));
+ }
+ }
+
+ private class CommandArgumentEnumerator : IEnumerator<CommandArgument>
+ {
+ private readonly IEnumerator<CommandArgument> _enumerator;
+
+ public CommandArgumentEnumerator(IEnumerator<CommandArgument> enumerator)
+ {
+ _enumerator = enumerator;
+ }
+
+ public CommandArgument Current
+ {
+ get
+ {
+ return _enumerator.Current;
+ }
+ }
+
+ object IEnumerator.Current
+ {
+ get
+ {
+ return Current;
+ }
+ }
+
+ public void Dispose()
+ {
+ _enumerator.Dispose();
+ }
+
+ public bool MoveNext()
+ {
+ if (Current == null || !Current.MultipleValues)
+ {
+ return _enumerator.MoveNext();
+ }
+
+ // If current argument allows multiple values, we don't move forward and
+ // all later values will be added to current CommandArgument.Values
+ return true;
+ }
+
+ public void Reset()
+ {
+ _enumerator.Reset();
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/CommandLine/CommandOption.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/CommandLine/CommandOption.cs b/src/tools/lucene-cli/CommandLine/CommandOption.cs
new file mode 100644
index 0000000..16c1025
--- /dev/null
+++ b/src/tools/lucene-cli/CommandLine/CommandOption.cs
@@ -0,0 +1,112 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Lucene.Net.Cli.CommandLine
+{
+ public class CommandOption
+ {
+ public CommandOption(string template, CommandOptionType optionType)
+ {
+ Template = template;
+ OptionType = optionType;
+ Values = new List<string>();
+
+ foreach (var part in Template.Split(new[] { ' ', '|' }, StringSplitOptions.RemoveEmptyEntries))
+ {
+ if (part.StartsWith("--"))
+ {
+ LongName = part.Substring(2);
+ }
+ else if (part.StartsWith("-"))
+ {
+ var optName = part.Substring(1);
+
+ // If there is only one char and it is not an English letter, it is a symbol option (e.g. "-?")
+ if (optName.Length == 1 && !IsEnglishLetter(optName[0]))
+ {
+ SymbolName = optName;
+ }
+ else
+ {
+ ShortName = optName;
+ }
+ }
+ else if (part.StartsWith("<") && part.EndsWith(">"))
+ {
+ ValueName = part.Substring(1, part.Length - 2);
+ }
+ else
+ {
+ throw new ArgumentException($"Invalid template pattern '{template}'", nameof(template));
+ }
+ }
+
+ if (string.IsNullOrEmpty(LongName) && string.IsNullOrEmpty(ShortName) && string.IsNullOrEmpty(SymbolName))
+ {
+ throw new ArgumentException($"Invalid template pattern '{template}'", nameof(template));
+ }
+ }
+
+ /// <summary>
+ /// An ID that can be used to locate this option.
+ /// </summary>
+ public string UniqueId { get; set; }
+ public string Template { get; set; }
+ public string ShortName { get; set; }
+ public string LongName { get; set; }
+ public string SymbolName { get; set; }
+ public string ValueName { get; set; }
+ public string Description { get; set; }
+ public List<string> Values { get; private set; }
+ public CommandOptionType OptionType { get; private set; }
+ public bool ShowInHelpText { get; set; } = true;
+ public bool Inherited { get; set; }
+
+ public bool TryParse(string value)
+ {
+ switch (OptionType)
+ {
+ case CommandOptionType.MultipleValue:
+ Values.Add(value);
+ break;
+ case CommandOptionType.SingleValue:
+ if (Values.Any())
+ {
+ return false;
+ }
+ Values.Add(value);
+ break;
+ case CommandOptionType.NoValue:
+ if (value != null)
+ {
+ return false;
+ }
+ // Add a value to indicate that this option was specified
+ Values.Add("on");
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ public bool HasValue()
+ {
+ return Values.Any();
+ }
+
+ public string Value()
+ {
+ return HasValue() ? Values[0] : null;
+ }
+
+ private bool IsEnglishLetter(char c)
+ {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/CommandLine/CommandOptionType.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/CommandLine/CommandOptionType.cs b/src/tools/lucene-cli/CommandLine/CommandOptionType.cs
new file mode 100644
index 0000000..ef541e4
--- /dev/null
+++ b/src/tools/lucene-cli/CommandLine/CommandOptionType.cs
@@ -0,0 +1,12 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Lucene.Net.Cli.CommandLine
+{
+ public enum CommandOptionType
+ {
+ MultipleValue,
+ SingleValue,
+ NoValue
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/CommandLine/CommandParsingException.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/CommandLine/CommandParsingException.cs b/src/tools/lucene-cli/CommandLine/CommandParsingException.cs
new file mode 100644
index 0000000..bd2446a
--- /dev/null
+++ b/src/tools/lucene-cli/CommandLine/CommandParsingException.cs
@@ -0,0 +1,18 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+
+namespace Lucene.Net.Cli.CommandLine
+{
+ public class CommandParsingException : Exception
+ {
+ public CommandParsingException(CommandLineApplication command, string message)
+ : base(message)
+ {
+ Command = command;
+ }
+
+ public CommandLineApplication Command { get; }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/CommandLineOptions.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/CommandLineOptions.cs b/src/tools/lucene-cli/CommandLineOptions.cs
new file mode 100644
index 0000000..93c7455
--- /dev/null
+++ b/src/tools/lucene-cli/CommandLineOptions.cs
@@ -0,0 +1,74 @@
+using System;
+
+namespace Lucene.Net.Cli
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class CommandLineOptions
+ {
+ public static int Parse(string[] args)
+ {
+ var options = new CommandLineOptions();
+
+ var cmd = new RootCommand.Configuration(options);
+
+ try
+ {
+ return cmd.Execute(args);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(Resources.Strings.GeneralExceptionMessage + Environment.NewLine + ex.ToString());
+ cmd.ShowHint();
+ return 1;
+ }
+ }
+
+ //public static readonly string VERBOSE_OPTION_VALUE_NAME = "verbose";
+ //public static readonly string DIRECTORY_TYPE_VALUE_NAME = "directoryType";
+ //public static readonly string INDEX_DIRECTORY_ARGUMENT_ID = "indexDirectory";
+
+ //public CommandOption VerboseOption = new CommandOption("-v|--verbose", CommandOptionType.NoValue)
+ //{
+ // Description = Resources.Strings.VerboseOptionDescription,
+ // ValueName = VERBOSE_OPTION_VALUE_NAME
+ //};
+ //public CommandArgument IndexDirectoryArgument = new CommandArgument()
+ //{
+ // Name = "[<INDEX-DIRECTORY>]",
+ // Description = Resources.Strings.IndexDirectoryArgumentDescription,
+ // Id = INDEX_DIRECTORY_ARGUMENT_ID
+ //};
+ //public string IndexDirectory
+ //{
+ // get
+ // {
+ // // Return current directory if index directory not supplied.
+ // return string.IsNullOrWhiteSpace(IndexDirectoryArgument.Value) ?
+ // System.AppContext.BaseDirectory :
+ // IndexDirectoryArgument.Value;
+ // }
+ //}
+
+ //public CommandOption DirectoryTypeOption = new CommandOption("-dir|-dir-impl|--dir-impl|--directory-type", CommandOptionType.SingleValue)
+ //{
+ // Description = Resources.Strings.DirectoryTypeOptionDescription,
+ // ValueName = DIRECTORY_TYPE_VALUE_NAME
+ //};
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/ConfigurationBase.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/ConfigurationBase.cs b/src/tools/lucene-cli/ConfigurationBase.cs
new file mode 100644
index 0000000..28e8de5
--- /dev/null
+++ b/src/tools/lucene-cli/ConfigurationBase.cs
@@ -0,0 +1,130 @@
+using Lucene.Net.Cli.CommandLine;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace Lucene.Net.Cli
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public abstract class ConfigurationBase : CommandLineApplication
+ {
+ private static Assembly thisAssembly = typeof(ConfigurationBase).GetTypeInfo().Assembly;
+ protected static string HELP_VALUE_NAME = "help";
+
+ protected ConfigurationBase()
+ //: base(throwOnUnexpectedArg: false)
+ {
+ var help = this.HelpOption("-?|-h|--help");
+ help.UniqueId = HELP_VALUE_NAME;
+ help.ShowInHelpText = false;
+
+ this.ShortVersionGetter = () =>
+ {
+ return "Lucene.Net Command Line Utility, Version: " + thisAssembly
+ .GetCustomAttribute<AssemblyInformationalVersionAttribute>()
+ .InformationalVersion;
+ };
+
+ this.LongVersionGetter = () =>
+ {
+ return ShortVersionGetter();
+ };
+ }
+
+ public override void OnExecute(Func<int> invoke)
+ {
+ base.OnExecute(() =>
+ {
+ if (this.GetOptionByUniqueId(HELP_VALUE_NAME).HasValue())
+ {
+ this.ShowHelp();
+ return 1;
+ }
+ try
+ {
+ return invoke();
+ }
+ catch (ArgumentException e)
+ {
+ // Rather than writing to console, the
+ // utilities are now throwing ArgumentException
+ // if the args cannot be parsed.
+ this.ShowHint();
+ this.ShowHelp();
+ return 1;
+ }
+ });
+ }
+
+ public Action<string[]> Main { get; set; }
+
+ public CommandOption GetOptionByUniqueId(string uniqueId)
+ {
+ return this.Options.FirstOrDefault(o => o.UniqueId == uniqueId);
+ }
+
+ public CommandOption GetOption<T>()
+ {
+ return this.Options.FirstOrDefault(o => typeof(T).IsAssignableFrom(o.GetType()));
+ }
+
+ public CommandArgument GetArgument<T>()
+ {
+ return this.Arguments.FirstOrDefault(o => typeof(T).IsAssignableFrom(o.GetType()));
+ }
+
+ /// <summary>
+ /// Gets the resource with a specific name. It is automatically
+ /// prefixed by the current command name.
+ /// </summary>
+ /// <param name="resourceName"></param>
+ /// <returns></returns>
+ protected string FromResource(string resourceName)
+ {
+ return Resources.Strings.ResourceManager.GetString(this.GetType().DeclaringType.Name + resourceName);
+ }
+
+ public void ShowNotEnoughArguments(int minimum)
+ {
+ Out.WriteLine(Resources.Strings.NotEnoughArguments, minimum);
+ }
+
+ public bool ValidateArguments(int minimum)
+ {
+ var args = GetNonNullArguments();
+
+ if (args.Length < minimum)
+ {
+ this.ShowNotEnoughArguments(minimum);
+ this.ShowHelp();
+ return false;
+ }
+ return true;
+ }
+
+ public string[] GetNonNullArguments()
+ {
+ return this.Arguments
+ .Where(a => !string.IsNullOrWhiteSpace(a.Value))
+ .SelectMany(a => a.MultipleValues ? a.Values : new List<string> { a.Value })
+ .ToArray();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/ICommand.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/ICommand.cs b/src/tools/lucene-cli/ICommand.cs
new file mode 100644
index 0000000..b84e8d6
--- /dev/null
+++ b/src/tools/lucene-cli/ICommand.cs
@@ -0,0 +1,27 @@
+namespace Lucene.Net.Cli
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// A console command.
+ /// </summary>
+ public interface ICommand
+ {
+ int Run(ConfigurationBase cmd);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/Program.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/Program.cs b/src/tools/lucene-cli/Program.cs
new file mode 100644
index 0000000..9ef9869
--- /dev/null
+++ b/src/tools/lucene-cli/Program.cs
@@ -0,0 +1,35 @@
+using System;
+
+namespace Lucene.Net.Cli
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class Program
+ {
+ public static int Main(string[] args)
+ {
+ int result = CommandLineOptions.Parse(args);
+
+#if DEBUG
+ Console.ReadKey();
+#endif
+
+ return result;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/Properties/AssemblyInfo.cs b/src/tools/lucene-cli/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..07a71d6
--- /dev/null
+++ b/src/tools/lucene-cli/Properties/AssemblyInfo.cs
@@ -0,0 +1,37 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("lucene-cli")]
+[assembly: AssemblyDescription(
+ "Lucene.Net maintenance utilities and demos.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyDefaultAlias("Lucene.Net.Cli")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d5f3414e-e743-4dca-a50a-da3278a2ba2b")]
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9e389540/src/tools/lucene-cli/Properties/launchSettings.json
----------------------------------------------------------------------
diff --git a/src/tools/lucene-cli/Properties/launchSettings.json b/src/tools/lucene-cli/Properties/launchSettings.json
new file mode 100644
index 0000000..1c0ef57
--- /dev/null
+++ b/src/tools/lucene-cli/Properties/launchSettings.json
@@ -0,0 +1,7 @@
+{
+ "profiles": {
+ "lucene-cli": {
+ "commandName": "Project"
+ }
+ }
+}
\ No newline at end of file