Exemplo n.º 1
0
        public static IDictionary <string, long> Process(IEnumerable <NPath> pathsToFormat, FormatContext formatContext, Func <FormatItem, bool> cancellableBeforeFormatCallback = null)
        {
            if (formatContext == null)
            {
                formatContext = new FormatContext();
            }

            if ((formatContext.Options & FormatOptions.DryRun) != 0)
            {
                throw new NotImplementedException("DryRun not supported yet");
            }

            var formatted   = new Dictionary <string, long>();
            var formatItems = new List <FormatItem>();

            foreach (var path in pathsToFormat)
            {
                FormatItem item;
                if (!File.Exists(path))
                {
                    formatContext.Logger.Error($"File {path} doesn't exist'");
                    continue;
                }
                try
                {
                    item = FormatItem.TryCreate(new NPath(path), formatContext);
                }
                catch (Exception inner)
                {
                    var outer = new Exception($"Fatal occurred while configuring formatting for '{path}' (see inner exception for details)", inner);
                    outer.Data["pathToFormat"] = path.ToString();
                    throw outer;
                }
                if (item == null)
                {
                    continue;
                }

                if (!CheckHeader(item))
                {
                    continue;
                }
                formatItems.Add(item);
                if (cancellableBeforeFormatCallback != null &&
                    cancellableBeforeFormatCallback.Invoke(item))
                {
                    return(formatted);
                }
            }

            if (formatItems.Any())
            {
                // avoid requiring ThisPackageRoot if we are only using the Generic formatter, which has no external
                // tooling dependencies
                if (formatItems.SelectMany(fi => fi.Formatters).Any(f => f != FormatterType.Generic))
                {
                    EnsureFilePermissionsOnUnixLikeOS(formatContext.ThisPackageRoot);
                }

                // FUTURE: this is a good spot to group by formatter, then let the formatter segment (for example,
                // uncrustify would want to segment by associated .ini file), so we can do batching with response
                // files to avoid per-file process spawn overhead.

                var sw = Stopwatch.StartNew();
                foreach (var formatItem in formatItems)
                {
                    if (cancellableBeforeFormatCallback != null &&
                        cancellableBeforeFormatCallback.Invoke(formatItem))
                    {
                        break;
                    }

                    if (Process(formatItem))
                    {
                        formatted[formatItem.Path] = File.GetLastWriteTime(formatItem.Path).Ticks;
                    }
                }

                sw.Stop();
                formatContext.Logger.Debug($"Formatted {formatItems.Count} files. Took {sw.ElapsedMilliseconds}ms");
            }

            return(formatted);
        }