예제 #1
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);
        }
예제 #2
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(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);
        }
예제 #3
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, new ScriptAnalyzerSettings
            {
                Mode = ScriptAnalyzerMode.Everything,
            });

            // 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>(
                _scriptConventions
                .GetDefaultAssemblies(_environment.ApplicationRoot)
                .Union(_referenceAssemblyResolver.GetReferenceAssemblies())
                .Select(a => FilePath.FromString(a.Location)));

            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(_scriptConventions.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);
        }