private static void AddFileDependencies(PackageDef pkg, AssemblyData dependency, AssemblyData foundAsm) { var depender = pkg.Files.FirstOrDefault(f => f.DependentAssemblies.Contains(dependency)); if (depender == null) { log.Warning("Adding dependent assembly '{0}' to package. It was not found in any other packages.", Path.GetFileName(foundAsm.Location)); } else { log.Info($"'{Path.GetFileName(depender.FileName)}' dependents on '{dependency.Name}' version '{dependency.Version}'. Adding dependency to package, it was not found in any other packages."); } var destPath = string.Format("Dependencies/{0}.{1}/{2}", Path.GetFileNameWithoutExtension(foundAsm.Location), foundAsm.Version.ToString(), Path.GetFileName(foundAsm.Location)); pkg.Files.Add(new PackageFile { SourcePath = foundAsm.Location, RelativeDestinationPath = destPath, DependentAssemblies = foundAsm.References.ToList() }); // Copy the file to the actual directory so we can rely on it actually existing where we say the package has it. if (!File.Exists(destPath)) { Directory.CreateDirectory(Path.GetDirectoryName(destPath)); ProgramHelper.FileCopy(foundAsm.Location, destPath); } }
private static void UpdateVersionInfo(string tempDir, List <PackageFile> files, SemanticVersion version) { var features = files.Where(f => f.HasCustomData <SetAssemblyInfoData>()).SelectMany(f => string.Join(",", f.GetCustomData <SetAssemblyInfoData>().Select(a => a.Attributes)).Split(',').Select(str => str.Trim().ToLower())).Distinct().ToHashSet(); if (!features.Any()) { return; } var timer = Stopwatch.StartNew(); SetAsmInfo.UpdateMethod updateMethod; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { updateMethod = SetAsmInfo.UpdateMethod.ILDasm; } else { updateMethod = SetAsmInfo.UpdateMethod.Mono; } foreach (var file in files) { if (!file.HasCustomData <SetAssemblyInfoData>()) { continue; } var toSet = string.Join(",", file.GetCustomData <SetAssemblyInfoData>().Select(a => a.Attributes)).Split(',').Select(str => str.Trim().ToLower()).Distinct().ToHashSet(); if (!toSet.Any()) { continue; } log.Debug("Updating version info for '{0}'", file.FileName); // Assume we can't open the file for writing (could be because we are trying to modify TPM or the engine), and copy to the same filename in a subdirectory var versionedOutput = Path.Combine(tempDir, "Versioned"); var origFilename = Path.GetFileName(file.FileName); var tempName = Path.Combine(versionedOutput, origFilename); int i = 1; while (File.Exists(tempName)) { tempName = Path.Combine(versionedOutput, origFilename + i.ToString()); i++; } Directory.CreateDirectory(Path.GetDirectoryName(tempName)); ProgramHelper.FileCopy(file.FileName, tempName); file.SourcePath = tempName; SemanticVersion fVersion = null; Version fVersionShort = null; if (toSet.Contains("version")) { fVersion = version; fVersionShort = new Version(version.ToString(3)); } SetAsmInfo.SetAsmInfo.SetInfo(file.FileName, fVersionShort, fVersionShort, fVersion, updateMethod); file.RemoveCustomData <SetAssemblyInfoData>(); } log.Info(timer, "Updated assembly version info using {0} method.", updateMethod); }
/// <summary> /// Load from an XML package definition file. /// This file is not expected to have info about the plugins in it, so this method will enumerate the plugins inside each dll by loading them. /// </summary> /// <param name="xmlFilePath">The Package Definition xml file. Usually named package.xml</param> /// <param name="projectDir">Directory used byt GitVersionCalculator to expand any $(GitVersion) macros in the XML file.</param> /// <returns></returns> public static PackageDef FromInputXml(string xmlFilePath, string projectDir) { PackageDef.ValidateXml(xmlFilePath); var pkgDef = PackageDef.FromXml(xmlFilePath); if (pkgDef.Files.Any(f => f.HasCustomData <UseVersionData>() && f.HasCustomData <SetAssemblyInfoData>())) { throw new InvalidDataException("A file cannot specify <SetAssemblyInfo/> and <UseVersion/> at the same time."); } pkgDef.Files = expandGlobEntries(pkgDef.Files); var excludeAdd = pkgDef.Files.Where(file => file.IgnoredDependencies != null).SelectMany(file => file.IgnoredDependencies).Distinct().ToList(); List <Exception> exceptions = new List <Exception>(); foreach (PackageFile item in pkgDef.Files) { string fullPath = Path.GetFullPath(item.FileName); if (!File.Exists(fullPath)) { string fileName = Path.GetFileName(item.FileName); if (File.Exists(fileName) && item.SourcePath == null) { // this is to support building everything to the root folder. This way the developer does not have to specify SourcePath. log.Warning("Specified file '{0}' was not found, using file '{1}' as source instead. Consider setting SourcePath to remove this warning.", item.FileName, fileName); item.SourcePath = fileName; } else { exceptions.Add(new FileNotFoundException("Missing file for package.", fullPath)); } } } if (exceptions.Count > 0) { throw new AggregateException("Missing files", exceptions); } pkgDef.Date = DateTime.UtcNow; // Copy to output directory first foreach (var file in pkgDef.Files) { if (file.RelativeDestinationPath != file.FileName) { try { var destPath = Path.GetFullPath(file.RelativeDestinationPath); if (!File.Exists(destPath)) { Directory.CreateDirectory(Path.GetDirectoryName(destPath)); ProgramHelper.FileCopy(file.FileName, destPath); } } catch { // Catching here. The files might be used by themselves } } } var searcher = new PluginSearcher(PluginSearcher.Options.IncludeSameAssemblies); searcher.Search(Directory.GetCurrentDirectory()); List <AssemblyData> assemblies = searcher.Assemblies.ToList(); // Enumerate plugins if this has not already been done. if (!pkgDef.Files.SelectMany(pfd => pfd.Plugins).Any()) { EnumeratePlugins(pkgDef, assemblies); } log.Info("Updating package version."); pkgDef.updateVersion(projectDir); log.Info("Package version is {0}", pkgDef.Version); pkgDef.findDependencies(excludeAdd, assemblies); return(pkgDef); }
private int Process(string[] OutputPaths) { try { PackageDef pkg = null; if (!File.Exists(PackageXmlFile)) { log.Error("Cannot locate XML file '{0}'", PackageXmlFile); return((int)ExitCodes.FileSystemError); } if (!Directory.Exists(ProjectDir)) { log.Error("Project directory '{0}' does not exist.", ProjectDir); return((int)ExitCodes.FileSystemError); } try { var fullpath = Path.GetFullPath(PackageXmlFile); pkg = PackageDefExt.FromInputXml(fullpath, ProjectDir); // Check if package name has invalid characters or is not a valid path var illegalCharacter = pkg.Name.IndexOfAny(Path.GetInvalidFileNameChars()); if (illegalCharacter >= 0) { log.Error("Package name cannot contain invalid file path characters: '{0}'", pkg.Name[illegalCharacter]); return((int)ExitCodes.InvalidPackageName); } } catch (AggregateException aex) { foreach (var ex in aex.InnerExceptions) { if (ex is FileNotFoundException) { log.Error("File not found: '{0}'", ((FileNotFoundException)ex).FileName); } else { log.Error(ex.ToString()); } } log.Error("Caught errors while loading package definition."); return(4); } var tmpFile = Path.GetTempFileName(); // If user omitted the Version XML attribute or put Version="", lets inform. if (string.IsNullOrEmpty(pkg.RawVersion)) { log.Warning($"Package version is {pkg.Version} due to blank or missing 'Version' XML attribute in 'Package' element"); } pkg.CreatePackage(tmpFile); if (OutputPaths == null || OutputPaths.Length == 0) { OutputPaths = new string[1] { "" } } ; foreach (var outputPath in OutputPaths) { var path = outputPath; if (String.IsNullOrEmpty(path)) { path = GetRealFilePathFromName(pkg.Name, pkg.Version.ToString(), DefaultEnding); } Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path))); ProgramHelper.FileCopy(tmpFile, path); log.Info("OpenTAP plugin package '{0}' containing '{1}' successfully created.", path, pkg.Name); } if (FakeInstall) { log.Warning("--fake-install argument is obsolete, use --install instead"); Install = FakeInstall; } if (Install) { var path = PackageDef.GetDefaultPackageMetadataPath(pkg, Directory.GetCurrentDirectory()); Directory.CreateDirectory(Path.GetDirectoryName(path)); using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate)) { pkg.SaveTo(fs); } log.Info($"Installed '{pkg.Name}' ({Path.GetFullPath(path)})"); } } catch (ArgumentException ex) { Console.Error.WriteLine(ex.Message); return((int)ExitCodes.GeneralPackageCreateError); } catch (InvalidDataException ex) { log.Error("Caught invalid data exception: {0}", ex.Message); return((int)ExitCodes.InvalidPackageDefinition); } return(0); }