Beispiel #1
0
 /// <summary>
 /// Executes nuget restore for project
 /// </summary>
 /// <param name="project">Project to restore</param>
 private static void RestoreProjectDependencies(ProjectDescription project)
 {
     // restoring packages for project with respec to global configuration file
     Func<Unit, Unit> failFunc = u => u;
     var nugetPath = RestorePackageHelper.findNuget("./");
     RestorePackageHelper.runNuGet(
         nugetPath,
         TimeSpan.FromMinutes(10),
         $"restore {project.ProjectFileName} -ConfigFile ./nuget.config",
         failFunc.ToFSharpFunc());
 }
Beispiel #2
0
 /// <summary>
 /// Extracts project uid from project file
 /// </summary>
 /// <param name="project">The project description</param>
 /// <returns>The project's uid</returns>
 private static string GetProjectUid(ProjectDescription project)
 {
     var doc = new XmlDocument();
     doc.Load(project.ProjectFileName);
     XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable);
     namespaceManager.AddNamespace("def", "http://schemas.microsoft.com/developer/msbuild/2003");
     var uid =
         doc.DocumentElement?.SelectSingleNode("/def:Project/def:PropertyGroup/def:ProjectGuid", namespaceManager)?
             .InnerText;
     return uid;
 }
Beispiel #3
0
        /// <summary>
        /// Runs defined unit tests on all projects
        /// </summary>
        /// <param name="project">The project to test</param>
        public static void RunXUnitTest(ProjectDescription project)
        {
            if (!project.ProjectType.HasFlag(ProjectDescription.EnProjectType.XUnitTests))
            {
                return;
            }

            var testAssembly = Path.Combine(project.TempBuildDirectory, $"{project.ProjectName}.dll");

            var runnerLocation = Directory.GetDirectories(Path.Combine(Directory.GetCurrentDirectory(), "packages"))
                .OrderByDescending(d => d)
                .First();

            Func<XUnit2.XUnit2Params, XUnit2.XUnit2Params> testParameters = p =>
            {
                p.SetFieldValue("ToolPath", Path.Combine(runnerLocation, "tools", "xunit.console.exe"));
                p.SetFieldValue("ErrorLevel", UnitTestCommon.TestRunnerErrorLevel.DontFailBuild);
                p.SetFieldValue("TimeOut", TimeSpan.FromHours(8));
                p.SetFieldValue("ForceTeamCity", true);
                return p;
            };

            XUnit2.xUnit2(testParameters.ToFSharpFunc(), new[] { testAssembly });
        }
Beispiel #4
0
        /// <summary>
        /// Builds current project
        /// </summary>
        /// <param name="project">Project to build</param>
        public static void Build(ProjectDescription project)
        {
            var tempSrc = Path.Combine(Path.GetFullPath(BuildDirectory), "src");

            TraceHelper.trace($"Building {project.ProjectName}");

            if (Directory.Exists(project.TempBuildDirectory))
            {
                Directory.Delete(project.TempBuildDirectory, true);
            }

            if (Directory.Exists(project.CleanBuildDirectory))
            {
                Directory.Delete(project.CleanBuildDirectory, true);
            }

            if (Directory.Exists(tempSrc))
            {
                var attempt = 0;
                while (true)
                {
                    try
                    {
                        Directory.Delete(tempSrc, true);
                        continue;
                    }
                    catch (IOException)
                    {
                        ConsoleLog("Src directory is blocked. Retrying...");
                        attempt++;
                        Thread.Sleep(100);
                        if (attempt >= 10)
                        {
                            throw;
                        }
                    }

                    break;
                }
            }

            Directory.CreateDirectory(project.CleanBuildDirectory);
            Directory.CreateDirectory(project.TempBuildDirectory);

            RestoreProjectDependencies(project);

            Func<string, bool> filter = s => true;
            FileHelper.CopyDir(tempSrc, project.ProjectDirectory, filter.ToFSharpFunc());
            // ReSharper disable once AssignNullToNotNullAttribute
            var projectFileName = Path.Combine(tempSrc, Path.GetFileName(project.ProjectFileName));

            // modifying project file to substitute internal nute-through dependencies to currently built files
            var projDoc = new XmlDocument();
            projDoc.Load(projectFileName);

            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(projDoc.NameTable);
            namespaceManager.AddNamespace("def", "http://schemas.microsoft.com/developer/msbuild/2003");

            var rootNode = projDoc.DocumentElement;
            if (rootNode == null)
            {
                ConsoleLog($"Could not read xml from {projectFileName}");
                return;
            }

            var refItemGroup = rootNode.SelectSingleNode("//def:ItemGroup[def:Reference]", namespaceManager);

            foreach (var dependency in project.InternalDependencies)
            {
                var refNode =
                    rootNode.SelectNodes("//def:Reference", namespaceManager)
                        ?.Cast<XmlElement>()
                        .FirstOrDefault(
                            e =>
                            e.HasAttribute("Include")
                            && Regex.IsMatch(e.Attributes["Include"].Value, $"^{Regex.Escape(dependency)}((, )|$)"))
                    ?? rootNode.SelectNodes("//def:ProjectReference", namespaceManager)
                        ?.Cast<XmlElement>()
                        .FirstOrDefault(
                            e =>
                            e.HasAttribute("Include")
                            && Regex.IsMatch(e.Attributes["Include"].Value, $"(^|[\\\\\\/]){Regex.Escape(dependency)}.csproj$"));

                if (refNode == null)
                {
                    var projectReference = rootNode.SelectNodes("//def:ProjectReference", namespaceManager)?.Cast<XmlElement>().Where(e => e.HasAttribute("Include"));
                    if (projectReference != null)
                    {
                        foreach (var element in projectReference)
                        {
                            ConsoleLog($"Comparing {element.Attributes["Include"].Value} and {dependency}");
                        }
                    }
                }

                if (refNode != null)
                {
                    var libPath = Path.Combine(Path.GetFullPath(BuildClean), dependency, $"{dependency}.dll");
                    refNode.ParentNode?.RemoveChild(refNode);
                    refNode = projDoc.CreateElement("Reference", "http://schemas.microsoft.com/developer/msbuild/2003");
                    refItemGroup?.AppendChild(refNode);
                    refNode.SetAttribute("Include", dependency);
                    refNode.InnerXml = $"<SpecificVersion>False</SpecificVersion><HintPath>{libPath}</HintPath><Private>True</Private>";
                    ConsoleLog($"ref linked to {dependency} was updated");
                    if (!File.Exists(libPath))
                    {
                        ConsoleLog($"!!!!!{libPath} does not exist!!!!");
                    }
                }
                else
                {
                    ConsoleLog($"{dependency} ref node was not found");
                }
            }

            // todo: @kantora update NuGet package references in case of directory structure change
            ConsoleLog($"Writing modified {projectFileName}");
            projDoc.Save(projectFileName);

            var assemblyInfoPath = Path.Combine(
                tempSrc,
                "Properties",
                "AssemblyInfo.cs");

            var assemblyText = File.ReadAllText(assemblyInfoPath);
            assemblyText += $"\n[assembly: AssemblyMetadata(\"NugetVersion\", \"{Version?.Replace("\"", "\\\"")}\")]\n";
            assemblyText += $"\n[assembly: AssemblyMetadata(\"BuildDate\", \"{DateTimeOffset.Now.ToString("s")}\")]\n";

            var assemblyVersion = Regex.Replace(Version ?? "1.0.0.0", "((\\d\\.?)+)(.*)", "$1");

            assemblyText = Regex.Replace(assemblyText, "AssemblyVersion\\(\"([^\\)]+)\"\\)", $"AssemblyVersion(\"{assemblyVersion}\")");
            assemblyText = Regex.Replace(assemblyText, "AssemblyFileVersion\\(\"([^\\)]+)\"\\)", $"AssemblyFileVersion(\"{assemblyVersion}\")");
            File.WriteAllText(assemblyInfoPath, assemblyText);

            MSBuildHelper.MSBuildRelease(project.TempBuildDirectory, "Clean", new[] { projectFileName });
            MSBuildHelper.MSBuildRelease(project.TempBuildDirectory, "Build", new[] { projectFileName });

            Directory.CreateDirectory(project.CleanBuildDirectory);

            var extensions = new[] { "dll", "nuspec", "pdb", "xml", "exe", "dll.config", "exe.config", "fsx" };

            var buildFiles = Directory.GetFiles(project.TempBuildDirectory)
                .Where(f => extensions.Any(e => $"{project.ProjectName}.{e}".Equals(Path.GetFileName(f), StringComparison.InvariantCultureIgnoreCase)))
                .ToList();

            foreach (var fileName in buildFiles.Select(Path.GetFileName).Where(fileName => fileName != null))
            {
                ConsoleLog($"Copying {fileName}");
                File.Copy(
                    Path.Combine(project.TempBuildDirectory, fileName),
                    Path.Combine(project.CleanBuildDirectory, fileName));
            }

            Func<string, bool> alwaysTrue = f => true;

            foreach (var directory in Directory.GetDirectories(project.TempBuildDirectory).Select(Path.GetFileName))
            {
                ConsoleLog($"Copying localization {directory}");
                FileHelper.CopyDir(
                    Path.Combine(project.CleanBuildDirectory, directory),
                    Path.Combine(project.TempBuildDirectory, directory),
                    alwaysTrue.ToFSharpFunc());
            }

            if (buildFiles.Any(f => f.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) || f.EndsWith(".fsx", StringComparison.InvariantCultureIgnoreCase)))
            {
                var toolsDir = Path.Combine(project.CleanBuildDirectory, "tools");
                Directory.CreateDirectory(toolsDir);

                FileHelper.CopyDir(toolsDir, project.TempBuildDirectory, alwaysTrue.ToFSharpFunc());
            }

            TraceHelper.trace($"Build {project.ProjectName} finished");
        }
Beispiel #5
0
        /// <summary>
        /// Creates nuget package
        /// </summary>
        /// <param name="project">
        /// The project to publish
        /// </param>
        public static void CreateNuget(ProjectDescription project)
        {
            if (!project.ProjectType.HasFlag(ProjectDescription.EnProjectType.NugetPackage))
            {
                return;
            }

            TraceHelper.trace($"Packing {project.ProjectName}");

            var nuspecData = new XmlDocument();
            var nuspecDataFileName = $"{project.ProjectName}.nuspec";
            nuspecData.Load(Path.Combine(project.ProjectDirectory, nuspecDataFileName));
            // ReSharper disable PossibleNullReferenceException
            var metaData = nuspecData.DocumentElement.SelectSingleNode("/package/metadata");
            metaData.SelectSingleNode("id").InnerText = project.ProjectName;
            metaData.SelectSingleNode("version").InnerText = Version;
            metaData.SelectSingleNode("title").InnerText = project.ProjectName;

            if ("$author$".Equals(metaData.SelectSingleNode("authors").InnerText))
            {
                metaData.SelectSingleNode("authors").InnerText = "ClusterKit Team";
            }

            if ("$author$".Equals(metaData.SelectSingleNode("owners").InnerText))
            {
                metaData.SelectSingleNode("owners").InnerText = "ClusterKit Team";
            }

            if ("$description$".Equals(metaData.SelectSingleNode("description").InnerText))
            {
                metaData.SelectSingleNode("description").InnerText = "ClusterKit lib";
            }

            var dependenciesRootElement = metaData.AppendChild(nuspecData.CreateElement("dependencies"));
            var dependenciesDoc = new XmlDocument();
            dependenciesDoc.Load(Path.Combine(project.ProjectDirectory, "packages.config"));

            foreach (XmlElement dependency in dependenciesDoc.DocumentElement.SelectNodes("/packages/package"))
            {
                if (project.InternalDependencies.Contains(dependency.Attributes["id"].Value))
                {
                    continue;
                }

                if (!Directory.Exists(Path.Combine(PackageInputDirectory, $"{dependency.Attributes["id"].Value}.{dependency.Attributes["version"].Value}")))
                {
                    continue;
                }

                var dependencyElement = dependenciesRootElement.AppendChild(nuspecData.CreateElement("dependency"));
                dependencyElement.Attributes.Append(nuspecData.CreateAttribute("id")).Value =
                    dependency.Attributes["id"].Value;
                dependencyElement.Attributes.Append(nuspecData.CreateAttribute("version")).Value =
                    dependency.Attributes["version"].Value;
            }

            foreach (var dependency in project.InternalDependencies)
            {
                var dependencyElement = dependenciesRootElement.AppendChild(nuspecData.CreateElement("dependency"));
                dependencyElement.Attributes.Append(nuspecData.CreateAttribute("id")).Value =
                    dependency;
                dependencyElement.Attributes.Append(nuspecData.CreateAttribute("version")).Value = Version;
            }

            var filesRootElement = nuspecData.DocumentElement.SelectSingleNode("/package").AppendChild(nuspecData.CreateElement("files"));
            foreach (var file in Directory.GetFiles(project.CleanBuildDirectory))
            {
                var fileElement = filesRootElement.AppendChild(nuspecData.CreateElement("file"));
                fileElement.Attributes.Append(nuspecData.CreateAttribute("src")).Value = Path.GetFileName(file);
                fileElement.Attributes.Append(nuspecData.CreateAttribute("target")).Value = $"./lib/{Path.GetFileName(file)}";
            }

            foreach (var directory in Directory.GetDirectories(project.CleanBuildDirectory).Select(Path.GetFileName).Where(d => d != "tools"))
            {
                foreach (var file in Directory.GetFiles(Path.Combine(project.CleanBuildDirectory, directory)))
                {
                    var fileElement = filesRootElement.AppendChild(nuspecData.CreateElement("file"));
                    fileElement.Attributes.Append(nuspecData.CreateAttribute("src")).Value = Path.Combine(directory, Path.GetFileName(file));
                    fileElement.Attributes.Append(nuspecData.CreateAttribute("target")).Value = $"./lib/{directory}/{Path.GetFileName(file)}";
                }
            }

            var toolsDir = Path.Combine(project.CleanBuildDirectory, "tools");
            if (Directory.Exists(toolsDir))
            {
                foreach (var file in Directory.GetFiles(toolsDir))
                {
                    var fileElement = filesRootElement.AppendChild(nuspecData.CreateElement("file"));
                    fileElement.Attributes.Append(nuspecData.CreateAttribute("src")).Value = Path.Combine("tools", Path.GetFileName(file));
                    fileElement.Attributes.Append(nuspecData.CreateAttribute("target")).Value = $"./tools/{Path.GetFileName(file)}";
                }
            }

            var generatedNuspecFile = Path.Combine(project.CleanBuildDirectory, nuspecDataFileName);
            nuspecData.Save(generatedNuspecFile);

            if (!Directory.Exists(PackageOutputDirectory))
            {
                Directory.CreateDirectory(PackageOutputDirectory);
            }

            Func<NuGetHelper.NuGetParams, NuGetHelper.NuGetParams> provider = defaults =>
                {
                    defaults.SetFieldValue("Version", Version);
                    defaults.SetFieldValue("WorkingDir", project.CleanBuildDirectory);
                    defaults.SetFieldValue("OutputPath", PackageOutputDirectory);
                    return defaults;
                };

            Fake.NuGetHelper.NuGetPackDirectly(provider.ToFSharpFunc(), generatedNuspecFile);

            // ReSharper restore PossibleNullReferenceException
        }