/// <summary>
        /// Adds the copy ressources information.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <param name="coreOptions">The core options.</param>
        /// <param name="uniqueOutputPath">if set to <c>true</c> [unique output path].</param>
        /// <returns></returns>
        private string AddCopyRessourcesInformation(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions, bool uniqueOutputPath)
        {
            var buildBuilder = new StringBuilder();
            var folder = project.GetRelativeFolderPath(coreOptions);

            foreach (var currentRessource in _ressourceFinder.ExtractRessourcesFromProject(project.Path))
            {
                if (!string.IsNullOrEmpty(currentRessource))
                {
                    string temp;

                    if (!uniqueOutputPath)
                    {
                        // In a non web project, we look in the configuration folder, otherwise in the bin folder
                        if (!project.IsWebProject)
                            temp = string.Format("{0}\\bin\\$(Configuration)\\{1}\\{2}.resources.dll", folder, currentRessource, project.AssemblyName);
                        else
                            temp = string.Format("{0}\\bin\\{1}\\{2}.resources.dll", folder, currentRessource, project.AssemblyName);
                    }
                    else
                        temp = string.Format("(UniqueOutputPath)\\{0}\\{1}.resources.dll", currentRessource, project.AssemblyName);

                    buildBuilder.AppendFormat("		<Copy SourceFiles=\"{0}\" DestinationFolder=\"$(DestinationFolder)\\{1}\" Condition=\"Exists('{0}') AND $(CopyEnabled) AND $(CopyRessources)\" ContinueOnError=\"$(ContinueOnError)\" OverwriteReadOnlyFiles=\"True\" SkipUnchangedFiles=\"True\" />", temp, currentRessource);
                    buildBuilder.AppendLine();
                }
            }

            return buildBuilder.ToString();
        }
        /// <summary>
        /// Call when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
        /// </summary>
        /// <param name="project">The project that is being visited for build</param>
        /// <param name="coreOptions">The application core options</param>
        /// <returns>
        /// The msbuild syntax to add to the build file
        /// </returns>
        public override string VisitBuildAllTypeTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            var buildBuilder = new StringBuilder();

            buildBuilder.AppendLine(AddCopyRessourcesInformation(project, coreOptions, false));

            return buildBuilder.ToString();
        }
        /// <summary>
        /// Build the dependency graph between the projects in the root folder and optionnaly save the graph in a GraphML file
        /// </summary>
        /// <param name="coreOptions">
        /// The coreOptions used to get the dependency order of the projects
        /// </param>
        /// <returns>
        /// The list of <see cref="VisualStudioProject"/> in the correct build order
        /// </returns>
        public List<VisualStudioProject> GetDependencyOrder(IMsBuilderificCoreOptions coreOptions)
        {
            var graph = GetDependencyGraph(coreOptions);

            if (!string.IsNullOrEmpty(coreOptions.GraphFilename))
                PersistGraph(graph, coreOptions);

            return GetDependencyOrderFromGraph(graph);
        }
        /// <summary>
        /// Call for web project when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
        /// </summary>
        /// <param name="project">The project that is being visited for build</param>
        /// <param name="coreOptions">The application core options</param>
        /// <returns>
        /// The msbuild syntax to add to the build file
        /// </returns>
        public override string VisitBuildWebProjectTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            var buildBuilder = new StringBuilder();

            _options.Transforms.ForEach(t => buildBuilder.AppendLine(AddCopyPackagesInformation(project, coreOptions, false, t)));
            
            buildBuilder.AppendLine(AddCopyPackagesInformation(project, coreOptions, false));

            return buildBuilder.ToString();
        }
        /// <summary>
        /// Call for web project when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
        /// </summary>
        /// <param name="project">The project that is being visited for build</param>
        /// <param name="coreOptions">The application core options</param>
        /// <returns>
        /// The msbuild syntax to add to the build file
        /// </returns>
        public override string VisitBuildWebProjectTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            var buildCommand = new StringBuilder();

            buildCommand.AppendLine(String.Format("		<MSBuild Properties=\"Configuration=$(Configuration);Platform=$(PlatformConfig);DefineConstants=THREAD_STATIC_CONTAINER\" Projects=\"{0}\" Targets=\"Build\" StopOnFirstFailure=\"True\" ContinueOnError=\"$(ContinueOnError)\" UnloadProjectsOnCompletion=\"$(UnloadProjectsOnCompletion)\" UseResultsCache=\"$(UseResultsCache)\" >", project.GetRelativeFilePath(coreOptions)));
            buildCommand.AppendLine(string.Format("			<Output TaskParameter=\"TargetOutputs\" ItemName=\"ProjectArtefacts\"/>"));
            buildCommand.AppendLine(string.Format("		</MSBuild>"));

            return buildCommand.ToString();
        }
Beispiel #6
0
        private static List<VisualStudioProject> GetBuildOder(IMsBuilderificCoreOptions options)
        {
            var finder = Injection.Engine.Resolve<IProjectDependencyFinder>();

            if (options.ProjectDetectionExclusionPatterns != null)
            {
                foreach (var exclusion in options.ProjectDetectionExclusionPatterns)
                    finder.AddExclusionPattern(exclusion);
            }

            return finder.GetDependencyOrder(options);
        }
        /// <summary>
        /// Call for program projects (exe) when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
        /// </summary>
        /// <param name="project">The project that is being visited for build</param>
        /// <param name="coreOptions">The application core options</param>
        /// <returns>
        /// The msbuild syntax to add to the build file
        /// </returns>
        public override string VisitBuildExeProjectTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            var packageCommand = new StringBuilder();
            var folder = project.GetRelativeFolderPath(coreOptions);
            var filename = project.GetRelativeFilePath(coreOptions);

            var packagingCondition = string.Format("Condition=\"$(GenerateMsDeployPackages) AND Exists('{0}\\bin') \" ", folder);                

            packageCommand.AppendLine(string.Format("		<MakeDir Directories=\"$(MSBuildProjectDirectory)\\{0}\\bin\\Packages\\$(Configuration)\\\" {1} />", folder, packagingCondition));
            packageCommand.AppendLine(String.Format("		<Exec Command='\"$(MsDeployLocation)\" -verb:sync -source:contentPath=\"$(MSBuildProjectDirectory)\\{0}\" -dest:package=\"$(MSBuildProjectDirectory)\\{0}\\bin\\Packages\\$(Configuration)\\{1}.zip\" -skip:objectName=filePath,absolutePath=\".*\\.vb|cache.*\" -skip:objectName=dirPath,absolutePath=\"obj\" -skip:objectName=dirPath,absolutePath=\"_Resharper\" -skip:objectName=dirPath,absolutePath=\"Packages\" -skip:xpath=\"//dirPath[count(*)=0]\" -skip:objectName=dirPath,absolutePath=\"_PublishedWebsites\" ' {2} />", folder, Path.GetFileNameWithoutExtension(filename), packagingCondition));

            return packageCommand.ToString();
        }
        /// <summary>
        /// Called just after the build operation on the <paramref name="project"/>
        /// </summary>
        /// <param name="project">The project that was visited for build</param>
        /// <param name="coreOptions">The application core options</param>
        /// <returns>
        /// The msbuild syntax to add to the build file
        /// </returns>
        public override string PostVisitBuildTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            var deleteBinBuilder = new StringBuilder();

            var folder = project.GetRelativeFolderPath(coreOptions);

            if (!project.IsWebProject)
                deleteBinBuilder.AppendLine(string.Format("		<RemoveDir Directories=\"{0}\\bin\\$(Configuration)\" Condition=\"$(GenerateMsDeployPackages)\" />", folder));
            else
                deleteBinBuilder.AppendLine(string.Format("		<RemoveDir Directories=\"{0}\\bin\" Condition=\"$(GenerateMsDeployPackages)\" />", folder));

            return deleteBinBuilder.ToString();
        }
        public override string VisitCleanTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            var cleanBuilder = new StringBuilder();

            cleanBuilder.AppendLine(String.Format("		<CleanedFiles Include=\"\\\\?\\$(MSBuildProjectDirectory)\\{0}\\bin\\**;\\\\?\\{0}\\obj\\**;\" />", project.GetRelativeFolderPath(coreOptions)));

            if (!string.IsNullOrEmpty(_options.CopyOutputTo))
                cleanBuilder.AppendLine(String.Format("		<CleanedFiles Include=\"\\\\?\\$(DestinationFolder)\\**\\{0}*\" />", Path.GetFileNameWithoutExtension(project.GetRelativeFilePath(coreOptions))));

            if(project.IsWebProject)
                cleanBuilder.AppendLine(String.Format("		<CleanedServicesFiles Include=\"\\\\?\\$(MSBuildProjectDirectory)\\{0}\\bin\\**;\\\\?\\{0}\\obj\\**;\" />", project.GetRelativeFolderPath(coreOptions)));

            return cleanBuilder.ToString();
        }
        public static string GetRelativeFilePath(this VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            if (project == null)
                throw new ArgumentNullException("project", "The project cannot be null");

            if (!String.IsNullOrEmpty(project.Path))
            {
                var folder = GetRelativeFolderPath(project, coreOptions);
                if (!String.IsNullOrEmpty(folder))
                    return Path.Combine(folder, Path.GetFileName(project.Path));

                return Path.GetFileName(project.Path);
            }

            throw new ArgumentException("The project path is empty or null");
        }
        /// <summary>
        /// Call for project library when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
        /// </summary>
        /// <param name="project">The project that is being visited for build</param>
        /// <param name="coreOptions">The application core options</param>
        /// <returns>
        /// The msbuild syntax to add to the build file
        /// </returns>
        public override string VisitBuildLibraryProjectTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            if (Regex.IsMatch(project.AssemblyName, _options.TestDiscoveryPattern))
            {
                var builder = new StringBuilder();
                if (string.IsNullOrEmpty(_options.GlobalTestSettings))
                    builder.AppendLine(string.Format("		<Exec Command='\"$(MsTestLocation)\" /testcontainer:{0}\\$(TestBinFolder)\\{1}.dll /category:\"$(MsTestCategories)\" /usestderr /detail:errormessage /detail:errorstacktrace /resultsfile:\"{1}\".trx' ContinueOnError=\"$(ContinueOnTestError)\" Condition=\"$(ExecuteTests)\" />", project.GetRelativeFolderPath(coreOptions), project.AssemblyName));                
                else
                    builder.AppendLine(string.Format("		<Exec Command='\"$(MsTestLocation)\" /testcontainer:{0}\\$(TestBinFolder)\\{1}.dll /runconfig:\"{2}\" /category:\"$(MsTestCategories)\" /usestderr /detail:errormessage /detail:errorstacktrace/resultsfile:\"{1}\".trx' ContinueOnError=\"$(ContinueOnTestError)\" Condition=\"$(ExecuteTests)\" />", project.GetRelativeFolderPath(coreOptions), project.AssemblyName, _options.GlobalTestSettings));

                if(_options.GenerateTeamCityTransactionMessage)
                    builder.AppendLine(string.Format("<Message Text=\"##teamcity[importData type='mstest' path='{0}.trx']\"/>", project.AssemblyName));

                return builder.ToString();
            }

            return null;
        }
        /// <summary>
        /// Call for project library when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
        /// </summary>
        /// <param name="project">The project that is being visited for build</param>
        /// <param name="coreOptions">The application core options</param>
        /// <returns>
        /// The msbuild syntax to add to the build file
        /// </returns>
        public override string VisitBuildLibraryProjectTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            var buildCommand = new StringBuilder();

            //ExecuteTests
            string condition = null;
            if(project.IsTestProject)
                condition = "Condition=\"$(BuildTestProjects)\"";
            
            string customOutputPath = null;
            if (!string.IsNullOrEmpty(_options.MsBuildFileOuputPath))
                customOutputPath = "OutputPath=$(OutputPath)";

            buildCommand.AppendLine(String.Format("		<MSBuild Properties=\"Configuration=$(Configuration);Platform=$(PlatformConfig);{0}\" Projects=\"{1}\" Targets=\"$(Action)\" StopOnFirstFailure=\"True\" ContinueOnError=\"$(ContinueOnError)\" UnloadProjectsOnCompletion=\"$(UnloadProjectsOnCompletion)\" UseResultsCache=\"$(UseResultsCache)\" {2} >", customOutputPath, project.GetRelativeFilePath(coreOptions), condition));
            buildCommand.AppendLine(string.Format("			<Output TaskParameter=\"TargetOutputs\" ItemName=\"ProjectArtefacts\"/>"));
            buildCommand.AppendLine(string.Format("		</MSBuild>"));

            return buildCommand.ToString();
        }
        public static string GetRelativeFolderPath(this VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            if (project == null)
                throw new ArgumentNullException("project", "The project cannot be null");

            if (coreOptions == null)
                throw new ArgumentNullException("coreOptions", "The coreOptions are mandatory to get the relative file path");

            var folder = Directory.GetParent(project.Path).FullName;

            if (!string.IsNullOrEmpty(coreOptions.RelativeToPath))
            {
                var relativePath = Directory.GetParent(project.Path).FullName.Replace(coreOptions.RelativeToPath, "");
                while (relativePath.StartsWith("\\"))
                    relativePath = relativePath.Substring(1);
                folder = relativePath;
            }

            return folder;
        }
        /// <summary>
        /// Call for web project when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
        /// </summary>
        /// <param name="project">The project that is being visited for build</param>
        /// <param name="coreOptions">The application core options</param>
        /// <returns>
        /// The msbuild syntax to add to the build file
        /// </returns>
        public override string VisitBuildWebProjectTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            var packageCommand = new StringBuilder();
            var folder = project.GetRelativeFolderPath(coreOptions);

            if (_options.Transforms != null && _options.Transforms.Count > 0)
            {
                _options.Transforms.ForEach(t =>
                                               {
                                                   packageCommand.AppendLine(string.Format("		<Delete Files=\"$(MSBuildProjectDirectory)\\{0}\\web.temp.{1}.config\" Condition=\"$(GenerateMsDeployPackages) AND Exists('{0}\\web.temp.{1}.config')\" />", folder, t));
                                                   packageCommand.AppendLine(string.Format("		<Copy SourceFiles=\"$(MSBuildProjectDirectory)\\{0}\\web.config\" DestinationFiles=\"$(MSBuildProjectDirectory)\\{0}\\web.temp.{1}.config\" Condition=\"$(GenerateMsDeployPackages) AND Exists('{0}\\web.{1}.config')\" />", folder, t));
                                                   packageCommand.AppendLine(string.Format("		<TransformXml Source=\"$(MSBuildProjectDirectory)\\{0}\\web.temp.{1}.config\" Transform=\"$(MSBuildProjectDirectory)\\{0}\\web.{1}.config\" Destination=\"$(MSBuildProjectDirectory)\\{0}\\web.transformed.{1}.config\" Condition=\"$(GenerateMsDeployPackages) AND Exists('{0}\\web.{1}.config')\" />", folder, t));
                  
                                                   packageCommand.AppendLine(GetMsDeployCommand(project, coreOptions, t, true));
                                               });
            }

            packageCommand.AppendLine(GetMsDeployCommand(project, coreOptions));

            return packageCommand.ToString();     
        }
        /// <summary>
        /// Call when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
        /// </summary>
        /// <param name="project">The project that is being visited for build</param>
        /// <param name="coreOptions">The application core options</param>
        /// <returns>
        /// The msbuild syntax to add to the build file
        /// </returns>
        public override string VisitBuildAllTypeTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
        {
            var buildBuilder = new StringBuilder();

            var extensions = new List<String>();
            
            if(_options.CopyConfig)
                extensions.Add("config");

            if(_options.CopyXml)
                extensions.Add("xml");

            if (_options.CopyRessources)
            {
                extensions.Add("ressources");
                extensions.Add("resx");
            }
            
            if (project.OutputType == ProjectOutputType.Exe.ToString() || project.OutputType == ProjectOutputType.WinExe.ToString())
            {
                if (_options.CopyExe)
                    extensions.Add("exe");
            }
            else
            {
                if(_options.CopyDll)
                    extensions.Add("dll");
            }

            if (_options.CopyPdbs)
                extensions.Add("pdb");

            foreach (var ext in extensions)
            {
                var capitalizedExt = char.ToUpper(ext[0]) + ext.Substring(1);
                buildBuilder.AppendLine(AddCopyInformation(project, coreOptions, capitalizedExt, false));
            }

            return buildBuilder.ToString();
        }
        /// <summary>
        /// Saves the graph in the GraphML format in the specified filename
        /// </summary>
        /// <param name="graph">
        /// The graph to persist
        /// </param>
        /// <param name="options">
        /// The core options used to get information about the graph to generate
        /// </param>
        public void PersistGraph(AdjacencyGraph<VisualStudioProject, Edge<VisualStudioProject>> graph, IMsBuilderificCoreOptions options)
        {
            using (var xwriter = XmlWriter.Create(options.GraphFilename))
                graph.SerializeToGraphML<VisualStudioProject, Edge<VisualStudioProject>, AdjacencyGraph<VisualStudioProject, Edge<VisualStudioProject>>>(xwriter, s => s.AssemblyName, e => String.Format("{0} depends on {1}", e.Source.AssemblyName, e.Target.AssemblyName));

        }
        /// <summary>
        /// Build the dependency graph from the projects found in the root folder - the exlusion patterns
        /// </summary>
        /// <param name="coreOptions">
        /// The coreOptions used to get the dependency order of the projects
        /// </param>
        /// <returns>
        /// A graph representing the dependencies between the projects in the root folder
        /// </returns>
        public AdjacencyGraph<VisualStudioProject, Edge<VisualStudioProject>> GetDependencyGraph(IMsBuilderificCoreOptions coreOptions)
        {
            if (!Directory.Exists(coreOptions.RootFolder))
                throw new ArgumentException(string.Format("Le répertoire source est inexistant : {0}", coreOptions.RootFolder), "rootFolder");

            var graph = new AdjacencyGraph<VisualStudioProject, Edge<VisualStudioProject>>();

            var projects = Directory.GetFiles(coreOptions.RootFolder, "*.*proj", SearchOption.AllDirectories);
            if (coreOptions.CSharpSupport && coreOptions.VbNetSupport)
                projects = projects.Where(s => s.EndsWith(".vbproj") || s.EndsWith(".csproj")).ToArray();
            else if (coreOptions.CSharpSupport)
                projects = projects.Where(s => s.EndsWith(".csproj")).ToArray();
            else if (coreOptions.VbNetSupport)
                projects = projects.Where(s => s.EndsWith(".vbproj")).ToArray();
            else 
                projects = new string[]{};

            var projs = projects.Where(f => !_excludedPatterns.Any(f.Contains));

            foreach (var projectFile in projs)
            { 
                var currentProjectFile = projectFile;

                // Get all instances from supported project parser, and retrieve the only one that can work
                var projectInstance = _projectLoader.Select(pl =>
                {
                    VisualStudioProject result;
                    pl.TryParse(currentProjectFile, out result);
                    return result;
                }).SingleOrDefault(s => s != null);

                graph.AddVertex(projectInstance);
            }

            foreach (var v in graph.Vertices)
            {
                foreach (var dep in v.Dependencies)
                {
                    var dependence = dep;
                    var target = graph.Vertices.SingleOrDefault(x => x.AssemblyName == dependence);

                    if (target != null)
                        graph.AddVerticesAndEdge(new Edge<VisualStudioProject>(v, target));
                }
            }

            return graph;
        }
 /// <summary>
 /// Get a value indicating whether or not the visitor should execute, based on the core options specified
 /// </summary>
 /// <param name="coreOptions">The application core options</param>
 /// <returns>
 ///   <c>true</c> if the visitor shall be called, <c>false</c> otherwise
 /// </returns>
 public override bool ShallExecute(IMsBuilderificCoreOptions coreOptions)
 {
     return _options.GenerateMsTestTask && !string.IsNullOrEmpty(_options.TestDiscoveryPattern);
 }
 /// <summary>
 /// Called when it is time to add build specific instructions for a <paramref name="project"/> that contains WCF services
 /// </summary>
 /// <param name="project">The project that will be visited for build for the specific Service target</param>
 /// <param name="coreOptions">The application core options</param>
 /// <returns>
 /// The msbuild syntax to add to the build file
 /// </returns>
 public override string VisitServiceTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
 {
     // Building a web service and a web project is the same
     return VisitBuildWebProjectTarget(project, coreOptions);
 }
 /// <summary>
 /// Get a value indicating whether or not the visitor should execute, based on the core options specified
 /// </summary>
 /// <param name="coreOptions">The application core options</param>
 /// <returns>
 ///   <c>true</c> if the visitor shall be called, <c>false</c> otherwise
 /// </returns>
 public override bool ShallExecute(IMsBuilderificCoreOptions coreOptions)
 {
     return coreOptions == null || !string.IsNullOrEmpty(_options.CopyOutputTo);
 }
 /// <summary>
 /// Get a value indicating whether or not the visitor should execute, based on the core options specified
 /// </summary>
 /// <param name="coreOptions">The application core options</param>
 /// <returns>
 ///   <c>true</c> if the visitor shall be called, <c>false</c> otherwise
 /// </returns>
 public override bool ShallExecute(IMsBuilderificCoreOptions coreOptions)
 {
     return _options.GeneratePackagesOnBuild;
 }
        /// <summary>
        /// Gets the ms deploy command.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <param name="coreOptions">The core options.</param>
        /// <param name="configuration">The configuration.</param>
        /// <param name="isTransform">if set to <c>true</c> [is transform].</param>
        /// <returns></returns>
        private string GetMsDeployCommand(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions, string configuration = "$(Configuration)", bool isTransform = false)
        {
            var packageCommand = new StringBuilder();
            var folder = project.GetRelativeFolderPath(coreOptions);
            var filename = project.GetRelativeFilePath(coreOptions);
            var regExParamEntry = string.Format(".+\\\\{0}", Regex.Escape(folder));

            string conditions ;
            if(isTransform)
                conditions = string.Format("Condition=\"$(GenerateMsDeployPackages) AND Exists('{0}\\web.{1}.config')\"", folder, configuration);
            else
                conditions = string.Format("Condition=\"$(GenerateMsDeployPackages) AND Exists('{0}\\bin')\"", folder);

            packageCommand.AppendLine(string.Format("		<MakeDir Directories=\"$(MSBuildProjectDirectory)\\{0}\\bin\\Packages\\{1}\\\" {2} />", folder, configuration, conditions));
            string skipWebConfig = null;
            if (isTransform)
            {
                var assemblyNameEscaped = Regex.Escape(string.Format("{0}\\{1}", project.AssemblyName, "web.config"));
                skipWebConfig = string.Format("-skip:objectname=filepath,absolutepath=\"{0}\" -replace:objectName=filepath,scopeAttributeName=path,match=web.transformed.{1}.config,replace=web.config", assemblyNameEscaped, configuration);
            }
            packageCommand.AppendLine(String.Format("		<Exec Command='\"$(MsDeployLocation)\" -verb:sync -source:iisApp=\"$(MSBuildProjectDirectory)\\{0}\" -dest:package=\"$(MSBuildProjectDirectory)\\{0}\\bin\\Packages\\{1}\\{2}.zip\" -declareParam:name=\"IIS Web Application Name\",value=\"{2}\",tags=IisApp,kind=ProviderPath,scope=IisApp,match=\"{3}\" {4} -skip:objectName=filePath,absolutePath=\".*\\.vb$|pdb$\" -skip:objectName=dirPath,absolutePath=\"obj|_Resharper|Packages|_PublishedWebsites\" ' {5} />", folder, configuration, Path.GetFileNameWithoutExtension(filename), regExParamEntry, skipWebConfig, conditions));

            return packageCommand.ToString();     
        }
 /// <summary>
 /// Call for program projects (exe) when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
 /// </summary>
 /// <param name="project">The project that is being visited for build</param>
 /// <param name="coreOptions">The application core options</param>
 /// <returns>
 /// The msbuild syntax to add to the build file
 /// </returns>
 public virtual string VisitBuildExeProjectTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
 {
     return null;
 }
 /// <summary>
 /// Called just before adding specific instructions for a <paramref name="project"/> that contains WCF services
 /// </summary>
 /// <param name="project">The project that will be visited for build for the specific Service target</param>
 /// <param name="coreOptions">The application core options</param>
 /// <returns>
 /// The msbuild syntax to add to the build file
 /// </returns>
 public virtual string PreVisitServiceTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
 {
     return null;
 }
        /// <summary>
        /// Adds the copy information.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <param name="coreOptions">The core options.</param>
        /// <param name="capitalizedExt">The capitalized ext.</param>
        /// <param name="uniqueOutputPath">if set to <c>true</c> [unique output path].</param>
        /// <returns></returns>
        private string AddCopyInformation(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions, string capitalizedExt, bool uniqueOutputPath)
        {
            var buildBuilder = new StringBuilder();
            var folder = project.GetRelativeFolderPath(coreOptions);

            if (!uniqueOutputPath)
            {
                // In a non web project, we look in the configuration folder, otherwise in the bin folder
                string temp;
                if (!project.IsWebProject)
                    temp = string.Format("{0}\\bin\\$(Configuration)\\{1}.{2}", folder, project.AssemblyName, capitalizedExt.ToLower());
                else
                    temp = string.Format("{0}\\bin\\{1}.{2}", folder, project.AssemblyName, capitalizedExt.ToLower());

                buildBuilder.AppendFormat("		<Copy SourceFiles=\"{0}\" DestinationFolder=\"$(DestinationFolder)\" Condition=\"Exists('{0}') AND $(CopyEnabled) AND $(Copy{1})\" ContinueOnError=\"$(ContinueOnError)\" OverwriteReadOnlyFiles=\"True\" SkipUnchangedFiles=\"True\" />", temp, capitalizedExt);
                buildBuilder.AppendLine();

                if (_options.CopyCodeContracts)
                {
                    if (!project.IsWebProject)
                        temp = string.Format("{0}\\bin\\$(Configuration)\\CodeContracts\\{1}.Contracts.{2}", folder, project.AssemblyName, capitalizedExt.ToLower());
                    else
                        temp = string.Format("{0}\\bin\\CodeContracts\\{1}.Contracts.{2}", folder, project.AssemblyName, capitalizedExt.ToLower());

                    buildBuilder.AppendFormat("		<Copy SourceFiles=\"{0}\" DestinationFolder=\"$(DestinationFolder)\\CodeContracts\" Condition=\"Exists('{0}') AND $(CopyEnabled) AND $(Copy{1}) AND $(CopyCodeContracts)\" ContinueOnError=\"$(ContinueOnError)\" OverwriteReadOnlyFiles=\"True\" SkipUnchangedFiles=\"True\" />", temp, capitalizedExt);
                }

                buildBuilder.AppendLine();
            }

            return buildBuilder.ToString();
        }
        /// <summary>
        /// Generates a build script from the projects' dependency order
        /// </summary>
        /// <param name="dependencyOrder">
        /// The order in which the MsBuildScript shall be generated
        /// </param>
        /// <param name="coreOptions">The coreOptions that will be passed to the visitors</param>
        public void WriteBuildScript(List<VisualStudioProject> dependencyOrder, IMsBuilderificCoreOptions coreOptions)
        {
            if (dependencyOrder == null)
                return;

            var cleanStringBuilder = new StringBuilder();
            var buildStringBuilder = new StringBuilder();
            var preBuildStringBuilder = new StringBuilder();
            var postBuildStringBuilder = new StringBuilder();            
            var serviceStringBuilder = new StringBuilder();
            var preServiceStringBuilder = new StringBuilder();
            var postServiceStringBuilder = new StringBuilder();
            
            var properties = GetVisitorsProperties();

            foreach (var vsnetProject in dependencyOrder)
            {
                if (vsnetProject == null)
                    continue;

                var currentVisualStudioProject = vsnetProject;

                var sortedVisitors = _visitors.OrderBy(s => s.Order);
                sortedVisitors.ToList().ForEach(v =>
                                      {
                                          if (v == null || !v.ShallExecute(coreOptions))
                                              return;                                          

                                          cleanStringBuilder.AppendLine(v.PreVisitCleanTarget(currentVisualStudioProject, coreOptions));
                                          cleanStringBuilder.AppendLine(v.VisitCleanTarget(currentVisualStudioProject, coreOptions));
                                          cleanStringBuilder.AppendLine(v.PostVisitCleanTarget(currentVisualStudioProject, coreOptions));

                                          preBuildStringBuilder.AppendLine(v.PreVisitBuildTarget(currentVisualStudioProject, coreOptions));
                                          if (currentVisualStudioProject.IsWebProject)
                                              buildStringBuilder.AppendLine(v.VisitBuildWebProjectTarget(currentVisualStudioProject, coreOptions));
                                          else if (currentVisualStudioProject.OutputType != ProjectOutputType.Library.ToString())
                                              buildStringBuilder.AppendLine(v.VisitBuildExeProjectTarget(currentVisualStudioProject, coreOptions));
                                          else
                                              buildStringBuilder.AppendLine(v.VisitBuildLibraryProjectTarget(currentVisualStudioProject, coreOptions));
                                          
                                          buildStringBuilder.AppendLine(v.VisitBuildAllTypeTarget(currentVisualStudioProject, coreOptions));
                                          
                                          postBuildStringBuilder.AppendLine(v.PostVisitBuildTarget(currentVisualStudioProject, coreOptions));

                                          if (coreOptions.GenerateSpecificTargetForWebProject && currentVisualStudioProject.IsWebProject)
                                          {
                                              preServiceStringBuilder.AppendLine(v.PreVisitServiceTarget(currentVisualStudioProject, coreOptions));
                                              serviceStringBuilder.AppendLine(v.VisitServiceTarget(currentVisualStudioProject, coreOptions));
                                              postServiceStringBuilder.AppendLine(v.PostVisitServiceTarget(currentVisualStudioProject, coreOptions));
                                          }
                                      });                              
            }

            buildStringBuilder.Insert(0, preBuildStringBuilder.ToString());
            buildStringBuilder.Append(postBuildStringBuilder);

            serviceStringBuilder.Insert(0, preServiceStringBuilder.ToString());
            serviceStringBuilder.Append(postServiceStringBuilder);
            
            var clean = Regex.Replace(cleanStringBuilder.ToString(), @"(?m)^[ \t]*\r?\n", string.Empty, RegexOptions.Multiline);
            var build = Regex.Replace(buildStringBuilder.ToString(), @"(?m)^[ \t]*\r?\n", string.Empty, RegexOptions.Multiline);
            var service = Regex.Replace(serviceStringBuilder.ToString(), @"(?m)^[ \t]*\r?\n", string.Empty, RegexOptions.Multiline);

            var propertiesBuilder = new StringBuilder();
            foreach(var property in properties)
                propertiesBuilder.AppendLine(string.Format("        <{0}>{1}</{0}>", property.Key, property.Value));

            var output = string.Format(Properties.Resources.msbuildtemplate, propertiesBuilder.ToString(), clean, build, service);

            File.WriteAllText(coreOptions.MsBuildOutputFilename, output);
        }
 /// <summary>
 /// Called when it is time to add build specific instructions for a <paramref name="project"/> that contains WCF services
 /// </summary>
 /// <param name="project">The project that will be visited for build for the specific Service target</param>
 /// <param name="coreOptions">The application core options</param>
 /// <returns>
 /// The msbuild syntax to add to the build file
 /// </returns>
 public override string VisitServiceTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
 {
     return VisitBuildAllTypeTarget(project, coreOptions);
 }
 /// <summary>
 /// Call for program projects (exe) when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
 /// </summary>
 /// <param name="project">The project that is being visited for build</param>
 /// <param name="coreOptions">The application core options</param>
 /// <returns>
 /// The msbuild syntax to add to the build file
 /// </returns>
 public override string VisitBuildExeProjectTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
 {
     // Same logic for exe and library projects, defaults to same implementation
     return VisitBuildLibraryProjectTarget(project, coreOptions);
 }
        /// <summary>
        /// Adds the copy packages information.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <param name="coreOptions">The core options.</param>
        /// <param name="uniqueOutputPath">if set to <c>true</c> [unique output path].</param>
        /// <param name="configuration">The configuration.</param>
        /// <returns></returns>
        private static string AddCopyPackagesInformation(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions, bool uniqueOutputPath, string configuration = "$(Configuration)")
        {
            var buildBuilder = new StringBuilder();
            var folder = project.GetRelativeFolderPath(coreOptions);
            string temp;
            string command;

            if (!uniqueOutputPath)
            {
                temp = string.Format("{0}\\bin\\Packages\\{1}\\{2}.zip", folder, configuration, project.AssemblyName);
                command = string.Format("		<Move SourceFiles=\"{0}\" DestinationFolder=\"$(DestinationFolder)\\Packages\\{1}\" Condition=\"Exists('{0}') AND $(GenerateMsDeployPackages)\" ContinueOnError=\"$(ContinueOnError)\" />", temp, configuration);
            }
            else
            {
                temp = string.Format("(UniqueOutputPath)\\Packages\\{0}\\{1}.zip", configuration, project.AssemblyName);
                command = string.Format("		<Move SourceFiles=\"{0}\" DestinationFolder=\"$(DestinationFolder)\\Packages\\{1}\" Condition=\"Exists('{0}') AND $(GenerateMsDeployPackages)\" ContinueOnError=\"$(ContinueOnError)\" />", temp, configuration);
            }

            buildBuilder.AppendLine(command);

            return buildBuilder.ToString();
        }
 /// <summary>
 /// Call for program projects (exe) when it is time to add build information to the build file for the <paramref name="project"/>, for each possible targets
 /// </summary>
 /// <param name="project">The project that is being visited for build</param>
 /// <param name="coreOptions">The application core options</param>
 /// <returns>
 /// The msbuild syntax to add to the build file
 /// </returns>
 public override string VisitBuildExeProjectTarget(VisualStudioProject project, IMsBuilderificCoreOptions coreOptions)
 {
     return VisitBuildWebProjectTarget(project, coreOptions);
 }