Exemple #1
0
        public async Task <IBuildScript> FindAndCreateBuildScriptInstanceAsync(CommandArguments args)
        {
            string buildScriptFilePath     = _buildScriptLocator.FindBuildScript(args);
            var    buildScriptAssemblyPath = Path.Combine("bin", Path.GetFileName(buildScriptFilePath));

            buildScriptAssemblyPath = Path.ChangeExtension(buildScriptAssemblyPath, "dll");

            List <string>             code = _file.ReadAllLines(buildScriptFilePath);
            ScriptAnalyzerResult      scriptAnalyzerResult      = _scriptAnalyzer.Analyze(code);
            ProjectFileAnalyzerResult projectFileAnalyzerResult = _projectFileAnalyzer.Analyze(disableAnalysis: scriptAnalyzerResult.ScriptAttributes.Contains(ScriptAttributes.DisableLoadScriptReferencesAutomatically));
            bool oldWay = false;

#if NET462
            oldWay = true;
#endif
            var references = GetBuildScriptReferences(args, projectFileAnalyzerResult, scriptAnalyzerResult, code, oldWay, buildScriptFilePath);

            if (oldWay)
            {
                return(await CreateBuildScriptInstanceOldWay(buildScriptFilePath, references, code, scriptAnalyzerResult));
            }

            var assembly = TryLoadBuildScriptFromAssembly(buildScriptAssemblyPath, buildScriptFilePath);

            if (assembly != null)
            {
                return(CreateBuildScriptInstance(assembly, buildScriptFilePath));
            }

            code.Insert(0, $"#line 1 \"{buildScriptFilePath}\"");
            assembly = CompileBuildScriptToAssembly(buildScriptAssemblyPath, buildScriptFilePath, references, string.Join("\r\n", code));
            return(CreateBuildScriptInstance(assembly, buildScriptFilePath));
        }
Exemple #2
0
        public async Task <IBuildScript> FindAndCreateBuildScriptInstanceAsync(CommandArguments args)
        {
            string buildScriptFilePath     = _buildScriptLocator.FindBuildScript(args);
            var    buildScriptAssemblyPath = GetBuildScriptAssemblyFileName(buildScriptFilePath, fullPath: false);

            List <string>             code = _file.ReadAllLines(buildScriptFilePath);
            ScriptAnalyzerResult      scriptAnalyzerResult      = _scriptAnalyzer.Analyze(code);
            ProjectFileAnalyzerResult projectFileAnalyzerResult = _projectFileAnalyzer.Analyze(
                disableAnalysis: scriptAnalyzerResult.ScriptAttributes.Contains(ScriptConfigAttributes
                                                                                .DisableLoadScriptReferencesAutomatically));

            ProcessConfigAttributes(scriptAnalyzerResult);
            ProcessAddedCsFilesToBuildScript(scriptAnalyzerResult, code);
            ProcessPartialBuildScriptClasses(scriptAnalyzerResult, code, buildScriptFilePath);

            bool oldWay = scriptAnalyzerResult.ScriptAttributes.Contains(ScriptConfigAttributes
                                                                         .CreateBuildScriptInstanceOldWayAttribute);

#if NET462
            oldWay = true;
#endif
            var references = GetBuildScriptReferences(args, projectFileAnalyzerResult, scriptAnalyzerResult,
                                                      oldWay, buildScriptFilePath);

            if (oldWay)
            {
                return(await CreateBuildScriptInstanceOldWay(buildScriptFilePath, references, code,
                                                             scriptAnalyzerResult));
            }

            Assembly assembly;
            if (!scriptAnalyzerResult.ScriptAttributes.Contains(ScriptConfigAttributes.AlwaysRecompileScript))
            {
                assembly = TryLoadBuildScriptFromAssembly(buildScriptAssemblyPath, buildScriptFilePath,
                                                          scriptAnalyzerResult, projectFileAnalyzerResult);

                if (assembly != null)
                {
                    return(CreateBuildScriptInstance(assembly, buildScriptFilePath));
                }
            }

            code.Insert(0, $"#line 1 \"{buildScriptFilePath}\"");
            assembly = CompileBuildScript(buildScriptAssemblyPath, buildScriptFilePath, references, string.Join("\r\n", code));
            return(CreateBuildScriptInstance(assembly, buildScriptFilePath));
        }
        public void Analyze()
        {
            List <string> lines = new List <string>()
            {
                "//#ass",
                "//",
                "//#ass hello.dll",
                "//#nuget Package, 2.0.0",
                "//#imp test.cs",
                "public class MyScript"
            };

            _pathWrapper.Setup(x => x.GetExtension(It.IsAny <string>())).Returns(".dll");
            _fileWrapper.Setup(x => x.Exists(It.IsAny <string>())).Returns(true);

            var res = _analyzer.Analyze(lines);

            Assert.Equal("MyScript", res.ClassName);
            Assert.Single(res.AssemblyReferences);
            Assert.Single(res.NugetPackageReferences);
            Assert.Single(res.CsFiles);
            Assert.Equal(2, lines.Count);
        }
Exemple #4
0
        private static ScriptAnalyzerResult PerformAnalysis(IScriptAnalyzer analyzer, DirectoryPath root, BootstrapFeatureSettings settings)
        {
            var result = analyzer.Analyze(settings.Script, new ScriptAnalyzerSettings()
            {
                Mode = ScriptAnalyzerMode.Modules
            });

            if (!result.Succeeded)
            {
                var messages = string.Join("\n", result.Errors.Select(s => $"{root.GetRelativePath(s.File).FullPath}, line #{s.Line}: {s.Message}"));
                throw new AggregateException($"Bootstrapping failed for '{settings.Script}'.\n{messages}");
            }

            return(result);
        }
Exemple #5
0
        public bool Execute(CakeOptions options)
        {
            // Get the script path and the root.
            var path = options.Script.MakeAbsolute(_environment);
            var root = path.GetDirectory();

            // Analyze the script.
            var result = _analyzer.Analyze(path);

            if (!result.Succeeded)
            {
                var messages = string.Join("\n", result.Errors.Select(s => $"{root.GetRelativePath(s.File).FullPath}, line #{s.Line}: {s.Message}"));
                throw new AggregateException($"Bootstrapping failed for '{path}'.\n{messages}");
            }

            // Install modules.
            _processor.InstallModules(
                result.Modules,
                _configuration.GetModulePath(root, _environment));

            // Success.
            return(true);
        }
        /// <summary>
        /// Runs the script using the specified script host.
        /// </summary>
        /// <param name="host">The script host.</param>
        /// <param name="scriptPath">The script.</param>
        /// <param name="arguments">The arguments.</param>
        public void Run(IScriptHost host, FilePath scriptPath, IDictionary <string, string> arguments)
        {
            if (host == null)
            {
                throw new ArgumentNullException(nameof(host));
            }
            if (scriptPath == null)
            {
                throw new ArgumentNullException(nameof(scriptPath));
            }
            if (arguments == null)
            {
                throw new ArgumentNullException(nameof(arguments));
            }

            // Make the script path absolute.
            scriptPath = scriptPath.MakeAbsolute(_environment);

            // Prepare the environment.
            _environment.WorkingDirectory = scriptPath.GetDirectory();

            // Analyze the script file.
            _log.Verbose("Analyzing build script...");
            var result = _analyzer.Analyze(scriptPath.GetFilename());

            // Log all errors and throw
            if (!result.Succeeded)
            {
                foreach (var error in result.Errors)
                {
                    var format = $"{error.File.MakeAbsolute(_environment).FullPath}:{error.Line}: {{0}}";
                    _log.Error(format, error.Message);
                }
                throw new CakeException("Errors occurred while analyzing script.");
            }

            // Install tools.
            _log.Verbose("Processing build script...");
            var toolsPath = GetToolPath(scriptPath.GetDirectory());

            _processor.InstallTools(result.Tools, toolsPath);

            // Install addins.
            var addinRoot       = GetAddinPath(scriptPath.GetDirectory());
            var addinReferences = _processor.InstallAddins(result.Addins, addinRoot);

            foreach (var addinReference in addinReferences)
            {
                result.References.Add(addinReference.FullPath);
            }

            // Create and prepare the session.
            var session = _engine.CreateSession(host);

            // Load all references.
            var applicationRoot = _environment.ApplicationRoot;
            var assemblies      = new HashSet <Assembly>();

            assemblies.AddRange(_conventions.GetDefaultAssemblies(applicationRoot));

            foreach (var reference in result.References)
            {
                var referencePath = new FilePath(reference);
                if (host.Context.FileSystem.Exist(referencePath))
                {
                    var assembly = _assemblyLoader.Load(referencePath, true);
                    assemblies.Add(assembly);
                }
                else
                {
                    // Add a reference to the session.
                    session.AddReference(referencePath);
                }
            }

            var aliases = new List <ScriptAlias>();

            // Got any assemblies?
            if (assemblies.Count > 0)
            {
                // Find all script aliases.
                var foundAliases = _aliasFinder.FindAliases(assemblies);
                if (foundAliases.Count > 0)
                {
                    aliases.AddRange(foundAliases);
                }

                // Add assembly references to the session.
                foreach (var assembly in assemblies)
                {
                    session.AddReference(assembly);
                }
            }

            // Import all namespaces.
            var namespaces = new HashSet <string>(result.Namespaces, StringComparer.Ordinal);

            namespaces.AddRange(_conventions.GetDefaultNamespaces());
            namespaces.AddRange(aliases.SelectMany(alias => alias.Namespaces));
            foreach (var @namespace in namespaces.OrderBy(ns => ns))
            {
                session.ImportNamespace(@namespace);
            }

            // Execute the script.
            var script = new Script(result.Namespaces, result.Lines, aliases, result.UsingAliases, result.UsingStaticDirectives, result.Defines);

            session.Execute(script);
        }
Exemple #7
0
        /// <summary>
        /// Runs the script using the specified script host.
        /// </summary>
        /// <param name="host">The script host.</param>
        /// <param name="scriptPath">The script.</param>
        /// <param name="arguments">The arguments.</param>
        public void Run(IScriptHost host, FilePath scriptPath, IDictionary <string, string> arguments)
        {
            if (host == null)
            {
                throw new ArgumentNullException("host");
            }
            if (scriptPath == null)
            {
                throw new ArgumentNullException("scriptPath");
            }
            if (arguments == null)
            {
                throw new ArgumentNullException("arguments");
            }

            // Prepare the context.
            host.Context.Arguments.SetArguments(arguments);
            host.Context.Environment.WorkingDirectory = scriptPath.MakeAbsolute(host.Context.Environment).GetDirectory();

            // Analyze the script file.
            _log.Verbose("Analyzing build script...");
            scriptPath = scriptPath.IsRelative ? scriptPath.MakeAbsolute(_environment) : scriptPath;
            var result = _analyzer.Analyze(scriptPath.GetFilename());

            // Install tools.
            _log.Verbose("Processing build script...");
            var toolsPath = scriptPath.GetDirectory().Combine("tools");

            _processor.InstallTools(result, toolsPath);

            // Install addins.
            var applicationRoot = _environment.GetApplicationRoot();
            var addinRoot       = applicationRoot.Combine("Addins").Collapse();
            var addinReferences = _processor.InstallAddins(result, addinRoot);

            foreach (var addinReference in addinReferences)
            {
                result.References.Add(addinReference.FullPath);
            }

            // Create and prepare the session.
            var session = _engine.CreateSession(host, arguments);

            // Load all references.
            var assemblies = new HashSet <Assembly>();

            assemblies.AddRange(_conventions.GetDefaultAssemblies(applicationRoot));
            foreach (var reference in result.References)
            {
                if (host.Context.FileSystem.Exist((FilePath)reference))
                {
                    var assembly = Assembly.LoadFrom(reference);
                    assemblies.Add(assembly);
                }
                else
                {
                    // Add a reference to the session.
                    session.AddReference(reference);
                }
            }

            var aliases = new List <ScriptAlias>();

            // Got any assemblies?
            if (assemblies.Count > 0)
            {
                // Find all script aliases.
                var foundAliases = _aliasFinder.FindAliases(assemblies);
                if (foundAliases.Count > 0)
                {
                    aliases.AddRange(foundAliases);
                }

                // Add assembly references to the session.
                foreach (var assembly in assemblies)
                {
                    session.AddReference(assembly);
                }
            }

            // Import all namespaces.
            var namespaces = new HashSet <string>(result.Namespaces, StringComparer.Ordinal);

            namespaces.AddRange(_conventions.GetDefaultNamespaces());
            namespaces.AddRange(aliases.SelectMany(alias => alias.Namespaces));
            foreach (var @namespace in namespaces.OrderBy(ns => ns))
            {
                session.ImportNamespace(@namespace);
            }

            // Execute the script.
            var script = new Script(result.Namespaces, result.Lines, aliases, result.UsingAliases);

            session.Execute(script);
        }
Exemple #8
0
        public CakeScript Generate(FileChange fileChange)
        {
            if (fileChange == null)
            {
                throw new ArgumentNullException(nameof(fileChange));
            }

            // Make the script path absolute.
            var scriptPath = new FilePath(fileChange.FileName).MakeAbsolute(_environment);

            // Prepare the file changes
            _log.Verbose("Handling file change...");
            HandleFileChange(scriptPath, fileChange);

            // Analyze the script file.
            _log.Verbose("Analyzing build script...");
            var result = _analyzer.Analyze(scriptPath);

            // Install addins.
            foreach (var addin in result.Addins)
            {
                try
                {
                    _log.Verbose("Installing addins...");
                    var addinReferences = _processor.InstallAddins(new[] { addin }, _addinRoot);
                    foreach (var addinReference in addinReferences)
                    {
                        result.References.Add(addinReference.FullPath);
                    }
                }
                catch (Exception e)
                {
                    // Log and continue if it fails
                    _log.Error(e);
                }
            }

            // Load all references.
            _log.Verbose("Adding references...");
            var references = new HashSet <FilePath>(_defaultReferences.Value);

            references.AddRange(result.References.Select(r => new FilePath(r)));

            // Find aliases
            _log.Verbose("Finding aliases...");
            var aliases = new List <CakeScriptAlias>();

            foreach (var reference in references)
            {
                if (_fileSystem.Exist(reference))
                {
                    aliases.AddRange(_aliasFinder.FindAliases(reference));
                }
            }

            // Import all namespaces.
            _log.Verbose("Importing namespaces...");
            var namespaces = new HashSet <string>(result.Namespaces, StringComparer.Ordinal);

            namespaces.AddRange(GetDefaultNamespaces());
            namespaces.AddRange(aliases.SelectMany(alias => alias.Namespaces));

            // Create the response.
            // ReSharper disable once UseObjectOrCollectionInitializer
            _log.Verbose("Creating response...");
            var response = new CakeScript();

            response.Host.TypeName     = _hostObject.TypeName;
            response.Host.AssemblyPath = _hostObject.AssemblyPath;
            response.Source            = string.Join("\n", result.Defines) +
                                         string.Join("\n", result.UsingAliases) +
                                         string.Join("\n", result.UsingStaticDirectives) +
                                         GenerateSource(aliases) +
                                         string.Join("\n", result.Lines);
            response.Usings.AddRange(namespaces);
            response.References.AddRange(references.Select(r => r.FullPath));

            // Return the response.
            return(response);
        }