Example #1
0
        public static bool TryParseAsEnumFlags <TEnum>(
            IEnumerable <string> values,
            string optionName,
            out TEnum result,
            TEnum?defaultValue           = null,
            OptionValueProvider provider = null) where TEnum : struct
        {
            result = (TEnum)(object)0;

            if (values?.Any() != true)
            {
                if (defaultValue != null)
                {
                    result = (TEnum)(object)defaultValue;
                }

                return(true);
            }

            int flags = 0;

            foreach (string value in values)
            {
                if (!TryParseAsEnum(value, optionName, out TEnum result2, provider: provider))
                {
                    return(false);
                }

                flags |= (int)(object)result2;
            }

            result = (TEnum)(object)flags;

            return(true);
        }
Example #2
0
        public static bool TryParseAsEnumValues <TEnum>(
            IEnumerable <string> values,
            string optionName,
            out ImmutableArray <TEnum> result,
            ImmutableArray <TEnum> defaultValue = default,
            OptionValueProvider provider        = null) where TEnum : struct
        {
            if (values?.Any() != true)
            {
                result = (defaultValue.IsDefault) ? ImmutableArray <TEnum> .Empty : defaultValue;

                return(true);
            }

            ImmutableArray <TEnum> .Builder builder = ImmutableArray.CreateBuilder <TEnum>();

            foreach (string value in values)
            {
                if (!TryParseAsEnum(value, optionName, out TEnum result2, provider: provider))
                {
                    return(false);
                }

                builder.Add(result2);
            }

            result = builder.ToImmutableArray();

            return(true);
        }
        public static ImmutableArray <OptionValueList> GetOptionValues(
            IEnumerable <CommandOption> options,
            IEnumerable <OptionValueProvider> providers,
            Filter?filter = null)
        {
            providers = OptionValueProvider.GetProviders(options, providers).ToImmutableArray();

            IEnumerable <OptionValue> allValues = providers.SelectMany(p => p.Values.Where(v => !v.Hidden));

            ImmutableArray <OptionValueList> .Builder builder = ImmutableArray.CreateBuilder <OptionValueList>();

            (int width1, int width2) = CalculateOptionValuesWidths(allValues);

            foreach (OptionValueProvider provider in providers)
            {
                IEnumerable <OptionValue>        values     = provider.Values.Where(f => !f.Hidden);
                ImmutableArray <OptionValueItem> valueItems = GetOptionValueItems(values, width1, width2);

                builder.Add(new OptionValueList(provider.Name, valueItems));
            }

            return((filter != null)
                ? FilterOptionValues(builder, filter)
                : builder.ToImmutableArray());
        }
Example #4
0
        public static bool TryParseAsEnum <TEnum>(
            string value,
            string optionName,
            out TEnum result,
            TEnum?defaultValue           = null,
            OptionValueProvider provider = null) where TEnum : struct
        {
            if (!TryParseAsEnum(value, out result, defaultValue, provider))
            {
                WriteParseError(value, optionName, provider?.GetHelpText() ?? OptionValue.GetDefaultHelpText <TEnum>());
                return(false);
            }

            return(true);
        }
Example #5
0
        public override void WriteOptionDescription(CommandOption option)
        {
            _writer.WriteString(option.Description);

            OptionValueProvider provider = null !;

            if (TryGetProvider())
            {
                if (!string.IsNullOrEmpty(option.Description))
                {
                    _writer.WriteString(" ");
                }

                _writer.WriteString((provider.Values.Length == 1) ? "Allowed value is " : "Allowed values are ");
                _writer.WriteString(OptionValueProviders.GetHelpText(provider, f => !f.Hidden));
                _writer.WriteString(".");
            }

            if (!string.IsNullOrEmpty(option.Description) ||
                provider != null)
            {
                _writer.WriteLine();
                _writer.WriteLine();
            }

            bool TryGetProvider()
            {
                if (option.ValueProviderName != null)
                {
                    return(OptionValueProviders.ProvidersByName.TryGetValue(option.ValueProviderName, out provider));
                }

                if (option.MetaValue != null &&
                    OptionValueProviders.ProvidersByName.TryGetValue(option.MetaValue, out provider))
                {
                    return(true);
                }

                Match match = _metaValueRegex.Match(option.Description);

                return(match.Success &&
                       OptionValueProviders.ProvidersByName.TryGetValue(match.Value, out provider));
            }
        }
Example #6
0
 public static bool TryParse(
     IEnumerable <string> values,
     string optionName,
     OptionValueProvider provider,
     out Filter?filter,
     bool allowNull = false,
     OptionValueProvider?namePartProvider  = null,
     FileNamePart defaultNamePart          = FileNamePart.Name,
     PatternOptions includedPatternOptions = PatternOptions.None)
 {
     return(TryParse(
                values: values,
                optionName: optionName,
                provider: provider,
                filter: out filter,
                namePart: out _,
                allowNull: allowNull,
                namePartProvider: namePartProvider,
                defaultNamePart: defaultNamePart,
                includedPatternOptions: includedPatternOptions));
 }
Example #7
0
        public static bool TryParseAsEnum <TEnum>(
            string value,
            out TEnum result,
            TEnum?defaultValue           = null,
            OptionValueProvider provider = default) where TEnum : struct
        {
            if (value == null &&
                defaultValue != null)
            {
                result = defaultValue.Value;
                return(true);
            }

            if (provider != null)
            {
                return(provider.TryParseEnum(value, out result));
            }
            else
            {
                return(Enum.TryParse(value?.Replace("-", ""), ignoreCase: true, out result));
            }
        }
Example #8
0
        private static void WriteParseError(string value, string optionName, OptionValueProvider provider)
        {
            string helpText = provider.GetHelpText();

            WriteParseError(value, optionName, helpText);
        }
Example #9
0
        internal static bool TryParseRegexOptions(
            IEnumerable <string> options,
            string optionsParameterName,
            out RegexOptions regexOptions,
            out PatternOptions patternOptions,
            PatternOptions includedPatternOptions = PatternOptions.None,
            OptionValueProvider provider          = null)
        {
            regexOptions = RegexOptions.None;

            if (!TryParseAsEnumFlags(options, optionsParameterName, out patternOptions, provider: provider ?? OptionValueProviders.PatternOptionsProvider))
            {
                return(false);
            }

            Debug.Assert((patternOptions & (PatternOptions.CaseSensitive | PatternOptions.IgnoreCase)) != (PatternOptions.CaseSensitive | PatternOptions.IgnoreCase));

            if ((patternOptions & PatternOptions.CaseSensitive) != 0)
            {
                includedPatternOptions &= ~PatternOptions.IgnoreCase;
            }
            else if ((patternOptions & PatternOptions.IgnoreCase) != 0)
            {
                includedPatternOptions &= ~PatternOptions.CaseSensitive;
            }

            patternOptions |= includedPatternOptions;

            if ((patternOptions & PatternOptions.Compiled) != 0)
            {
                regexOptions |= RegexOptions.Compiled;
            }

            if ((patternOptions & PatternOptions.CultureInvariant) != 0)
            {
                regexOptions |= RegexOptions.CultureInvariant;
            }

            if ((patternOptions & PatternOptions.ECMAScript) != 0)
            {
                regexOptions |= RegexOptions.ECMAScript;
            }

            if ((patternOptions & PatternOptions.ExplicitCapture) != 0)
            {
                regexOptions |= RegexOptions.ExplicitCapture;
            }

            if ((patternOptions & PatternOptions.IgnoreCase) != 0)
            {
                regexOptions |= RegexOptions.IgnoreCase;
            }

            if ((patternOptions & PatternOptions.IgnorePatternWhitespace) != 0)
            {
                regexOptions |= RegexOptions.IgnorePatternWhitespace;
            }

            if ((patternOptions & PatternOptions.Multiline) != 0)
            {
                regexOptions |= RegexOptions.Multiline;
            }

            if ((patternOptions & PatternOptions.RightToLeft) != 0)
            {
                regexOptions |= RegexOptions.RightToLeft;
            }

            if ((patternOptions & PatternOptions.Singleline) != 0)
            {
                regexOptions |= RegexOptions.Singleline;
            }

            return(true);
        }
Example #10
0
        public static bool TryParseDisplay(
            IEnumerable <string> values,
            string optionName,
            out ContentDisplayStyle?contentDisplayStyle,
            out PathDisplayStyle?pathDisplayStyle,
            out LineDisplayOptions lineDisplayOptions,
            out DisplayParts displayParts,
            out ImmutableArray <FileProperty> fileProperties,
            out string indent,
            out string separator,
            OptionValueProvider contentDisplayStyleProvider = null,
            OptionValueProvider pathDisplayStyleProvider    = null)
        {
            contentDisplayStyle = null;
            pathDisplayStyle    = null;
            lineDisplayOptions  = LineDisplayOptions.None;
            displayParts        = DisplayParts.None;
            fileProperties      = ImmutableArray <FileProperty> .Empty;
            indent    = null;
            separator = null;

            ImmutableArray <FileProperty> .Builder builder = null;

            foreach (string value in values)
            {
                int index = value.IndexOf('=');

                if (index >= 0)
                {
                    string key    = value.Substring(0, index);
                    string value2 = value.Substring(index + 1);

                    if (OptionValues.Display_Content.IsKeyOrShortKey(key))
                    {
                        if (!TryParseAsEnum(value2, optionName, out ContentDisplayStyle contentDisplayStyle2, provider: contentDisplayStyleProvider))
                        {
                            return(false);
                        }

                        contentDisplayStyle = contentDisplayStyle2;
                    }
                    else if (OptionValues.Display_Path.IsKeyOrShortKey(key))
                    {
                        if (!TryParseAsEnum(value2, optionName, out PathDisplayStyle pathDisplayStyle2, provider: pathDisplayStyleProvider))
                        {
                            return(false);
                        }

                        pathDisplayStyle = pathDisplayStyle2;
                    }
                    else if (OptionValues.Display_Indent.IsKeyOrShortKey(key))
                    {
                        indent = value2;
                    }
                    else if (OptionValues.Display_Separator.IsKeyOrShortKey(key))
                    {
                        separator = value2;
                    }
                    else
                    {
                        ThrowException(value);
                    }
                }
                else if (OptionValues.Display_Summary.IsValueOrShortValue(value))
                {
                    displayParts |= DisplayParts.Summary;
                }
                else if (OptionValues.Display_Count.IsValueOrShortValue(value))
                {
                    displayParts |= DisplayParts.Count;
                }
                else if (OptionValues.Display_CreationTime.IsValueOrShortValue(value))
                {
                    (builder ?? (builder = ImmutableArray.CreateBuilder <FileProperty>())).Add(FileProperty.CreationTime);
                }
                else if (OptionValues.Display_ModifiedTime.IsValueOrShortValue(value))
                {
                    (builder ?? (builder = ImmutableArray.CreateBuilder <FileProperty>())).Add(FileProperty.ModifiedTime);
                }
                else if (OptionValues.Display_Size.IsValueOrShortValue(value))
                {
                    (builder ?? (builder = ImmutableArray.CreateBuilder <FileProperty>())).Add(FileProperty.Size);
                }
                else if (OptionValues.Display_LineNumber.IsValueOrShortValue(value))
                {
                    lineDisplayOptions |= LineDisplayOptions.IncludeLineNumber;
                }
                else if (OptionValues.Display_TrimLine.IsValueOrShortValue(value))
                {
                    lineDisplayOptions |= LineDisplayOptions.TrimLine;
                }
                else if (OptionValues.Display_TrimLine.IsValueOrShortValue(value))
                {
                    lineDisplayOptions |= LineDisplayOptions.TrimLine;
                }
                else if (OptionValues.Display_TrimLine.IsValueOrShortValue(value))
                {
                    lineDisplayOptions |= LineDisplayOptions.TrimLine;
                }
                else
                {
                    ThrowException(value);
                }
            }

            if (builder != null)
            {
                fileProperties = builder.ToImmutableArray();
            }

            return(true);

            void ThrowException(string value)
            {
                string helpText = OptionValueProviders.DisplayProvider.GetHelpText();

                throw new ArgumentException($"Option '{OptionNames.GetHelpText(optionName)}' has invalid value '{value}'. Allowed values: {helpText}.", nameof(values));
            }
        }
Example #11
0
        public static bool TryParse(
            IEnumerable <string> values,
            string optionName,
            OptionValueProvider provider,
            out Filter?filter,
            out FileNamePart namePart,
            bool allowNull = false,
            OptionValueProvider?namePartProvider  = null,
            FileNamePart defaultNamePart          = FileNamePart.Name,
            PatternOptions includedPatternOptions = PatternOptions.None)
        {
            filter   = null;
            namePart = defaultNamePart;

            string?pattern = values.FirstOrDefault();

            if (pattern == null)
            {
                if (allowNull)
                {
                    return(true);
                }
                else
                {
                    throw new InvalidOperationException($"Option '{OptionNames.GetHelpText(optionName)}' is required.");
                }
            }

            TimeSpan            matchTimeout = Regex.InfiniteMatchTimeout;
            string?             groupName    = null;
            string?             separator    = null;
            Func <string, bool>?predicate    = null;

            List <string>?options = null;

            foreach (string option in values.Skip(1))
            {
                int index = option.IndexOfAny(_equalsOrLessThanOrGreaterThanChars);

                if (index != -1)
                {
                    string key = option.Substring(0, index);

                    if (!provider.ContainsKeyOrShortKey(key))
                    {
                        WriteOptionError(option, optionName, provider);
                        return(false);
                    }

                    string value = option.Substring(index + 1);

                    if (OptionValues.Group.IsKeyOrShortKey(key))
                    {
                        groupName = value;
                        continue;
                    }
                    else if (OptionValues.ListSeparator.IsKeyOrShortKey(key))
                    {
                        separator = value;
                        continue;
                    }
                    else if (OptionValues.Part.IsKeyOrShortKey(key))
                    {
                        if (!TryParseAsEnum(
                                value,
                                out namePart,
                                provider: namePartProvider ?? OptionValueProviders.NamePartKindProvider))
                        {
                            WriteOptionValueError(
                                value,
                                OptionValues.Part,
                                namePartProvider ?? OptionValueProviders.NamePartKindProvider);
                            return(false);
                        }

                        continue;
                    }
                    else if (OptionValues.Timeout.IsKeyOrShortKey(key))
                    {
                        if (!TryParseMatchTimeout(value, out matchTimeout))
                        {
                            WriteOptionValueError(value, OptionValues.Timeout);
                            return(false);
                        }

                        continue;
                    }
                }

                if (Expression.TryParse(option, out Expression? expression))
                {
                    if (OptionValues.Length.IsKeyOrShortKey(expression.Identifier) &&
                        provider.ContainsKeyOrShortKey(expression.Identifier))
                    {
                        try
                        {
                            predicate = PredicateHelpers.GetLengthPredicate(expression);
                            continue;
                        }
                        catch (ArgumentException)
                        {
                            WriteOptionValueError(
                                expression.Value,
                                OptionValues.Length,
                                HelpProvider.GetExpressionsText("  ", includeDate: false));
                            return(false);
                        }
                    }
                    else
                    {
                        WriteOptionError(option, optionName, provider);
                        return(false);
                    }
                }

                (options ??= new List <string>()).Add(option);
            }

            if (!TryParseRegexOptions(
                    options,
                    optionName,
                    out RegexOptions regexOptions,
                    out PatternOptions patternOptions,
                    includedPatternOptions,
                    provider))
            {
                return(false);
            }

            switch (patternOptions & (PatternOptions.WholeWord | PatternOptions.WholeLine))
            {
            case PatternOptions.None:
            case PatternOptions.WholeWord:
            case PatternOptions.WholeLine:
            {
                break;
            }

            default:
            {
                string helpValue = OptionValueProviders.PatternOptionsProvider
                                   .GetValue(nameof(PatternOptions.WholeWord)).HelpValue;

                string helpValue2 = OptionValueProviders.PatternOptionsProvider
                                    .GetValue(nameof(PatternOptions.WholeLine)).HelpValue;

                WriteError($"Values '{helpValue}' and '{helpValue2}' cannot be combined.");

                return(false);
            }
            }

            if ((patternOptions & PatternOptions.FromFile) != 0 &&
                !FileSystemHelpers.TryReadAllText(pattern, out pattern, ex => WriteError(ex)))
            {
                return(false);
            }

            pattern = BuildPattern(pattern, patternOptions, separator);

            if (pattern.Length == 0)
            {
                throw new InvalidOperationException(
                          $"Option '{OptionNames.GetHelpText(optionName)}' is invalid: pattern cannot be empty.");
            }

            Regex?regex = null;

            try
            {
                regex = new Regex(pattern, regexOptions, matchTimeout);
            }
            catch (ArgumentException ex)
            {
                WriteError(ex, $"Could not parse regular expression: {ex.Message}");
                return(false);
            }

            int groupIndex = -1;

            if (groupName != null)
            {
                groupIndex = regex.GroupNumberFromName(groupName);
                if (groupIndex == -1)
                {
                    string message = $"Group '{groupName}' does not exist.";

                    string[] groupNames = regex.GetGroupNames();

                    if (groupNames.Length > 1)
                    {
                        message += " Existing group names: "
                                   + $"{TextHelpers.Join(", ", " and ", groupNames.Where(f => f != "0"))}.";
                    }

                    WriteError(message);
                    return(false);
                }
            }

            filter = new Filter(
                regex,
                isNegative: (patternOptions & PatternOptions.Negative) != 0,
                groupNumber: groupIndex,
                predicate: predicate);

            return(true);
        }
Example #12
0
        private static void Main(params string[] args)
        {
            IEnumerable <Command> commands = CommandLoader.LoadCommands(typeof(CommandLoader).Assembly)
                                             .Select(c => c.WithOptions(c.Options.OrderBy(f => f, CommandOptionComparer.Name)))
                                             .OrderBy(c => c.Name, StringComparer.InvariantCulture);

            var application = new CommandLineApplication(
                "orang",
                "Search, replace, rename and delete files and its content using the power of .NET regular expressions.",
                commands.OrderBy(f => f.Name, StringComparer.InvariantCulture));

            string?destinationDirectoryPath = null;
            string?dataDirectoryPath        = null;

            if (Debugger.IsAttached)
            {
                destinationDirectoryPath = (args.Length > 0) ? args[0] : @"..\..\..\..\..\docs\cli";
                dataDirectoryPath        = @"..\..\..\data";
            }
            else
            {
                destinationDirectoryPath = args[0];
                dataDirectoryPath        = @"..\src\DocumentationGenerator\data";
            }

            string readmeFilePath = Path.GetFullPath(Path.Combine(destinationDirectoryPath, "README.md"));

            var settings = new MarkdownWriterSettings(
                MarkdownFormat.Default.WithTableOptions(
                    MarkdownFormat.Default.TableOptions | TableOptions.FormatHeaderAndContent));

            using (var sw = new StreamWriter(readmeFilePath, append: false, Encoding.UTF8))
                using (MarkdownWriter mw = MarkdownWriter.Create(sw, settings))
                {
                    mw.WriteStartHeading(1);
                    mw.WriteString("Orang Command-Line Interface");
                    mw.WriteRaw(" <img align=\"left\" src=\"../../images/icon48.png\">");
                    mw.WriteEndHeading();
                    mw.WriteString(application.Description);
                    mw.WriteLine();

                    mw.WriteHeading2("Commands");

                    Table(
                        TableRow("Command", "Description"),
                        application
                        .Commands
                        .Select(f => TableRow(Link(f.Name, f.Name + "-command.md"), f.Description)))
                    .WriteTo(mw);

                    mw.WriteLine();

                    string readmeLinksFilePath = Path.Combine(dataDirectoryPath, "readme_bottom.md");

                    if (File.Exists(readmeLinksFilePath))
                    {
                        mw.WriteRaw(File.ReadAllText(readmeLinksFilePath));
                    }

                    WriteFootNote(mw);

                    Console.WriteLine(readmeFilePath);
                }

            string valuesFilePath = Path.GetFullPath(Path.Combine(destinationDirectoryPath, "OptionValues.md"));

            ImmutableArray <OptionValueProvider> providers = OptionValueProvider.GetProviders(
                commands.SelectMany(f => f.Options),
                OptionValueProviders.ProvidersByName.Select(f => f.Value))
                                                             .ToImmutableArray();

            MDocument document = Document(
                Heading1("List of Option Values"),
                BulletList(providers.Select(f => Link(
                                                f.Name,
                                                MarkdownHelpers.CreateGitHubHeadingLink(f.Name)))),
                providers.Select(provider =>
            {
                return(new MObject[]
                {
                    Heading2(provider.Name),
                    Table(
                        TableRow("Value", " ", "Description"),
                        provider.Values.Select(f => CreateTableRow(f, providers)))
                });
            }));

            document.Add(
                Heading2("Expression Syntax"),
                Table(
                    TableRow("Expression", "Description"),
                    HelpProvider.GetExpressionItems(includeDate: true)
                    .Select(f => TableRow(InlineCode(f.expression), f.description))));

            AddFootnote(document);

            var markdownFormat = new MarkdownFormat(
                tableOptions: MarkdownFormat.Default.TableOptions | TableOptions.FormatContent);

            File.WriteAllText(valuesFilePath, document.ToString(markdownFormat));

            foreach (Command command in application.Commands)
            {
                readmeFilePath = Path.GetFullPath(Path.Combine(destinationDirectoryPath, $"{command.Name}-command.md"));

                using (var sw = new StreamWriter(readmeFilePath, append: false, Encoding.UTF8))
                    using (MarkdownWriter mw = MarkdownWriter.Create(sw))
                    {
                        var writer = new DocumentationWriter(mw);

                        writer.WriteCommandHeading(command, application);
                        writer.WriteCommandDescription(command);

                        mw.WriteLink("Home", "README.md#readme");

                        foreach (string section in new[] { "Synopsis", "Arguments", "Options", "Samples" })
                        {
                            mw.WriteString(" ");
                            mw.WriteCharEntity((char)0x2022);
                            mw.WriteString(" ");
                            mw.WriteLink(section, "#" + section);
                        }

                        mw.WriteLine();

                        writer.WriteCommandSynopsis(command, application);
                        writer.WriteArguments(command.Arguments);
                        writer.WriteOptions(command.Options);

                        string samplesFilePath = Path.Combine(dataDirectoryPath, command.Name + "_bottom.md");

                        if (File.Exists(samplesFilePath))
                        {
                            string content = File.ReadAllText(samplesFilePath);
                            mw.WriteRaw(content);
                        }

                        WriteFootNote(mw);

                        Console.WriteLine(readmeFilePath);
                    }
            }

            Console.WriteLine("Done");

            if (Debugger.IsAttached)
            {
                Console.ReadKey();
            }
        }
Example #13
0
        public static bool TryParse(
            IEnumerable <string> values,
            string optionName,
            OptionValueProvider provider,
            out Filter filter,
            bool allowNull = false,
            NamePartKind defaultNamePart          = NamePartKind.Name,
            PatternOptions includedPatternOptions = PatternOptions.None)
        {
            filter = null;

            string pattern = values.FirstOrDefault();

            if (pattern == null)
            {
                if (allowNull)
                {
                    return(true);
                }
                else
                {
                    throw new InvalidOperationException($"Option '{OptionNames.GetHelpText(optionName)}' is required.");
                }
            }

            TimeSpan             matchTimeout = Regex.InfiniteMatchTimeout;
            string               groupName    = null;
            NamePartKind         namePart     = defaultNamePart;
            string               separator    = null;
            Func <Capture, bool> predicate    = null;

            List <string> options = null;

            foreach (string option in values.Skip(1))
            {
                int index = option.IndexOf("=");

                if (index != -1)
                {
                    string key   = option.Substring(0, index);
                    string value = option.Substring(index + 1);

                    if (OptionValues.Group.IsKeyOrShortKey(key))
                    {
                        groupName = value;
                        continue;
                    }
                    else if (OptionValues.ListSeparator.IsKeyOrShortKey(key))
                    {
                        separator = value;
                        continue;
                    }
                    else if (OptionValues.Part.IsKeyOrShortKey(key))
                    {
                        if (!TryParseAsEnum(value, out namePart, provider: OptionValueProviders.NamePartKindProvider))
                        {
                            string helpText = OptionValueProviders.NamePartKindProvider.GetHelpText();
                            WriteError($"Option '{OptionValues.Part.HelpValue}' has invalid value '{value}'. Allowed values: {helpText}.");
                            return(false);
                        }

                        continue;
                    }
                    else if (OptionValues.Timeout.IsKeyOrShortKey(key))
                    {
                        if (!TryParseMatchTimeout(value, out matchTimeout))
                        {
                            WriteError($"Option '{OptionValues.Timeout.HelpValue}' has invalid value '{value}'.");
                            return(false);
                        }

                        continue;
                    }
                }

                if (Expression.TryParse(option, out Expression expression))
                {
                    if (OptionValues.Length.IsKeyOrShortKey(expression.Identifier))
                    {
                        try
                        {
                            predicate = PredicateHelpers.GetLengthPredicate(expression);
                            continue;
                        }
                        catch (ArgumentException)
                        {
                            WriteError($"Option '{OptionNames.GetHelpText(optionName)}' has invalid value '{option}'.");
                            return(false);
                        }
                    }
                    else
                    {
                        WriteError($"Option '{OptionNames.GetHelpText(optionName)}' has invalid value '{option}'. Allowed values: {provider.GetHelpText()}.");
                        return(false);
                    }
                }

                (options ?? (options = new List <string>())).Add(option);
            }

            if (!TryParseRegexOptions(options, optionName, out RegexOptions regexOptions, out PatternOptions patternOptions, includedPatternOptions, provider))
            {
                return(false);
            }

            switch (patternOptions & (PatternOptions.WholeWord | PatternOptions.WholeLine))
            {
            case PatternOptions.None:
            case PatternOptions.WholeWord:
            case PatternOptions.WholeLine:
            {
                break;
            }

            default:
            {
                WriteError($"Values '{OptionValueProviders.PatternOptionsProvider.GetValue(nameof(PatternOptions.WholeWord)).HelpValue}' and '{OptionValueProviders.PatternOptionsProvider.GetValue(nameof(PatternOptions.WholeLine)).HelpValue}' cannot be combined.");
                return(false);
            }
            }

            if ((patternOptions & PatternOptions.FromFile) != 0 &&
                !FileSystemHelpers.TryReadAllText(pattern, out pattern))
            {
                return(false);
            }

            pattern = BuildPattern(pattern, patternOptions, separator);

            Regex regex = null;

            try
            {
                regex = new Regex(pattern, regexOptions, matchTimeout);
            }
            catch (ArgumentException ex)
            {
                WriteError(ex, $"Could not parse regular expression: {ex.Message}");
                return(false);
            }

            int groupIndex = -1;

            if (groupName != null)
            {
                groupIndex = regex.GroupNumberFromName(groupName);
                if (groupIndex == -1)
                {
                    string message = $"Group '{groupName}' does not exist.";

                    string[] groupNames = regex.GetGroupNames();

                    if (groupNames.Length > 1)
                    {
                        message += $" Existing group names: {TextHelpers.Join(", ", " and ", groupNames.Where(f => f != "0"))}.";
                    }

                    WriteError(message);
                    return(false);
                }
            }

            filter = new Filter(
                regex,
                namePart: namePart,
                groupNumber: groupIndex,
                isNegative: (patternOptions & PatternOptions.Negative) != 0,
                predicate);

            return(true);
        }
Example #14
0
        private static void Main(params string[] args)
        {
            IEnumerable <Command> commands = CommandLoader.LoadCommands(typeof(CommandLoader).Assembly)
                                             .Select(c => c.WithOptions(c.Options.OrderBy(f => f, CommandOptionComparer.Instance)))
                                             .OrderBy(c => c.Name, StringComparer.InvariantCulture);

            var application = new CommandLineApplication(
                "orang",
                "Search, replace, rename and delete files and its content using the power of .NET regular expressions.",
                commands.OrderBy(f => f.Name, StringComparer.InvariantCulture));

            string?destinationDirectoryPath = null;
            string?dataDirectoryPath        = null;

            if (Debugger.IsAttached)
            {
                destinationDirectoryPath = (args.Length > 0) ? args[0] : @"..\..\..\..\..\docs\cli";
                dataDirectoryPath        = @"..\..\..\data";
            }
            else
            {
                destinationDirectoryPath = args[0];
                dataDirectoryPath        = @"..\src\DocumentationGenerator\data";
            }

            string readmeFilePath = Path.GetFullPath(Path.Combine(destinationDirectoryPath, "README.md"));

            using (var sw = new StreamWriter(readmeFilePath, append: false, Encoding.UTF8))
                using (MarkdownWriter mw = MarkdownWriter.Create(sw))
                {
                    mw.WriteHeading1("Orang Command-Line Interface");
                    mw.WriteString(application.Description);
                    mw.WriteLine();

                    mw.WriteHeading2("Commands");

                    foreach (Command command in application.Commands)
                    {
                        mw.WriteStartBulletItem();
                        mw.WriteLink(command.Name, command.Name + "-command.md");
                        mw.WriteEndBulletItem();
                    }

                    mw.WriteLine();

                    string readmeLinksFilePath = Path.Combine(dataDirectoryPath, "readme_bottom.md");

                    if (File.Exists(readmeLinksFilePath))
                    {
                        mw.WriteRaw(File.ReadAllText(readmeLinksFilePath));
                    }

                    WriteFootNote(mw);

                    Console.WriteLine(readmeFilePath);
                }

            string valuesFilePath = Path.GetFullPath(Path.Combine(destinationDirectoryPath, "AllowedValues.md"));

            ImmutableArray <OptionValueProvider> providers = OptionValueProvider.GetProviders(commands.SelectMany(f => f.Options), OptionValueProviders.ProvidersByName.Select(f => f.Value)).ToImmutableArray();

            MDocument document = Document(
                Heading1("List of Allowed Values"),
                BulletList(providers.Select(f => Link(f.Name, "#" + f.Name
                                                      .ToLower()
                                                      .Replace("<", "")
                                                      .Replace(">", "")
                                                      .Replace("_", "-")))),
                providers.Select(provider =>
            {
                return(new MObject[]
                {
                    Heading2(provider.Name),
                    Table(
                        TableRow("Value", "Description"),
                        provider.Values.Select(f => TableRow(f.HelpValue, f.Description)))
                });
            }));

            AddFootnote(document);

            var markdownFormat = new MarkdownFormat(tableOptions: MarkdownFormat.Default.TableOptions | TableOptions.FormatContent);

            File.WriteAllText(valuesFilePath, document.ToString(markdownFormat));

            foreach (Command command in application.Commands)
            {
                readmeFilePath = Path.GetFullPath(Path.Combine(destinationDirectoryPath, $"{command.Name}-command.md"));

                using (var sw = new StreamWriter(readmeFilePath, append: false, Encoding.UTF8))
                    using (MarkdownWriter mw = MarkdownWriter.Create(sw))
                    {
                        var writer = new DocumentationWriter(mw);

                        writer.WriteCommandHeading(command, application);
                        writer.WriteCommandDescription(command);
                        writer.WriteCommandSynopsis(command, application);
                        writer.WriteArguments(command.Arguments);
                        writer.WriteOptions(command.Options);

                        string samplesFilePath = Path.Combine(dataDirectoryPath, command.Name + "_bottom.md");

                        if (File.Exists(samplesFilePath))
                        {
                            string content = File.ReadAllText(samplesFilePath);
                            mw.WriteRaw(content);
                        }

                        WriteFootNote(mw);

                        Console.WriteLine(readmeFilePath);
                    }
            }

            Console.WriteLine("Done");

            if (Debugger.IsAttached)
            {
                Console.ReadKey();
            }
        }