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)); }
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); }
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); }
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); }
/// <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); }
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); }