/// <summary> /// Finalizes the changelog by moving all entries from `[vNext]` to the version specified by release. /// <p>If <paramref name="repository"/> is specified a summary with all versions and links to list the changes directly on GitHub is appended to the end of the changelog.</p> /// </summary> /// <param name="changelogFile">The path to the changelog file.</param> /// <param name="tag">The version to finalize the changelog.</param> /// <param name="repository">The repository to create the version overview for.</param> /// <seealso cref="FinalizeChangelog(ChangeLog,NuGetVersion,GitRepository)"/> public static void FinalizeChangelog(string changelogFile, string tag, [CanBeNull] GitRepository repository = null) { Logger.Info($"Finalizing {PathConstruction.GetRelativePath(NukeBuild.RootDirectory, changelogFile)} for '{tag}'..."); var content = TextTasks.ReadAllLines(changelogFile).ToList(); var sections = GetReleaseSections(content).ToList(); var firstSection = sections.First(); var secondSection = sections.Skip(1).FirstOrDefault(); ControlFlow.Assert(firstSection.Caption.All(char.IsLetter), "Cannot find a draft section."); ControlFlow.Assert(sections.All(x => !x.Caption.EqualsOrdinalIgnoreCase(tag)), $"Tag '{tag}' already exists."); ControlFlow.Assert(firstSection.EndIndex > firstSection.StartIndex, $"Draft section '{firstSection.Caption}' does not contain any information."); ControlFlow.Assert(secondSection == null || NuGetVersion.Parse(tag).CompareTo(NuGetVersion.Parse(secondSection.Caption)) > 0, $"Tag '{tag}' is not greater compared to last tag '{secondSection?.Caption}'."); content.Insert(firstSection.StartIndex + 1, string.Empty); content.Insert(firstSection.StartIndex + 2, $"## [{tag}] / {DateTime.Now:yyyy-MM-dd}"); UpdateVersionSummary(tag, content, repository); content.Add(string.Empty); TextTasks.WriteAllLines(changelogFile, content); }
public static void EnqueueIfNotAlready(HudElementWaypoint wp) { if (!TextTasks.Contains(wp)) { TextTasks.Enqueue(wp); } }
/// <summary> /// Finalizes the changelog by moving all entries from `[vNext]` to the version specified by release. /// <p>If <paramref name="repository"/> is specified a summary with all versions and links to list the changes directly on GitHub is appended to the end of the changelog.</p> /// </summary> /// <param name="changelogFile">The path to the changelog file.</param> /// <param name="tag">The <see cref="NuGetVersion"/> to finalize the changelog.</param> /// <param name="repository">The repository to create the version overview for.</param> /// <seealso cref="FinalizeChangelog(ChangeLog,NuGetVersion,GitRepository)"/> public static void FinalizeChangelog(ChangeLog changelogFile, NuGetVersion tag, [CanBeNull] GitRepository repository = null) { Logger.Info($"Finalizing {PathConstruction.GetRelativePath(NukeBuild.RootDirectory, changelogFile.Path)} for '{tag}'..."); var unreleasedNotes = changelogFile.Unreleased; var releaseNotes = changelogFile.ReleaseNotes; var lastReleased = changelogFile.LatestVersion; ControlFlow.Assert(unreleasedNotes != null, "Changelog should have draft section."); ControlFlow.Assert(releaseNotes.Any(x => x.Version != null && x.Version.Equals(tag)), $"Tag '{tag}' already exists."); ControlFlow.Assert(lastReleased != null && tag.CompareTo(lastReleased.Version) > 0, $"Tag '{tag}' is not greater compared to last tag '{lastReleased.NotNull().Version}'."); var path = changelogFile.Path; var content = TextTasks.ReadAllLines(path).ToList(); content.Insert(unreleasedNotes.StartIndex + 1, string.Empty); content.Insert(unreleasedNotes.EndIndex + 2, $"## [{tag}] / {DateTime.Now:yyyy-MM-dd}"); UpdateVersionSummary(tag.ToString(), content, repository); content.Add(string.Empty); TextTasks.WriteAllLines(path, content); }
public static void FillTemplateFile( string file, IReadOnlyCollection <string> definitions = null, IReadOnlyDictionary <string, string> replacements = null) { TextTasks.WriteAllLines(file, FillTemplate(TextTasks.ReadAllLines(file), definitions, replacements)); }
/// <summary> /// Parses MSBuild project file. /// </summary> public static MSBuildProject MSBuildParseProject(string projectFile, Configure <MSBuildSettings> configurator = null) { Logger.Trace($"Parsing project file '{projectFile}'..."); var content = TextTasks.ReadAllText(projectFile); var isSdkProject = content.Contains("Sdk=\"Microsoft.NET.Sdk\""); var isLegacyProject = content.Contains("http://schemas.microsoft.com/developer/msbuild/2003"); ControlFlow.Assert((isSdkProject || isLegacyProject) && (!isSdkProject || !isLegacyProject), "Unknown format."); var toolSettings = configurator.InvokeSafe(new MSBuildSettings()) .DisableLogOutput() .SetProjectFile(projectFile) .SetVerbosity(MSBuildVerbosity.Diagnostic) .SetTargets(Guid.NewGuid().ToString()); var process = ProcessTasks.StartProcess(toolSettings); process.AssertWaitForExit(); var lines = process.Output.Select(x => x.Text).ToArray(); var properties = ParseProperties(lines); var itemGroups = ParseItemGroups(lines); return(new MSBuildProject(isSdkProject, properties, itemGroups)); }
protected override StreamWriter CreateStream() { TextTasks.WriteAllLines( PomFile, ResourceUtility.GetResourceAllLines <TeamCityConfiguration>("pom.xml")); return(base.CreateStream()); }
public static Solution ParseSolution(string solutionFile, string configuration = null, string targetFramework = null) { string GuidPattern(string text) => $@"\{{(?<{Regex.Escape(text)}>[0-9a-fA-F]{{8}}-[0-9a-fA-F]{{4}}-[0-9a-fA-F]{{4}}-[0-9a-fA-F]{{4}}-[0-9a-fA-F]{{12}})\}}"; string TextPattern(string name) => $@"""(?<{Regex.Escape(name)}>[^""]*)"""; string ProjectPattern() => $@"^Project\(""{GuidPattern("typeId")}""\)\s*=\s*{TextPattern("name")},\s*{TextPattern("path")},\s*""{GuidPattern("id")}""$"; var lines = TextTasks.ReadAllLines(solutionFile); var childToParent = lines .SkipWhile(x => !Regex.IsMatch(x, @"^\s*GlobalSection\(NestedProjects\) = preSolution$")) .Skip(count: 1) .TakeWhile(x => !Regex.IsMatch(x, @"^\s*EndGlobalSection$")) .Select(x => Regex.Match(x, $@"^\s*{GuidPattern("child")}\s*=\s*{GuidPattern("parent")}$")) .ToDictionary(x => Guid.Parse(x.Groups["child"].Value), x => Guid.Parse(x.Groups["parent"].Value)); var projectData = lines .Select(x => Regex.Match(x, ProjectPattern())) .Where(x => x.Success) .Select(x => new { Id = Guid.Parse(x.Groups["id"].Value), Name = x.Groups["name"].Value, TypeId = Guid.Parse(x.Groups["typeId"].Value), Path = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(solutionFile).NotNull(), x.Groups["path"].Value)) }).ToList(); var projects = new List <Project>(); while (projectData.Count > 0) { var data = projectData.First(); projectData.Remove(data); Project parent = null; if (childToParent.TryGetValue(data.Id, out var parentId)) { parent = projects.SingleOrDefault(x => x.Id == parentId); if (parent == null) { projectData.Add(data); continue; } } projects.Add(new Project(data.Id, data.Name, data.Path, data.TypeId, parent, configuration, targetFramework)); } return(new Solution(solutionFile, projects.AsReadOnly())); }
public static IEnumerable <string> ExtractChangelogSectionNotes(string changelogFile, string tag = null) { var content = TextTasks.ReadAllLines(changelogFile).ToList(); var sections = GetReleaseSections(content); var section = tag == null ? sections.First(x => x.StartIndex < x.EndIndex) : sections.First(x => x.Caption.EqualsOrdinalIgnoreCase(tag)).NotNull($"Could not find release section for '{tag}'."); return(content .Skip(section.StartIndex + 1) .Take(section.EndIndex - section.StartIndex)); }
protected override ConfigurationEntity GetConfiguration(NukeBuild build, IReadOnlyCollection <ExecutableTarget> relevantTargets) { TextTasks.WriteAllLines( PomFile, ResourceUtility.GetResourceAllLines <TeamCityConfiguration>("pom.xml")); return(new TeamCityConfiguration { Version = Version, Project = GetProject(build, relevantTargets) }); }
public static (int insertIndex, List <string> content) ExtractChangelog(string changelogFile, string tag = null) { var content = TextTasks.ReadAllLines(changelogFile).ToList(); var firstSectionIndex = content.FindIndex(x => x.StartsWith(tag ?? "## ")); if (firstSectionIndex == -1) { return(content.Count, content); } return(firstSectionIndex, content); }
public static Overwrite LoadOverwrites(string overwriteFile) { if (!File.Exists(overwriteFile)) { return(null); } var deserializer = new DeserializerBuilder() .WithNamingConvention(new CamelCaseNamingConvention()) .IgnoreUnmatchedProperties() .Build(); return(deserializer.Deserialize <Overwrite>(TextTasks.ReadAllText(overwriteFile))); }
public void Should_Emit_Autofac(string template) { var(directory, output) = InvokeDotnetNew(template, x => x .AddPair("skipSolution") .AddPair("autofac") ); var project = XDocument.Load(directory.GlobFiles("*.csproj").Single()); var program = TextTasks.ReadAllText(directory.GlobFiles("Program.cs").Single()); project.Descendants("PackageReference") .Should().ContainSingle(x => x.Attribute("Include").Value == "Rocket.Surgery.Hosting.Autofac"); program.Should().Contain(".ConfigureRocketSurgery(builder => builder.UseAutofac())"); }
internal TeamCity(Action <string> messageSink) { _messageSink = messageSink ?? Console.WriteLine; _systemProperties = Lazy.Create(() => ParseDictionary(EnvironmentInfo.GetVariable <string>("TEAMCITY_BUILD_PROPERTIES_FILE"))); _configurationProperties = Lazy.Create(() => ParseDictionary(SystemProperties?["teamcity.configuration.properties.file"])); _runnerProperties = Lazy.Create(() => ParseDictionary(SystemProperties?["teamcity.runner.properties.file"])); _recentlyFailedTests = Lazy.Create(() => { var file = SystemProperties?["teamcity.tests.recentlyFailedTests.file"]; return(File.Exists(file) ? TextTasks.ReadAllLines(file).ToImmutableList() as IReadOnlyCollection <string> : new string[0]); }); }
public static void GenerateSchema <T>(string output, string id, string title) { Logger.Info($"Generating schema for '{typeof(T).Name}' to '{output}'..."); var schemaGenerator = new JSchemaGenerator { DefaultRequired = Required.DisallowNull, ContractResolver = new CamelCasePropertyNamesContractResolver(), GenerationProviders = { new StringEnumGenerationProvider() } }; var toolSchema = schemaGenerator.Generate(typeof(T)); toolSchema.Id = new Uri(id); toolSchema.Title = title; TextTasks.WriteAllText(output, toolSchema.ToString(SchemaVersion.Draft4)); }
protected override void Generate(NukeBuild build, IReadOnlyCollection <ExecutableTarget> executableTargets) { var relevantTargets = VcsTriggeredTargets.Concat(ManuallyTriggeredTargets) .SelectMany(x => ExecutionPlanner.GetExecutionPlan(executableTargets, new[] { x })) .Distinct() .Where(x => !ExcludedTargets.Contains(x.Name) && !NonEntryTargets.Contains(x.Name)).ToList(); var configuration = GetConfiguration(build, relevantTargets); ControlFlow.Assert(NukeBuild.RootDirectory != null, "NukeBuild.RootDirectory != null"); TextTasks.WriteAllLines( PomFile, ResourceUtility.GetResourceAllLines <TeamCityConfigurationEntity>("pom.xml")); using var writer = new CustomFileWriter(SettingsFile, indentationFactor: 4); configuration.Write(writer); }
public static void UpdateChangeLog(string changeLogPath, string releaseName, string releaseUrl) { var changeLogLines = TextTasks.ReadAllLines(changeLogPath); var firstVNextVersionLine = Array.FindIndex(changeLogLines, x => x == "## [vNext]") + 1; var latestReleaseSectionLine = Array.FindIndex(changeLogLines, firstVNextVersionLine, x => x.StartsWith("##")); var releaseText = changeLogLines .Skip(firstVNextVersionLine) .Take(latestReleaseSectionLine - firstVNextVersionLine) .Where(x => !string.IsNullOrEmpty(x)) .Append( $"- Changed supported version to [{releaseName}]({releaseUrl})."); var updatedChangeLog = changeLogLines.Take(firstVNextVersionLine) .Concat(releaseText) .Concat(changeLogLines.Skip(latestReleaseSectionLine)); TextTasks.WriteAllText(changeLogPath, updatedChangeLog.JoinNewLine()); }
void UpdateVersion(string version) { void UpdateVersion(string filePath) { var packageJson = TextTasks.ReadAllText(filePath); var package = JObject.Parse(packageJson); var packageVersion = package.Value <string>("version"); if (version == packageVersion) { return; } package["version"] = new JValue(version); TextTasks.WriteAllText(filePath, package.ToString(Formatting.Indented) + EnvironmentInfo.NewLine); } UpdateVersion(RootDirectory / "package.json"); UpdateVersion(RootDirectory / "package-lock.json"); }
protected override void Generate(NukeBuild build, IReadOnlyCollection <ExecutableTarget> executableTargets) { ControlFlow.Assert(NukeBuild.RootDirectory != null, "NukeBuild.RootDirectory != null"); var teamcityDirectory = NukeBuild.RootDirectory / ".teamcity"; TextTasks.WriteAllLines( teamcityDirectory / "pom.xml", ResourceUtility.GetResourceAllLines <TeamCityConfigurationEntity>("pom.xml")); using (var writer = new CustomFileWriter(teamcityDirectory / "settings.kts", indentationFactor: 4)) { GetHeader().ForEach(writer.WriteLine); var project = GetProject(build, executableTargets); project.Write(writer); project.VcsRoot.Write(writer); project.BuildTypes.ForEach(x => x.Write(writer)); } }
public static IReadOnlyList <ReleaseNotes> ReadReleaseNotes(string changelogFile) { var lines = TextTasks.ReadAllLines(changelogFile).ToList(); var releaseSections = GetReleaseSections(lines).ToList(); ControlFlow.Assert(releaseSections.Any(), "Changelog should have at least one release note section"); return(releaseSections.Select(Parse).ToList().AsReadOnly()); ReleaseNotes Parse(ReleaseSection section) { var releaseNotes = lines .Skip(section.StartIndex + 1) .Take(section.EndIndex - section.StartIndex) .ToList() .AsReadOnly(); return(NuGetVersion.TryParse(section.Caption, out var version) ? new ReleaseNotes(version, releaseNotes, section.StartIndex, section.EndIndex) : new ReleaseNotes(releaseNotes, section.StartIndex, section.EndIndex)); } }
public static void FinalizeChangelog(string changelogFile, string tag, [CanBeNull] GitRepository repository = null) { Logger.Info($"Finalizing {PathConstruction.GetRootRelativePath(changelogFile)} for '{tag}'..."); var content = TextTasks.ReadAllLines(changelogFile).ToList(); var sections = GetReleaseSections(content).ToList(); var firstSection = sections.First(); var secondSection = sections.Skip(1).FirstOrDefault(); ControlFlow.Assert(firstSection.Caption.All(char.IsLetter), "Cannot find a draft section."); ControlFlow.Assert(sections.All(x => !x.Caption.EqualsOrdinalIgnoreCase(tag)), $"Tag '{tag}' already exists."); ControlFlow.Assert(firstSection.EndIndex > firstSection.StartIndex, $"Draft section '{firstSection.Caption}' does not contain any information."); ControlFlow.Assert(secondSection == null || NuGetVersion.Parse(tag).CompareTo(NuGetVersion.Parse(secondSection.Caption)) > 0, $"Tag '{tag}' is not greater compared to last tag '{secondSection?.Caption}'."); content.Insert(firstSection.StartIndex + 1, string.Empty); content.Insert(firstSection.StartIndex + 2, $"## [{tag}] / {DateTime.Now:yyyy-MM-dd}"); if (repository != null && repository.IsGitHubRepository()) { sections = GetReleaseSections(content).ToList(); firstSection = sections.First(); var lastSection = sections.Last(); content.RemoveRange(lastSection.EndIndex + 1, content.Count - lastSection.EndIndex - 1); content.Add(string.Empty); content.Add($"[{firstSection.Caption}]: {repository}/compare/{tag}...HEAD"); for (var i = 1; i + 1 < sections.Count; i++) { content.Add($"[{sections[i].Caption}]: {repository}/compare/{sections[i + 1].Caption}...{sections[i].Caption}"); } content.Add($"[{lastSection.Caption}]: {repository}/tree/{lastSection.Caption}"); } content.Add(string.Empty); TextTasks.WriteAllLines(changelogFile, content); }
private async Task <bool> DownloadExternalFile(ExternalFilesData data) { try { var previousHash = File.Exists(data.OutputPath) ? FileSystemTasks.GetFileHash(data.OutputPath) : null; var template = (await HttpTasks.HttpDownloadStringAsync(data.Uri.OriginalString)).SplitLineBreaks(); TextTasks.WriteAllLines(data.OutputPath, TemplateUtility.FillTemplate(template, data.Tokens)); var newHash = FileSystemTasks.GetFileHash(data.OutputPath); if (newHash != previousHash) { LogWarning(message: $"External file '{data.OutputPath}' has been updated.", file: data.Identity); } return(true); } catch (Exception exception) { LogError(message: exception.Message, file: data.Identity); return(false); } }
public void Test(string archiveFile) { var rootFile = Path.Combine(TestTempDirectory, "rootfile.txt"); var nestedFile = Path.Combine(TestTempDirectory, "a", "b", "c", "nestedfile.txt"); TextTasks.WriteAllText(rootFile, "root"); TextTasks.WriteAllText(nestedFile, "nested"); var archive = Path.Combine(TestTempDirectory, archiveFile); CompressionTasks.Compress(TestTempDirectory, archive); File.Exists(archive).Should().BeTrue(); File.Delete(rootFile); File.Delete(nestedFile); Directory.GetFiles(TestTempDirectory, "*").Should().HaveCount(1); CompressionTasks.Uncompress(archive, TestTempDirectory); File.Exists(rootFile).Should().BeTrue(); File.ReadAllText(rootFile).Should().Be("root"); File.Exists(nestedFile).Should().BeTrue(); File.ReadAllText(nestedFile).Should().Be("nested"); }
public static T DeserializeFromFile <T>(string solutionFile) where T : Solution, new() { return(DeserializeFromContent <T>(TextTasks.ReadAllLines(solutionFile), solutionFile)); }
public Should_Emit_Multiple_Conventions_Data() { Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("autofac") .AddPair("skipSolution"), path => { var file = path.GlobFiles("*Convention.cs").Single(); var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); var text = TextTasks.ReadAllText(file); text.Should().Contain("using Rocket.Surgery.Extensions.Autofac;"); text.Should().Contain("public void Register(IAutofacConventionContext context)"); text.Should().Contain("IAutofacConvention { }"); project.Descendants("PackageReference").Should() .ContainSingle(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.Autofac"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("dryioc") .AddPair("skipSolution"), path => { var file = path.GlobFiles("*Convention.cs").Single(); var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); var text = TextTasks.ReadAllText(file); text.Should().Contain("using Rocket.Surgery.Extensions.DryIoc;"); text.Should().Contain("public void Register(IDryIocConventionContext context)"); text.Should().Contain("IDryIocConvention { }"); project.Descendants("PackageReference").Should() .ContainSingle(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.DryIoc"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("commandline") .AddPair("skipSolution"), path => { var file = path.GlobFiles("*Convention.cs").Single(); var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); var text = TextTasks.ReadAllText(file); text.Should().Contain("using Rocket.Surgery.Extensions.CommandLine;"); text.Should().Contain("public void Register(ICommandLineConventionContext context)"); text.Should().Contain("ICommandLineConvention { }"); project.Descendants("PackageReference").Should() .ContainSingle(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.CommandLine"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("serilog") .AddPair("skipSolution"), path => { var file = path.GlobFiles("*Convention.cs").Single(); var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); var text = TextTasks.ReadAllText(file); text.Should().Contain("using Rocket.Surgery.Extensions.Serilog;"); text.Should().Contain("public void Register(ISerilogConventionContext context)"); text.Should().Contain("ISerilogConvention { }"); project.Descendants("PackageReference").Should() .ContainSingle(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.Serilog"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("webjobs") .AddPair("skipSolution"), path => { var file = path.GlobFiles("*Convention.cs").Single(); var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); var text = TextTasks.ReadAllText(file); text.Should().Contain("using Rocket.Surgery.Extensions.WebJobs;"); text.Should().Contain("public void Register(IWebJobsConventionContext context)"); text.Should().Contain("IWebJobsConvention { }"); project.Descendants("PackageReference").Should() .ContainSingle(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.WebJobs"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("no-configuration") .AddPair("skipSolution"), path => { var file = path.GlobFiles("*Convention.cs").Single(); var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); var text = TextTasks.ReadAllText(file); text.Should().NotContain("using Rocket.Surgery.Extensions.Configuration;"); text.Should().NotContain("public void Register(IConfigurationConventionContext context)"); text.Should().NotContain("IConfigurationConvention { }"); project.Descendants("PackageReference").Should() .NotContain(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.Configuration"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("no-logging") .AddPair("skipSolution"), path => { var file = path.GlobFiles("*Convention.cs").Single(); var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); var text = TextTasks.ReadAllText(file); text.Should().NotContain("using Rocket.Surgery.Extensions.Logging;"); text.Should().NotContain("public void Register(ILoggingConventionContext context)"); text.Should().NotContain("ILoggingConvention { }"); project.Descendants("PackageReference").Should() .NotContain(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.Logging"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("no-di") .AddPair("skipSolution"), path => { var file = path.GlobFiles("*Convention.cs").Single(); var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); var text = TextTasks.ReadAllText(file); text.Should().NotContain("using Rocket.Surgery.Extensions.DependencyInjection;"); text.Should().NotContain("public void Register(IDependencyInjectionConventionContext context)"); text.Should().NotContain("IDependencyInjectionConvention { }"); project.Descendants("PackageReference").Should() .NotContain(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.DependencyInjection"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("automapper") .AddPair("skipSolution"), path => { var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); project.Descendants("PackageReference").Should() .ContainSingle(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.AutoMapper"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("fluentvalidation") .AddPair("skipSolution"), path => { var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); project.Descendants("PackageReference").Should() .ContainSingle(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.FluentValidation"); } )); Add(new Should_Emit_Multiple_Conventions_Item( new Dictionary <string, string?>() .AddPair("mediatr") .AddPair("skipSolution"), path => { var project = XDocument.Load(path.GlobFiles("*.csproj").Single()); project.Descendants("PackageReference").Should() .ContainSingle(z => z.Attribute("Include").Value == "Rocket.Surgery.Extensions.MediatR"); } )); }
public static void FillTemplateFile( string file, IReadOnlyDictionary <string, string> tokens = null) { TextTasks.WriteAllLines(file, FillTemplate(TextTasks.ReadAllLines(file), tokens)); }
public static bool IsUpdateAvailable(string versionName, string changelogFile) { var changelog = TextTasks.ReadAllLines(changelogFile); return(changelog.All(x => !x.Contains($"[{versionName}]"))); }
public static Solution Deserialize(string solutionFile) { return(Deserialize(solutionFile, TextTasks.ReadAllLines(solutionFile))); }
void PrepareSolution(string globalSolutionFile) { using (var fileStream = File.Create(globalSolutionFile)) using (var streamWriter = new StreamWriter(fileStream)) { streamWriter.Write(@" Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26124.0 MinimumVisualStudioVersion = 15.0.26124.0 Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""_build"", ""build\_build.csproj"", ""{594DB7F8-B1EA-4C9C-BF63-D12A361C513B}"" EndProject "); string GetSolutionFolderName(string s) { var directoryInfo = new FileInfo(s).Directory.NotNull(); return($"{directoryInfo.Parent.NotNull().Name}/{directoryInfo.Name}"); } var solutions = GlobFiles(RepositoriesDirectory, "*/*/*.sln") .Where(x => x != globalSolutionFile) .Select(x => new { File = x, Directory = GetRelativePath(RootDirectory, new FileInfo(x).Directory.NotNull().FullName), Name = GetSolutionFolderName(x), Guid = Guid.NewGuid().ToString("D").ToUpper(), Content = TextTasks.ReadAllLines(x) }) .OrderBy(x => x.Name).ToList(); foreach (var solution in solutions) { streamWriter.WriteLine(@"Project(""{2150E333-8FDC-42A3-9474-1A3956D46DE8}"") = " + $@"""{solution.Name}"", ""{solution.Name}"", ""{{{solution.Guid}}}"""); streamWriter.WriteLine("EndProject"); string FixLocation(string line) { if (line.StartsWith("Project")) { var index = line.Select((x, i) => (x, i)).Where(x => x.Item1 == '"').ElementAt(4).Item2; return(line.Insert(index + 1, $"{solution.Directory}\\")); } if (line.StartsWith("\t\t")) { var index = line.IndexOf('='); return(line.Insert(index + 2, $"{solution.Directory}\\")); } return(line); } solution.Content .SkipWhile(x => !x.StartsWith("Project")) .TakeWhile(x => !x.StartsWith("Global")) // ReSharper disable once AccessToDisposedClosure .ForEach(x => streamWriter.WriteLine(FixLocation(x))); } streamWriter.Write(@" Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution "); var guidDictionary = new Dictionary <string, (string SolutionFile, string Declaration)>(); foreach (var solution in solutions) { string GetAndTrackGuid(string declaration) { var guid = declaration.Substring(declaration.Length - 38, 36); if (guidDictionary.TryGetValue(guid, out var value)) { var solutionFileToFix = solution.Name.Contains("template") ? value.SolutionFile : solution.File; TextTasks.WriteAllText( solutionFileToFix, TextTasks.ReadAllText(solutionFileToFix) .Replace(guid, Guid.NewGuid().ToString("D").ToUpper())); ControlFlow.Fail(new[] { $"Guid {guid} is duplicated in:", $" {solution.File}", $" {declaration}", $" {value.SolutionFile}", $" {value.Declaration}", "Guid has been replaced. Restart target." }.JoinNewLine()); } guidDictionary.Add(guid, (solution.File, declaration)); return(guid); } solution.Content .Where(x => x.StartsWith("Project")) .Select(GetAndTrackGuid) // ReSharper disable once AccessToDisposedClosure .ForEach(x => streamWriter.WriteLine($"\t\t{{{x}}} = {{{solution.Guid}}}")); } streamWriter.Write(@" EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {594DB7F8-B1EA-4C9C-BF63-D12A361C513B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {594DB7F8-B1EA-4C9C-BF63-D12A361C513B}.Release|Any CPU.ActiveCfg = Release|Any CPU "); foreach (var solution in solutions) { solution.Content .SkipWhile(x => !x.Contains("GlobalSection(ProjectConfigurationPlatforms)")) .Skip(1) .TakeWhile(x => !x.Contains("EndGlobalSection")) // ReSharper disable once AccessToDisposedClosure .ForEach(x => streamWriter.WriteLine(x)); } streamWriter.Write(@" EndGlobalSection EndGlobal"); } }