Example #1
0
        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);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        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);
        }