예제 #1
0
        public bool Exists(string path)
        {
            int lastSep = path.IndexOfAny(new[] { '/', '\\' });
            ITemplateSourceFolder rootFolder = this;

            if (lastSep == -1)
            {
                return(rootFolder.Children.Any(x => string.Equals(path, x.Name, StringComparison.OrdinalIgnoreCase)));
            }

            string part = path.Substring(0, lastSep);
            ITemplateSourceFolder sourceFolder = (ITemplateSourceFolder)rootFolder.Children.FirstOrDefault(x => string.Equals(part, x.Name, StringComparison.OrdinalIgnoreCase));

            while (lastSep > 0)
            {
                int start = lastSep + 1;
                lastSep = path.IndexOfAny(new[] { '/', '\\' }, lastSep + 1);

                if (lastSep < 0)
                {
                    part = path.Substring(start);
                    return(sourceFolder.Children.Any(x => string.Equals(part, x.Name, StringComparison.OrdinalIgnoreCase)));
                }

                part         = path.Substring(start, lastSep - start);
                sourceFolder = (ITemplateSourceFolder)sourceFolder.Children.FirstOrDefault(x => string.Equals(part, x.Name, StringComparison.OrdinalIgnoreCase));
            }

            return(false);
        }
        public Stream OpenFile(string path)
        {
            int lastSep = path.IndexOfAny(new[] { '/', '\\' });
            IDisposable <ITemplateSourceFolder> rootFolder = Root;

            if (lastSep == -1)
            {
                ITemplateSourceFile sourceFile = (ITemplateSourceFile)rootFolder.Value.Children.FirstOrDefault(x => string.Equals(path, x.Name, StringComparison.OrdinalIgnoreCase));
                return(new CoDisposableStream(sourceFile.OpenRead(), rootFolder));
            }

            string part = path.Substring(0, lastSep);
            ITemplateSourceFolder sourceFolder = (ITemplateSourceFolder)rootFolder.Value.Children.FirstOrDefault(x => string.Equals(part, x.Name, StringComparison.OrdinalIgnoreCase));

            while (lastSep > 0)
            {
                int start = lastSep + 1;
                lastSep = path.IndexOfAny(new[] { '/', '\\' }, lastSep + 1);

                if (lastSep < 0)
                {
                    part = path.Substring(start);
                    ITemplateSourceFile sourceFile = (ITemplateSourceFile)sourceFolder.Children.FirstOrDefault(x => string.Equals(part, x.Name, StringComparison.OrdinalIgnoreCase));
                    return(new CoDisposableStream(sourceFile.OpenRead(), rootFolder));
                }

                part         = path.Substring(start, lastSep - start);
                sourceFolder = (ITemplateSourceFolder)sourceFolder.Children.FirstOrDefault(x => string.Equals(part, x.Name, StringComparison.OrdinalIgnoreCase));
            }

            rootFolder.Dispose();
            throw new FileNotFoundException("Unable to find file", path);
        }
 public File(ITemplateSourceFolder parent, string fullPath, string name, Func <ZipArchive> opener)
     : base(parent)
 {
     _opener  = opener;
     FullPath = fullPath;
     Name     = name;
 }
 public Directory(ITemplateSourceFolder parent, string fullPath, string name, Func <ZipArchive> opener)
     : base(parent)
 {
     FullPath        = fullPath;
     Name            = name;
     _opener         = opener;
     _lastSlashIndex = string.IsNullOrEmpty(fullPath) ? 0 : (fullPath.Length - 1);
 }
            public static ITemplateSourceEntry Create(int rootLength, ITemplateSourceFolder parent, FileSystemInfo info)
            {
                DirectoryInfo dir = info as DirectoryInfo;

                if (dir != null)
                {
                    return(new Directory(rootLength, parent, dir));
                }

                return(new File(rootLength, parent, (FileInfo)info));
            }
예제 #6
0
        public string PathRelativeTo(ITemplateSourceEntry source)
        {
            //The path should be relative to either source itself (in the case that it's a folder) or the parent of source)
            ITemplateSourceFolder relTo = source as ITemplateSourceFolder ?? source.Parent;

            //If the thing to be relative to is the root (or a file in the root), just use the full path of the item
            if (relTo == null)
            {
                return(FullPath);
            }

            //Get all the path segments for the thing we're relative to
            Dictionary <ITemplateSourceFolder, int> sourceSegments = new Dictionary <ITemplateSourceFolder, int> {
                { relTo, 0 }
            };
            ITemplateSourceFolder current = relTo.Parent;
            int index = 0;

            while (current != null)
            {
                sourceSegments[current] = ++index;
                current = current.Parent;
            }

            current = Parent;
            List <string> segments = new List <string> {
                Name
            };

            //Walk back the set of parents of this item until one is contained by our source, building up a list as we go
            int revIndex = 0;

            while (current != null && !sourceSegments.TryGetValue(current, out revIndex))
            {
                segments.Insert(0, current.Name);
                current = current.Parent;
            }

            //Now that we've found our common point (and the index of the common segment _from the end_ of the source's parent chain)
            //  the number of levels up we need to go is the value of revIndex
            segments.InsertRange(0, Enumerable.Repeat("..", revIndex));
            return(string.Join("/", segments));
        }
        public void Run(string runSpecPath, ITemplateSourceFolder sourceDir, string targetDir)
        {
            IGlobalRunSpec spec;

            using (FileStream stream = File.OpenRead(runSpecPath))
            {
                spec = RunSpecLoader(stream);
                EngineConfig config    = new EngineConfig(EngineConfig.DefaultWhitespaces, EngineConfig.DefaultLineEndings, spec.RootVariableCollection);
                IProcessor   processor = Processor.Create(config, spec.Operations);
                stream.Position = 0;
                using (MemoryStream ms = new MemoryStream())
                {
                    processor.Run(stream, ms);
                    ms.Position = 0;
                    spec        = RunSpecLoader(ms);
                }
            }

            RunInternal(this, sourceDir, targetDir, spec);
        }
예제 #8
0
 protected TemplateSourceFolder(ITemplateSourceFolder parent)
     : base(parent)
 {
 }
        private IEnumerable <ITemplate> GetTemplatesFromDir(IConfiguredTemplateSource source, ITemplateSourceFolder folder)
        {
            foreach (ITemplateSourceEntry entry in folder.Children)
            {
                if (entry.Kind == TemplateSourceEntryKind.File && entry.FullPath.EndsWith(".vstemplate"))
                {
                    VsTemplate tmp = null;
                    try
                    {
                        tmp = new VsTemplate((ITemplateSourceFile)entry, source, this);
                    }
                    catch
                    {
                    }

                    if (tmp != null)
                    {
                        yield return(tmp);
                    }
                }
                else if (entry.Kind == TemplateSourceEntryKind.Folder)
                {
                    foreach (ITemplate template in GetTemplatesFromDir(source, (ITemplateSourceFolder)entry))
                    {
                        yield return(template);
                    }
                }
            }
        }
예제 #10
0
        public ITemplateSourceFolder GetDirectoryAtRelativePath(string source)
        {
            int sepIndex = source.IndexOfAny(new[] { '\\', '/' });

            if (sepIndex < 0)
            {
                switch (source)
                {
                case "":
                case ".":
                    return(this);

                case "..":
                    return(Parent);

                default:
                    return((ITemplateSourceFolder)Children.FirstOrDefault(x => string.Equals(x.Name, source, StringComparison.OrdinalIgnoreCase)));
                }
            }

            string part = source.Substring(0, sepIndex);
            ITemplateSourceFolder current = this;

            while (sepIndex > -1)
            {
                switch (part)
                {
                case "":
                case ".":
                    break;

                case "..":
                    current = current.Parent;
                    break;

                default:
                    current = (ITemplateSourceFolder)current.Children.FirstOrDefault(x => string.Equals(x.Name, part, StringComparison.OrdinalIgnoreCase));
                    break;
                }

                int start = sepIndex + 1;
                sepIndex = source.IndexOfAny(new[] { '\\', '/' }, start);

                if (sepIndex == -1)
                {
                    part = source.Substring(start);
                    switch (part)
                    {
                    case "":
                    case ".":
                        break;

                    case "..":
                        current = current.Parent;
                        break;

                    default:
                        current = (ITemplateSourceFolder)current.Children.FirstOrDefault(x => string.Equals(x.Name, part, StringComparison.OrdinalIgnoreCase));
                        break;
                    }
                }
                else
                {
                    part = source.Substring(start, sepIndex - start);
                }
            }

            return(current);
        }
예제 #11
0
 protected TemplateSourceFile(ITemplateSourceFolder sourceFolder)
     : base(sourceFolder)
 {
 }
예제 #12
0
 protected TemplateSourceEntry(ITemplateSourceFolder parent)
 {
     Parent = parent;
 }
        public GlobalRunSpec(FileSource source, ITemplateSourceFolder templateRoot, IParameterSet parameters, IReadOnlyDictionary <string, JObject> operations, IReadOnlyDictionary <string, Dictionary <string, JObject> > special)
        {
            int expect = source.Include?.Length ?? 0;
            List <IPathMatcher> includes = new List <IPathMatcher>(expect);

            if (source.Include != null && expect > 0)
            {
                foreach (string include in source.Include)
                {
                    includes.Add(new GlobbingPatternMatcher(include));
                }
            }
            Include = includes;

            expect = source.CopyOnly?.Length ?? 0;
            List <IPathMatcher> copyOnlys = new List <IPathMatcher>(expect);

            if (source.CopyOnly != null && expect > 0)
            {
                foreach (string copyOnly in source.CopyOnly)
                {
                    copyOnlys.Add(new GlobbingPatternMatcher(copyOnly));
                }
            }
            CopyOnly = copyOnlys;

            expect = source.Exclude?.Length ?? 0;
            List <IPathMatcher> excludes = new List <IPathMatcher>(expect);

            if (source.Exclude != null && expect > 0)
            {
                foreach (string exclude in source.Exclude)
                {
                    excludes.Add(new GlobbingPatternMatcher(exclude));
                }
            }
            Exclude = excludes;

            Rename = source.Rename != null
                ? new Dictionary <string, string>(source.Rename, StringComparer.OrdinalIgnoreCase)
                : new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            VariableCollection variables;

            Operations             = ProcessOperations(parameters, templateRoot, operations, out variables);
            RootVariableCollection = variables;
            Dictionary <IPathMatcher, IRunSpec> specials = new Dictionary <IPathMatcher, IRunSpec>();

            if (special != null)
            {
                foreach (KeyValuePair <string, Dictionary <string, JObject> > specialEntry in special)
                {
                    IReadOnlyList <IOperationProvider> specialOps = null;
                    VariableCollection specialVariables           = variables;

                    if (specialEntry.Value != null)
                    {
                        specialOps = ProcessOperations(parameters, templateRoot, specialEntry.Value, out specialVariables);
                    }

                    RunSpec spec = new RunSpec(specialOps, specialVariables ?? variables);
                    specials[new GlobbingPatternMatcher(specialEntry.Key)] = spec;
                }
            }

            Special = specials;
        }
        private IReadOnlyList <IOperationProvider> ProcessOperations(IParameterSet parameters, ITemplateSourceFolder templateRoot, IReadOnlyDictionary <string, JObject> operations, out VariableCollection variables)
        {
            List <IOperationProvider> result = new List <IOperationProvider>();
            JObject variablesSection         = operations["variables"];

            JObject data;

            if (operations.TryGetValue("macros", out data))
            {
                foreach (JProperty property in data.Properties())
                {
                    RunMacros(property, variablesSection, parameters);
                }
            }

            if (operations.TryGetValue("include", out data))
            {
                string startToken = data["start"].ToString();
                string endToken   = data["end"].ToString();
                result.Add(new Include(startToken, endToken, templateRoot.OpenFile));
            }

            if (operations.TryGetValue("regions", out data))
            {
                JArray regionSettings = (JArray)data["settings"];
                foreach (JToken child in regionSettings.Children())
                {
                    JObject setting         = (JObject)child;
                    string  start           = setting["start"].ToString();
                    string  end             = setting["end"].ToString();
                    bool    include         = setting["include"]?.ToObject <bool>() ?? false;
                    bool    regionTrim      = setting["trim"]?.ToObject <bool>() ?? false;
                    bool    regionWholeLine = setting["wholeLine"]?.ToObject <bool>() ?? false;
                    result.Add(new Region(start, end, include, regionWholeLine, regionTrim));
                }
            }

            if (operations.TryGetValue("conditionals", out data))
            {
                string             ifToken       = data["if"].ToString();
                string             elseToken     = data["else"].ToString();
                string             elseIfToken   = data["elseif"].ToString();
                string             endIfToken    = data["endif"].ToString();
                string             evaluatorName = data["evaluator"].ToString();
                bool               trim          = data["trim"]?.ToObject <bool>() ?? false;
                bool               wholeLine     = data["wholeLine"]?.ToObject <bool>() ?? false;
                ConditionEvaluator evaluator     = CppStyleEvaluatorDefinition.CppStyleEvaluator;

                switch (evaluatorName)
                {
                case "C++":
                    evaluator = CppStyleEvaluatorDefinition.CppStyleEvaluator;
                    break;
                }

                result.Add(new Conditional(ifToken, elseToken, elseIfToken, endIfToken, wholeLine, trim, evaluator));
            }

            if (operations.TryGetValue("flags", out data))
            {
                foreach (JProperty property in data.Properties())
                {
                    JObject innerData  = (JObject)property.Value;
                    string  flag       = property.Name;
                    string  on         = innerData["on"]?.ToString() ?? string.Empty;
                    string  off        = innerData["off"]?.ToString() ?? string.Empty;
                    string  onNoEmit   = innerData["onNoEmit"]?.ToString() ?? string.Empty;
                    string  offNoEmit  = innerData["offNoEmit"]?.ToString() ?? string.Empty;
                    string  defaultStr = innerData["default"]?.ToString();
                    bool?   @default   = null;

                    if (defaultStr != null)
                    {
                        @default = bool.Parse(defaultStr);
                    }

                    result.Add(new SetFlag(flag, on, off, onNoEmit, offNoEmit, @default));
                }
            }

            if (operations.TryGetValue("replacements", out data))
            {
                foreach (JProperty property in data.Properties())
                {
                    ITemplateParameter param;
                    if (parameters.TryGetParameter(property.Value.ToString(), out param))
                    {
                        string val;
                        try
                        {
                            val = parameters.ParameterValues[param];
                        }
                        catch (KeyNotFoundException ex)
                        {
                            throw new Exception($"Unable to find a parameter value called \"{param.Name}\"", ex);
                        }

                        Replacment r = new Replacment(property.Name, val);
                        result.Add(r);
                    }
                }
            }

            variables = HandleVariables(parameters, variablesSection, result);
            return(result);
        }
        private static void RunInternal(Orchestrator self, ITemplateSourceFolder sourceDir, string targetDir, IGlobalRunSpec spec)
        {
            EngineConfig cfg      = new EngineConfig(EngineConfig.DefaultWhitespaces, EngineConfig.DefaultLineEndings, spec.RootVariableCollection);
            IProcessor   fallback = Processor.Create(cfg, spec.Operations);

            Dictionary <IPathMatcher, IProcessor> specializations = spec.Special
                                                                    .ToDictionary(
                x => x.Key,
                x =>
            {
                IReadOnlyList <IOperationProvider> operations = x.Value.GetOperations(spec.Operations);
                EngineConfig config  = new EngineConfig(EngineConfig.DefaultWhitespaces, EngineConfig.DefaultLineEndings, spec.RootVariableCollection);
                IProcessor processor = Processor.Create(config, operations);
                return(processor);
            });

            foreach (ITemplateSourceFile file in sourceDir.EnumerateFiles("*", SearchOption.AllDirectories))
            {
                string sourceRel = file.PathRelativeTo(sourceDir);

                foreach (IPathMatcher include in spec.Include)
                {
                    if (include.IsMatch(sourceRel))
                    {
                        bool excluded = false;
                        foreach (IPathMatcher exclude in spec.Exclude)
                        {
                            if (exclude.IsMatch(sourceRel))
                            {
                                excluded = true;
                                break;
                            }
                        }

                        if (!excluded)
                        {
                            bool copy = false;
                            foreach (IPathMatcher copyOnly in spec.CopyOnly)
                            {
                                if (copyOnly.IsMatch(sourceRel))
                                {
                                    copy = true;
                                    break;
                                }
                            }

                            if (!copy)
                            {
                                ProcessFile(self, file, sourceRel, targetDir, spec, fallback, specializations);
                            }
                            else
                            {
                                string targetRel;
                                if (!spec.TryGetTargetRelPath(sourceRel, out targetRel))
                                {
                                    targetRel = sourceRel;
                                }

                                string targetPath    = Path.Combine(targetDir, targetRel);
                                string fullTargetDir = Path.GetDirectoryName(targetPath);
                                Directory.CreateDirectory(fullTargetDir);

                                using (Stream sourceStream = file.OpenRead())
                                    using (Stream targetStream = File.Create(targetPath))
                                    {
                                        sourceStream.CopyTo(targetStream);
                                    }
                            }
                        }

                        break;
                    }
                }
            }
        }
 public void Run(IGlobalRunSpec spec, ITemplateSourceFolder sourceDir, string targetDir)
 {
     RunInternal(this, sourceDir, targetDir, spec);
 }
 public File(int rootLength, ITemplateSourceFolder parent, FileInfo file)
     : base(parent)
 {
     _rootLength = rootLength;
     _file       = file;
 }
예제 #18
0
        private IEnumerable <ITemplate> GetTemplatesFromDir(IConfiguredTemplateSource source, ITemplateSourceFolder folder)
        {
            foreach (ITemplateSourceEntry entry in folder.Children)
            {
                if (entry.Kind == TemplateSourceEntryKind.File && entry.Name.Equals(".netnew.json", StringComparison.OrdinalIgnoreCase))
                {
                    RunnableProjectTemplate tmp = null;
                    try
                    {
                        ITemplateSourceFile file      = (ITemplateSourceFile)entry;
                        JObject             srcObject = ReadConfigModel(file);

                        tmp = new RunnableProjectTemplate(srcObject, this, source, file, srcObject.ToObject <IRunnableProjectConfig>(new JsonSerializer
                        {
                            Converters =
                            {
                                new RunnableProjectConfigConverter()
                            }
                        }));
                    }
                    catch
                    {
                    }

                    if (tmp != null)
                    {
                        yield return(tmp);
                    }
                }
                else if (entry.Kind == TemplateSourceEntryKind.Folder)
                {
                    foreach (ITemplate template in GetTemplatesFromDir(source, (ITemplateSourceFolder)entry))
                    {
                        yield return(template);
                    }
                }
            }
        }
 public Directory(int rootLength, ITemplateSourceFolder parent, DirectoryInfo dir)
     : base(parent)
 {
     _rootLength = rootLength;
     _dir        = dir;
 }