示例#1
0
        public static string GetOrCompileProjectAssembly(string fullProjectLocation, ILogger logger, bool autoCompileProject, string configuration = "Debug", string platform = "AnyCPU", Dictionary <string, string> extraProperties = null, bool onlyErrors = false, BuildRequestDataFlags flags = BuildRequestDataFlags.None)
        {
            if (fullProjectLocation == null)
            {
                throw new ArgumentNullException("fullProjectLocation");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            var project      = LoadProject(fullProjectLocation, configuration, platform, extraProperties);
            var assemblyPath = project.GetPropertyValue("TargetPath");

            try
            {
                if (!string.IsNullOrWhiteSpace(assemblyPath))
                {
                    if (autoCompileProject)
                    {
                        var asyncBuild = new CancellableAsyncBuild(project, assemblyPath);
                        asyncBuild.Build(project, "Build", flags, new LoggerRedirect(logger, onlyErrors));
                        var buildResult = asyncBuild.BuildTask.Result;
                    }
                }
            }
            finally
            {
                project.ProjectCollection.UnloadAllProjects();
                project.ProjectCollection.Dispose();
            }

            return(assemblyPath);
        }
示例#2
0
        public static async Task RestoreNugetPackagesNonRecursive(ILogger logger, string solutionFullPath, bool force, IEnumerable <string> projectPaths)
        {
            foreach (var projectPath in projectPaths)
            {
                // TODO: We directly find the project.json rather than the solution file (otherwise NuGet reports an error if the solution didn't contain a project.json or if solution is not saved yet)
                // However, the problem is that if Game was referencing another assembly with a project.json, it won't be updated
                // At some point we should find all project.json of the full solution, and keep regenerating them if any of them changed
                var projectJson = Path.Combine(projectPath, "project.json");

                // Nothing to do if there is no project.json
                if (!File.Exists(projectJson))
                {
                    continue;
                }

                // Check if project.json is newer than project.lock.json (GetLastWriteTimeUtc returns year 1601 if file doesn't exist so it will also generate it)
                var projectLockJson = Path.Combine(projectPath, "project.lock.json");
                if (force || File.GetLastWriteTimeUtc(projectJson) > File.GetLastWriteTimeUtc(projectLockJson))
                {
                    // Check if it needs to be regenerated
                    // Run NuGet.exe restore
                    var parameters = $"restore \"{projectJson}\"";
                    if (solutionFullPath != null)
                    {
                        parameters += $" -solutiondirectory \"{Path.GetDirectoryName(solutionFullPath)}\"";
                    }
                    await ShellHelper.RunProcessAndGetOutputAsync(NugetPath, parameters, logger);
                }
            }
        }
示例#3
0
 public LoggerRedirect(ILogger logger, bool onlyErrors = false)
 {
     if (logger == null)
     {
         throw new ArgumentNullException("logger");
     }
     this.logger     = logger;
     this.onlyErrors = onlyErrors;
 }
示例#4
0
        /// <summary>
        /// Adds an existing package to the current session.
        /// </summary>
        /// <param name="packagePath">The package path.</param>
        /// <param name="logger">The session result.</param>
        /// <param name="loadParametersArg">The load parameters argument.</param>
        /// <exception cref="System.ArgumentNullException">packagePath</exception>
        /// <exception cref="System.ArgumentException">Invalid relative path. Expecting an absolute package path;packagePath</exception>
        /// <exception cref="System.IO.FileNotFoundException">Unable to find package</exception>
        public Package AddExistingPackage(UFile packagePath, ILogger logger, PackageLoadParameters loadParametersArg = null)
        {
            if (packagePath == null)
            {
                throw new ArgumentNullException("packagePath");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }
            if (!packagePath.IsAbsolute)
            {
                throw new ArgumentException("Invalid relative path. Expecting an absolute package path", "packagePath");
            }
            if (!File.Exists(packagePath))
            {
                throw new FileNotFoundException("Unable to find package", packagePath);
            }

            var loadParameters = loadParametersArg ?? PackageLoadParameters.Default();

            Package package;

            try
            {
                // Enable reference analysis caching during loading
                AssetReferenceAnalysis.EnableCaching = true;

                var packagesLoaded = new PackageCollection();

                package = PreLoadPackage(this, logger, packagePath, false, packagesLoaded, loadParameters);

                // Load all missing references/dependencies
                LoadMissingReferences(logger, loadParameters);

                // Load assets
                TryLoadAssets(this, logger, package, loadParameters);

                // Run analysis after
                foreach (var packageToAdd in packagesLoaded)
                {
                    var analysis = new PackageAnalysis(packageToAdd, GetPackageAnalysisParametersForLoad());
                    analysis.Run(logger);
                }
            }
            finally
            {
                // Disable reference analysis caching after loading
                AssetReferenceAnalysis.EnableCaching = false;
            }
            return(package);
        }
示例#5
0
        public static async Task RestoreNugetPackages(ILogger logger, string solutionFullPath, Project project)
        {
            var addedProjs = new HashSet <string>(); //to avoid worst case circular dependencies.
            var allProjs   = Utilities.IterateTree(project, project1 =>
            {
                var projs = new List <Project>();
                foreach (var item in project1.AllEvaluatedItems.Where(x => x.ItemType == "ProjectReference"))
                {
                    var path = Path.Combine(project.DirectoryPath, item.EvaluatedInclude);
                    if (!File.Exists(path))
                    {
                        continue;
                    }

                    if (addedProjs.Add(path))
                    {
                        projs.Add(project.ProjectCollection.LoadProject(path));
                    }
                }
                return(projs);
            });

            foreach (var proj in allProjs)
            {
                // TODO: We directly find the project.json rather than the solution file (otherwise NuGet reports an error if the solution didn't contain a project.json or if solution is not saved yet)
                // However, the problem is that if Game was referencing another assembly with a project.json, it won't be updated
                // At some point we should find all project.json of the full solution, and keep regenerating them if any of them changed
                var projectJson = Path.Combine(proj.DirectoryPath, "project.json");

                // Nothing to do if there is no project.json
                if (!File.Exists(projectJson))
                {
                    continue;
                }

                // Check if project.json is newer than project.lock.json (GetLastWriteTimeUtc returns year 1601 if file doesn't exist so it will also generate it)
                var projectLockJson = Path.Combine(proj.DirectoryPath, "project.lock.json");
                if (File.GetLastWriteTimeUtc(projectJson) > File.GetLastWriteTimeUtc(projectLockJson))
                {
                    // Check if it needs to be regenerated
                    // Run NuGet.exe restore
                    var parameters = $"restore \"{projectJson}\"";
                    if (solutionFullPath != null)
                    {
                        parameters += $" -solutiondirectory \"{Path.GetDirectoryName(solutionFullPath)}\"";
                    }
                    await ShellHelper.RunProcessAndGetOutputAsync(NugetPath, parameters, logger);
                }
            }
        }
示例#6
0
        /// <summary>
        /// Make sure packages have their assets loaded.
        /// </summary>
        /// <param name="log">The log.</param>
        /// <param name="loadParametersArg">The load parameters argument.</param>
        public void LoadMissingAssets(ILogger log, PackageLoadParameters loadParametersArg = null)
        {
            var loadParameters = loadParametersArg ?? PackageLoadParameters.Default();

            var cancelToken = loadParameters.CancelToken;

            // Make a copy of Packages as it can be modified by PreLoadPackageDependencies
            var previousPackages = Packages.ToList();

            foreach (var package in previousPackages)
            {
                // Output the session only if there is no cancellation
                if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested)
                {
                    return;
                }

                TryLoadAssets(this, log, package, loadParameters);
            }
        }
示例#7
0
        PackageUpgrader CheckPackageUpgrade(ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage)
        {
            // Don't do anything if source is a system (read-only) package for now
            // We only want to process local packages
            if (dependentPackage.IsSystem)
            {
                return(null);
            }

            // Check if package might need upgrading
            var dependentPackagePreviousMinimumVersion = dependency.Version.MinVersion;

            if (dependentPackagePreviousMinimumVersion < dependencyPackage.Meta.Version)
            {
                // Find upgrader for given package
                // Note: If no upgrader is found, we assume it is still compatible with previous versions, so do nothing
                var packageUpgrader = AssetRegistry.GetPackageUpgrader(dependencyPackage.Meta.Name);
                if (packageUpgrader != null)
                {
                    // Check if upgrade is necessary
                    if (dependency.Version.MinVersion >= packageUpgrader.Attribute.PackageUpdatedVersionRange.MinVersion)
                    {
                        return(null);
                    }

                    // Check if upgrade is allowed
                    if (dependency.Version.MinVersion < packageUpgrader.Attribute.PackageMinimumVersion)
                    {
                        // Throw an exception, because the package update is not allowed and can't be done
                        throw new InvalidOperationException(string.Format("Upgrading package [{0}] to use [{1}] from version [{2}] to [{3}] is not supported", dependentPackage.Meta.Name, dependencyPackage.Meta.Name, dependentPackagePreviousMinimumVersion, dependencyPackage.Meta.Version));
                    }

                    log.Info("Upgrading package [{0}] to use [{1}] from version [{2}] to [{3}] will be required", dependentPackage.Meta.Name, dependencyPackage.Meta.Name, dependentPackagePreviousMinimumVersion, dependencyPackage.Meta.Version);
                    return(packageUpgrader);
                }
            }

            return(null);
        }
示例#8
0
        public static async Task RestoreNugetPackages(ILogger logger, string solutionFullPath, Project project, bool force)
        {
            var addedProjs = new HashSet <string>(); //to avoid worst case circular dependencies.
            var allProjs   = Utilities.IterateTree(project, project1 =>
            {
                var projs = new List <Project>();
                foreach (var item in project1.AllEvaluatedItems.Where(x => x.ItemType == "ProjectReference"))
                {
                    var path = Path.Combine(project.DirectoryPath, item.EvaluatedInclude);
                    if (!File.Exists(path))
                    {
                        continue;
                    }

                    if (addedProjs.Add(path))
                    {
                        projs.Add(project.ProjectCollection.LoadProject(path));
                    }
                }
                return(projs);
            });

            await RestoreNugetPackagesNonRecursive(logger, solutionFullPath, force, allProjs.Select(x => x.DirectoryPath));
        }
示例#9
0
        /// <summary>
        /// Adds an existing package to the current session and runs the package analysis before adding it.
        /// </summary>
        /// <param name="package">The package to add</param>
        /// <param name="logger">The logger</param>
        public void AddExistingPackage(Package package, ILogger logger)
        {
            if (package == null) throw new ArgumentNullException(nameof(package));
            if (logger == null) throw new ArgumentNullException(nameof(logger));

            if (packages.Contains(package))
            {
                return;
            }

            // Preset the session on the package to allow the session to look for existing asset
            this.Packages.Add(package);

            // Run analysis after
            var analysis = new PackageAnalysis(package, GetPackageAnalysisParametersForLoad());
            analysis.Run(logger);

        }
示例#10
0
        /// <summary>
        /// Adds an existing package to the current session.
        /// </summary>
        /// <param name="packagePath">The package path.</param>
        /// <param name="logger">The session result.</param>
        /// <param name="loadParametersArg">The load parameters argument.</param>
        /// <exception cref="System.ArgumentNullException">packagePath</exception>
        /// <exception cref="System.ArgumentException">Invalid relative path. Expecting an absolute package path;packagePath</exception>
        /// <exception cref="System.IO.FileNotFoundException">Unable to find package</exception>
        public Package AddExistingPackage(UFile packagePath, ILogger logger, PackageLoadParameters loadParametersArg = null)
        {
            if (packagePath == null) throw new ArgumentNullException("packagePath");
            if (logger == null) throw new ArgumentNullException("logger");
            if (!packagePath.IsAbsolute) throw new ArgumentException("Invalid relative path. Expecting an absolute package path", "packagePath");
            if (!File.Exists(packagePath)) throw new FileNotFoundException("Unable to find package", packagePath);

            var loadParameters = loadParametersArg ?? PackageLoadParameters.Default();

            Package package;
            try
            {
                // Enable reference analysis caching during loading
                AssetReferenceAnalysis.EnableCaching = true;

                var packagesLoaded = new PackageCollection();

                package = PreLoadPackage(this, logger, packagePath, false, packagesLoaded, loadParameters);

                // Load all missing references/dependencies
                LoadMissingReferences(logger, loadParameters);

                // Load assets
                TryLoadAssets(this, logger, package, loadParameters);

                // Run analysis after
                foreach (var packageToAdd in packagesLoaded)
                {
                    var analysis = new PackageAnalysis(packageToAdd, GetPackageAnalysisParametersForLoad());
                    analysis.Run(logger);
                }
            }
            finally
            {
                // Disable reference analysis caching after loading
                AssetReferenceAnalysis.EnableCaching = false;
            }
            return package;
        }
示例#11
0
        private static void PreLoadPackageDependencies(PackageSession session, ILogger log, Package package, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null) throw new ArgumentNullException("session");
            if (log == null) throw new ArgumentNullException("log");
            if (package == null) throw new ArgumentNullException("package");
            if (loadParameters == null) throw new ArgumentNullException("loadParameters");

            bool packageDependencyErrors = false;

            // TODO: Remove and recheck Dependencies Ready if some secondary packages are removed?
            if (package.State >= PackageState.DependenciesReady)
                return;

            // 1. Load store package
            foreach (var packageDependency in package.Meta.Dependencies)
            {
                var loadedPackage = session.Packages.Find(packageDependency);
                if (loadedPackage == null)
                {
                    var file = PackageStore.Instance.GetPackageFileName(packageDependency.Name, packageDependency.Version, session.constraintProvider);

                    if (file == null)
                    {
                        // TODO: We need to support automatic download of packages. This is not supported yet when only Xenko
                        // package is supposed to be installed, but It will be required for full store
                        log.Error("Unable to find package {0} not installed", packageDependency);
                        packageDependencyErrors = true;
                        continue;
                    }

                    // Recursive load of the system package
                    loadedPackage = PreLoadPackage(session, log, file, true, loadedPackages, loadParameters);
                }

                if (loadedPackage == null || loadedPackage.State < PackageState.DependenciesReady)
                    packageDependencyErrors = true;
            }

            // 2. Load local packages
            foreach (var packageReference in package.LocalDependencies)
            {
                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageReference.Id))
                {
                    continue;
                }

                // Expand the string of the location
                var newLocation = (UFile)AssetRegistry.ExpandString(session, packageReference.Location);

                var subPackageFilePath = package.RootDirectory != null ? UPath.Combine(package.RootDirectory, newLocation) : newLocation;

                // Recursive load
                var loadedPackage = PreLoadPackage(session, log, subPackageFilePath.FullPath, false, loadedPackages, loadParameters);

                if (loadedPackage == null || loadedPackage.State < PackageState.DependenciesReady)
                    packageDependencyErrors = true;
            }

            // 3. Update package state
            if (!packageDependencyErrors)
            {
                package.State = PackageState.DependenciesReady;
            }
        }
示例#12
0
        PackageUpgrader CheckPackageUpgrade(ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage)
        {
            // Don't do anything if source is a system (read-only) package for now
            // We only want to process local packages
            if (dependentPackage.IsSystem)
                return null;

            // Check if package might need upgrading
            var dependentPackagePreviousMinimumVersion = dependency.Version.MinVersion;
            if (dependentPackagePreviousMinimumVersion < dependencyPackage.Meta.Version)
            {
                // Find upgrader for given package
                // Note: If no upgrader is found, we assume it is still compatible with previous versions, so do nothing
                var packageUpgrader = AssetRegistry.GetPackageUpgrader(dependencyPackage.Meta.Name);
                if (packageUpgrader != null)
                {
                    // Check if upgrade is necessary
                    if (dependency.Version.MinVersion >= packageUpgrader.Attribute.PackageUpdatedVersionRange.MinVersion)
                    {
                        return null;
                    }

                    // Check if upgrade is allowed
                    if (dependency.Version.MinVersion < packageUpgrader.Attribute.PackageMinimumVersion)
                    {
                        // Throw an exception, because the package update is not allowed and can't be done
                        throw new InvalidOperationException(string.Format("Upgrading package [{0}] to use [{1}] from version [{2}] to [{3}] is not supported", dependentPackage.Meta.Name, dependencyPackage.Meta.Name, dependentPackagePreviousMinimumVersion, dependencyPackage.Meta.Version));
                    }

                    log.Info("Upgrading package [{0}] to use [{1}] from version [{2}] to [{3}] will be required", dependentPackage.Meta.Name, dependencyPackage.Meta.Name, dependentPackagePreviousMinimumVersion, dependencyPackage.Meta.Version);
                    return packageUpgrader;
                }
            }

            return null;
        }
示例#13
0
        private static bool TryLoadAssets(PackageSession session, ILogger log, Package package, PackageLoadParameters loadParameters)
        {
            // Already loaded
            if (package.State >= PackageState.AssetsReady)
                return true;

            // Dependencies could not properly be loaded
            if (package.State < PackageState.DependenciesReady)
                return false;

            // A package upgrade has previously been tried and denied, so let's keep the package in this state
            if (package.State == PackageState.UpgradeFailed)
                return false;

            try
            {
                // First, check that dependencies have their assets loaded
                bool dependencyError = false;
                foreach (var dependency in package.FindDependencies(false, false))
                {
                    if (!TryLoadAssets(session, log, dependency, loadParameters))
                        dependencyError = true;
                }

                if (dependencyError)
                    return false;

                var pendingPackageUpgrades = new List<PendingPackageUpgrade>();

                // Note: Default state is upgrade failed (for early exit on error/exceptions)
                // We will update to success as soon as loading is finished.
                package.State = PackageState.UpgradeFailed;

                // Process store dependencies for upgraders
                foreach (var packageDependency in package.Meta.Dependencies)
                {
                    var dependencyPackage = session.Packages.Find(packageDependency);
                    if (dependencyPackage == null)
                    {
                        continue;
                    }

                    // Check for upgraders
                    var packageUpgrader = session.CheckPackageUpgrade(log, package, packageDependency, dependencyPackage);
                    if (packageUpgrader != null)
                    {
                        pendingPackageUpgrades.Add(new PendingPackageUpgrade(packageUpgrader, packageDependency, dependencyPackage));
                    }
                }

                // Prepare asset loading
                var newLoadParameters = loadParameters.Clone();
                newLoadParameters.AssemblyContainer = session.assemblyContainer;

                // Default package version override
                newLoadParameters.ExtraCompileProperties = new Dictionary<string, string>();
                var defaultPackageOverride = NugetStore.GetPackageVersionVariable(PackageStore.Instance.DefaultPackageName) + "Override";
                var defaultPackageVersion = PackageStore.Instance.DefaultPackageVersion.Version;
                newLoadParameters.ExtraCompileProperties.Add(defaultPackageOverride, new Version(defaultPackageVersion.Major, defaultPackageVersion.Minor).ToString());
                if (loadParameters.ExtraCompileProperties != null)
                {
                    foreach (var property in loadParameters.ExtraCompileProperties)
                    {
                        newLoadParameters.ExtraCompileProperties[property.Key] = property.Value;
                    }
                }

                if (pendingPackageUpgrades.Count > 0)
                {
                    var upgradeAllowed = true;
                    // Need upgrades, let's ask user confirmation
                    if (loadParameters.PackageUpgradeRequested != null)
                    {
                        upgradeAllowed = loadParameters.PackageUpgradeRequested(package, pendingPackageUpgrades);
                    }

                    if (!upgradeAllowed)
                    {
                        log.Error("Necessary package migration for [{0}] has not been allowed", package.Meta.Name);
                        return false;
                    }

                    // Perform pre assembly load upgrade
                    foreach (var pendingPackageUpgrade in pendingPackageUpgrades)
                    {
                        var packageUpgrader = pendingPackageUpgrade.PackageUpgrader;
                        var dependencyPackage = pendingPackageUpgrade.DependencyPackage;
                        if (!packageUpgrader.UpgradeBeforeAssembliesLoaded(session, log, package, pendingPackageUpgrade.Dependency, dependencyPackage))
                        {
                            log.Error("Error while upgrading package [{0}] for [{1}] from version [{2}] to [{3}]", package.Meta.Name, dependencyPackage.Meta.Name, pendingPackageUpgrade.Dependency.Version, dependencyPackage.Meta.Version);
                            return false;
                        }
                    }
                }

                // Load assemblies. Set the package filename to the path on disk, in case of renaming.
                // TODO: Could referenced projects be associated to other packages than this one?
                newLoadParameters.ExtraCompileProperties.Add("SiliconStudioCurrentPackagePath", package.FullPath);
                package.LoadAssemblies(log, newLoadParameters);

                // Load list of assets
                newLoadParameters.AssetFiles = Package.ListAssetFiles(log, package, loadParameters.CancelToken);

                if (pendingPackageUpgrades.Count > 0)
                {
                    // Perform upgrades
                    foreach (var pendingPackageUpgrade in pendingPackageUpgrades)
                    {
                        var packageUpgrader = pendingPackageUpgrade.PackageUpgrader;
                        var dependencyPackage = pendingPackageUpgrade.DependencyPackage;
                        if (!packageUpgrader.Upgrade(session, log, package, pendingPackageUpgrade.Dependency, dependencyPackage, newLoadParameters.AssetFiles))
                        {
                            log.Error("Error while upgrading package [{0}] for [{1}] from version [{2}] to [{3}]", package.Meta.Name, dependencyPackage.Meta.Name, pendingPackageUpgrade.Dependency.Version, dependencyPackage.Meta.Version);
                            return false;
                        }

                        // Update dependency to reflect new requirement
                        pendingPackageUpgrade.Dependency.Version = pendingPackageUpgrade.PackageUpgrader.Attribute.PackageUpdatedVersionRange;
                    }

                    // Mark package as dirty
                    package.IsDirty = true;
                }

                // Load assets
                package.LoadAssets(log, newLoadParameters);

                // Validate assets from package
                package.ValidateAssets(newLoadParameters.GenerateNewAssetIds);

                if (pendingPackageUpgrades.Count > 0)
                {
                    // Perform post asset load upgrade
                    foreach (var pendingPackageUpgrade in pendingPackageUpgrades)
                    {
                        var packageUpgrader = pendingPackageUpgrade.PackageUpgrader;
                        var dependencyPackage = pendingPackageUpgrade.DependencyPackage;
                        if (!packageUpgrader.UpgradeAfterAssetsLoaded(session, log, package, pendingPackageUpgrade.Dependency, dependencyPackage, pendingPackageUpgrade.DependencyVersionBeforeUpgrade))
                        {
                            log.Error("Error while upgrading package [{0}] for [{1}] from version [{2}] to [{3}]", package.Meta.Name, dependencyPackage.Meta.Name, pendingPackageUpgrade.Dependency.Version, dependencyPackage.Meta.Version);
                            return false;
                        }
                    }

                    // Mark package as dirty
                    package.IsDirty = true;
                }

                // Mark package as ready
                package.State = PackageState.AssetsReady;

                // Freeze the package after loading the assets
                session.FreezePackage(package);

                return true;
            }
            catch (Exception ex)
            {
                log.Error("Error while loading package [{0}]", ex, package);
                return false;
            }
        }
示例#14
0
        private static bool TryLoadAssets(PackageSession session, ILogger log, Package package, PackageLoadParameters loadParameters)
        {
            // Already loaded
            if (package.State >= PackageState.AssetsReady)
            {
                return(true);
            }

            // Dependencies could not properly be loaded
            if (package.State < PackageState.DependenciesReady)
            {
                return(false);
            }

            // A package upgrade has previously been tried and denied, so let's keep the package in this state
            if (package.State == PackageState.UpgradeFailed)
            {
                return(false);
            }

            try
            {
                // First, check that dependencies have their assets loaded
                bool dependencyError = false;
                foreach (var dependency in package.FindDependencies(false, false))
                {
                    if (!TryLoadAssets(session, log, dependency, loadParameters))
                    {
                        dependencyError = true;
                    }
                }

                if (dependencyError)
                {
                    return(false);
                }

                var pendingPackageUpgrades = new List <PendingPackageUpgrade>();

                // Note: Default state is upgrade failed (for early exit on error/exceptions)
                // We will update to success as soon as loading is finished.
                package.State = PackageState.UpgradeFailed;

                // Process store dependencies for upgraders
                foreach (var packageDependency in package.Meta.Dependencies)
                {
                    var dependencyPackage = session.Packages.Find(packageDependency);
                    if (dependencyPackage == null)
                    {
                        continue;
                    }

                    // Check for upgraders
                    var packageUpgrader = session.CheckPackageUpgrade(log, package, packageDependency, dependencyPackage);
                    if (packageUpgrader != null)
                    {
                        pendingPackageUpgrades.Add(new PendingPackageUpgrade(packageUpgrader, packageDependency, dependencyPackage));
                    }
                }

                // Load list of assets
                var assetFiles = Package.ListAssetFiles(log, package, loadParameters.CancelToken);

                if (pendingPackageUpgrades.Count > 0)
                {
                    var upgradeAllowed = true;
                    // Need upgrades, let's ask user confirmation
                    if (loadParameters.PackageUpgradeRequested != null)
                    {
                        upgradeAllowed = loadParameters.PackageUpgradeRequested(package, pendingPackageUpgrades);
                    }

                    if (!upgradeAllowed)
                    {
                        log.Error("Necessary package migration for [{0}] has not been allowed", package.Meta.Name);
                        return(false);
                    }

                    // Perform upgrades
                    foreach (var pendingPackageUpgrade in pendingPackageUpgrades)
                    {
                        var packageUpgrader   = pendingPackageUpgrade.PackageUpgrader;
                        var dependencyPackage = pendingPackageUpgrade.DependencyPackage;
                        if (!packageUpgrader.Upgrade(session, log, package, pendingPackageUpgrade.Dependency, dependencyPackage, assetFiles))
                        {
                            log.Error("Error while upgrading package [{0}] for [{1}] from version [{2}] to [{3}]", package.Meta.Name, dependencyPackage.Meta.Name, pendingPackageUpgrade.Dependency.Version, dependencyPackage.Meta.Version);
                            return(false);
                        }

                        // Update dependency to reflect new requirement
                        pendingPackageUpgrade.Dependency.Version = pendingPackageUpgrade.PackageUpgrader.Attribute.PackageUpdatedVersionRange;
                    }

                    // Mark package as dirty
                    package.IsDirty = true;
                }

                // Process the package for assets
                var newLoadParameters = loadParameters.Clone();
                newLoadParameters.AssetFiles        = assetFiles;
                newLoadParameters.AssemblyContainer = session.assemblyContainer;

                // Default package version override
                newLoadParameters.ExtraCompileProperties = new Dictionary <string, string>();
                var defaultPackageOverride = NugetStore.GetPackageVersionVariable(PackageStore.Instance.DefaultPackageName) + "Override";
                var defaultPackageVersion  = PackageStore.Instance.DefaultPackageVersion.Version;
                newLoadParameters.ExtraCompileProperties.Add(defaultPackageOverride, new Version(defaultPackageVersion.Major, defaultPackageVersion.Minor).ToString());
                if (loadParameters.ExtraCompileProperties != null)
                {
                    foreach (var property in loadParameters.ExtraCompileProperties)
                    {
                        newLoadParameters.ExtraCompileProperties[property.Key] = property.Value;
                    }
                }

                // Load assemblies and assets
                package.LoadAssembliesAndAssets(log, newLoadParameters);

                // Validate assets from package
                package.ValidateAssets(newLoadParameters.GenerateNewAssetIds);

                // Mark package as ready
                package.State = PackageState.AssetsReady;

                // Freeze the package after loading the assets
                session.FreezePackage(package);

                return(true);
            }
            catch (Exception ex)
            {
                log.Error("Error while loading package [{0}]", ex, package);
                return(false);
            }
        }
示例#15
0
        private static Package PreLoadPackage(PackageSession session, ILogger log, string filePath, bool isSystemPackage, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }
            if (log == null)
            {
                throw new ArgumentNullException("log");
            }
            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }
            if (loadedPackages == null)
            {
                throw new ArgumentNullException("loadedPackages");
            }
            if (loadParameters == null)
            {
                throw new ArgumentNullException("loadParameters");
            }

            try
            {
                var packageId = Package.GetPackageIdFromFile(filePath);

                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageId))
                {
                    return(session.Packages.Find(packageId));
                }

                // Package is already loaded, use the instance
                if (loadedPackages.ContainsById(packageId))
                {
                    return(loadedPackages.Find(packageId));
                }

                // Load the package without loading any assets
                var package = Package.LoadRaw(log, filePath);
                package.IsSystem = isSystemPackage;

                // Convert UPath to absolute (Package only)
                // Removed for now because it is called again in PackageSession.LoadAssembliesAndAssets (and running it twice result in dirty package)
                // If we remove it from here (and call it only in the other method), templates are not loaded (Because they are loaded via the package store that do not use PreLoadPackage)
                //if (loadParameters.ConvertUPathToAbsolute)
                //{
                //    var analysis = new PackageAnalysis(package, new PackageAnalysisParameters()
                //    {
                //        ConvertUPathTo = UPathType.Absolute,
                //        SetDirtyFlagOnAssetWhenFixingAbsoluteUFile = true,
                //        IsProcessingUPaths = true,
                //    });
                //    analysis.Run(log);
                //}
                // If the package doesn't have a meta name, fix it here (This is supposed to be done in the above disabled analysis - but we still need to do it!)
                if (string.IsNullOrWhiteSpace(package.Meta.Name) && package.FullPath != null)
                {
                    package.Meta.Name = package.FullPath.GetFileName();
                    package.IsDirty   = true;
                }

                // Add the package has loaded before loading dependencies
                loadedPackages.Add(package);

                // Package has been loaded, register it in constraints so that we force each subsequent loads to use this one (or fails if version doesn't match)
                session.constraintProvider.AddConstraint(package.Meta.Name, new VersionSpec(package.Meta.Version.ToSemanticVersion()));

                // Load package dependencies
                // This will perform necessary asset upgrades
                // TODO: We should probably split package loading in two recursive top-level passes (right now those two passes are mixed, making it more difficult to make proper checks)
                //   - First, load raw packages with their dependencies recursively, then resolve dependencies and constraints (and print errors/warnings)
                //   - Then, if everything is OK, load the actual references and assets for each packages
                PreLoadPackageDependencies(session, log, package, loadedPackages, loadParameters);

                // Add the package to the session but don't freeze it yet
                session.Packages.Add(package);

                return(package);
            }
            catch (Exception ex)
            {
                log.Error("Error while pre-loading package [{0}]", ex, filePath);
            }

            return(null);
        }
示例#16
0
        private static Package PreLoadPackage(PackageSession session, ILogger log, string filePath, bool isSystemPackage, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null) throw new ArgumentNullException("session");
            if (log == null) throw new ArgumentNullException("log");
            if (filePath == null) throw new ArgumentNullException("filePath");
            if (loadedPackages == null) throw new ArgumentNullException("loadedPackages");
            if (loadParameters == null) throw new ArgumentNullException("loadParameters");

            try
            {
                var packageId = Package.GetPackageIdFromFile(filePath);

                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageId))
                {
                    return session.Packages.Find(packageId);
                }

                // Package is already loaded, use the instance 
                if (loadedPackages.ContainsById(packageId))
                {
                    return loadedPackages.Find(packageId);
                }

                // Load the package without loading assets
                var newLoadParameters = loadParameters.Clone();
                newLoadParameters.AssemblyContainer = session.assemblyContainer;

                // Load the package
                var package = Package.Load(log, filePath, newLoadParameters);
                package.IsSystem = isSystemPackage;

                // Add the package has loaded before loading dependencies
                loadedPackages.Add(package);

                // Package has been loaded, register it in constraints so that we force each subsequent loads to use this one (or fails if version doesn't match)
                session.constraintProvider.AddConstraint(package.Meta.Name, new VersionSpec(package.Meta.Version.ToSemanticVersion()));

                // Load package dependencies
                PreLoadPackageDependencies(session, log, package, loadedPackages, loadParameters);

                // Add the package to the session but don't freeze it yet
                session.Packages.Add(package);

                // Validate assets from package
                package.ValidateAssets(loadParameters.GenerateNewAssetIds);

                // Freeze the package after loading the assets
                session.FreezePackage(package);

                return package;
            }
            catch (Exception ex)
            {
                log.Error("Error while pre-loading package [{0}]", ex, filePath);
            }

            return null;
        }
示例#17
0
        private static Package PreLoadPackage(PackageSession session, ILogger log, string filePath, bool isSystemPackage, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null) throw new ArgumentNullException("session");
            if (log == null) throw new ArgumentNullException("log");
            if (filePath == null) throw new ArgumentNullException("filePath");
            if (loadedPackages == null) throw new ArgumentNullException("loadedPackages");
            if (loadParameters == null) throw new ArgumentNullException("loadParameters");

            try
            {
                var packageId = Package.GetPackageIdFromFile(filePath);

                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageId))
                {
                    return session.Packages.Find(packageId);
                }

                // Package is already loaded, use the instance 
                if (loadedPackages.ContainsById(packageId))
                {
                    return loadedPackages.Find(packageId);
                }

                // Load the package without loading any assets
                var package = Package.LoadRaw(log, filePath);
                package.IsSystem = isSystemPackage;

                // Convert UPath to absolute (Package only)
                // Removed for now because it is called again in PackageSession.LoadAssembliesAndAssets (and running it twice result in dirty package)
                // If we remove it from here (and call it only in the other method), templates are not loaded (Because they are loaded via the package store that do not use PreLoadPackage)
                //if (loadParameters.ConvertUPathToAbsolute)
                //{
                //    var analysis = new PackageAnalysis(package, new PackageAnalysisParameters()
                //    {
                //        ConvertUPathTo = UPathType.Absolute,
                //        SetDirtyFlagOnAssetWhenFixingAbsoluteUFile = true,
                //        IsProcessingUPaths = true,
                //    });
                //    analysis.Run(log);
                //}
                // If the package doesn't have a meta name, fix it here (This is supposed to be done in the above disabled analysis - but we still need to do it!)
                if (string.IsNullOrWhiteSpace(package.Meta.Name) && package.FullPath != null)
                {
                    package.Meta.Name = package.FullPath.GetFileName();
                    package.IsDirty = true;
                }

                // Add the package has loaded before loading dependencies
                loadedPackages.Add(package);

                // Package has been loaded, register it in constraints so that we force each subsequent loads to use this one (or fails if version doesn't match)
                session.constraintProvider.AddConstraint(package.Meta.Name, new VersionSpec(package.Meta.Version.ToSemanticVersion()));

                // Load package dependencies
                // This will perform necessary asset upgrades
                // TODO: We should probably split package loading in two recursive top-level passes (right now those two passes are mixed, making it more difficult to make proper checks)
                //   - First, load raw packages with their dependencies recursively, then resolve dependencies and constraints (and print errors/warnings)
                //   - Then, if everything is OK, load the actual references and assets for each packages
                PreLoadPackageDependencies(session, log, package, loadedPackages, loadParameters);

                // Add the package to the session but don't freeze it yet
                session.Packages.Add(package);

                return package;
            }
            catch (Exception ex)
            {
                log.Error("Error while pre-loading package [{0}]", ex, filePath);
            }

            return null;
        }
示例#18
0
 /// <summary>
 /// Make sure packages have their dependencies and assets loaded.
 /// </summary>
 /// <param name="log">The log.</param>
 /// <param name="loadParameters">The load parameters.</param>
 public void LoadMissingReferences(ILogger log, PackageLoadParameters loadParameters = null)
 {
     LoadMissingDependencies(log, loadParameters);
     LoadMissingAssets(log, loadParameters);
 }
示例#19
0
        private static void PreLoadPackageDependencies(PackageSession session, ILogger log, Package package, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }
            if (log == null)
            {
                throw new ArgumentNullException("log");
            }
            if (package == null)
            {
                throw new ArgumentNullException("package");
            }
            if (loadParameters == null)
            {
                throw new ArgumentNullException("loadParameters");
            }

            bool packageDependencyErrors = false;

            // TODO: Remove and recheck Dependencies Ready if some secondary packages are removed?
            if (package.State >= PackageState.DependenciesReady)
            {
                return;
            }

            // 1. Load store package
            foreach (var packageDependency in package.Meta.Dependencies)
            {
                var loadedPackage = session.Packages.Find(packageDependency);
                if (loadedPackage == null)
                {
                    var file = PackageStore.Instance.GetPackageFileName(packageDependency.Name, packageDependency.Version, session.constraintProvider);

                    if (file == null)
                    {
                        // TODO: We need to support automatic download of packages. This is not supported yet when only Paradox
                        // package is supposed to be installed, but It will be required for full store
                        log.Error("Unable to find package {0} not installed", packageDependency);
                        packageDependencyErrors = true;
                        continue;
                    }

                    // Recursive load of the system package
                    loadedPackage = PreLoadPackage(session, log, file, true, loadedPackages, loadParameters);
                }

                if (loadedPackage == null || loadedPackage.State < PackageState.DependenciesReady)
                {
                    packageDependencyErrors = true;
                }
            }

            // 2. Load local packages
            foreach (var packageReference in package.LocalDependencies)
            {
                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageReference.Id))
                {
                    continue;
                }

                // Expand the string of the location
                var newLocation = (UFile)AssetRegistry.ExpandString(session, packageReference.Location);

                var subPackageFilePath = package.RootDirectory != null?UPath.Combine(package.RootDirectory, newLocation) : newLocation;

                // Recursive load
                var loadedPackage = PreLoadPackage(session, log, subPackageFilePath.FullPath, false, loadedPackages, loadParameters);

                if (loadedPackage == null || loadedPackage.State < PackageState.DependenciesReady)
                {
                    packageDependencyErrors = true;
                }
            }

            // 3. Update package state
            if (!packageDependencyErrors)
            {
                package.State = PackageState.DependenciesReady;
            }
        }
示例#20
0
        public static string GetOrCompileProjectAssembly(string solutionFullPath, string fullProjectLocation, ILogger logger, string targets, bool autoCompileProject, string configuration, string platform = "AnyCPU", Dictionary <string, string> extraProperties = null, bool onlyErrors = false, BuildRequestDataFlags flags = BuildRequestDataFlags.None)
        {
            if (fullProjectLocation == null)
            {
                throw new ArgumentNullException("fullProjectLocation");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            var project      = LoadProject(fullProjectLocation, configuration, platform, extraProperties);
            var assemblyPath = project.GetPropertyValue("TargetPath");

            try
            {
                if (!string.IsNullOrWhiteSpace(assemblyPath))
                {
                    if (autoCompileProject)
                    {
                        // NuGet restore
                        // TODO: We might want to call this less regularly than every build (i.e. project creation, and project.json update?)
                        // Probably not worth bothering since it might be part of MSBuild with VS15
                        var restoreNugetTask = RestoreNugetPackages(logger, solutionFullPath, project);

                        var asyncBuild = new CancellableAsyncBuild(project, assemblyPath);
                        asyncBuild.Build(restoreNugetTask, project, "Build", flags, new LoggerRedirect(logger, onlyErrors));
                        var buildResult = asyncBuild.BuildTask.Result;
                    }
                }
            }
            finally
            {
                project.ProjectCollection.UnloadAllProjects();
                project.ProjectCollection.Dispose();
            }

            return(assemblyPath);
        }
示例#21
0
 public YamlForwardLogger(ILogger logger)
 {
     this.logger = logger;
 }
示例#22
0
        /// <summary>
        /// Make sure packages have their assets loaded.
        /// </summary>
        /// <param name="log">The log.</param>
        /// <param name="loadParametersArg">The load parameters argument.</param>
        public void LoadMissingAssets(ILogger log, PackageLoadParameters loadParametersArg = null)
        {
            var loadParameters = loadParametersArg ?? PackageLoadParameters.Default();

            var cancelToken = loadParameters.CancelToken;

            // Make a copy of Packages as it can be modified by PreLoadPackageDependencies
            var previousPackages = Packages.ToList();
            foreach (var package in previousPackages)
            {
                // Output the session only if there is no cancellation
                if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested)
                {
                    return;
                }

                TryLoadAssets(this, log, package, loadParameters);
            }
        }
示例#23
0
 /// <summary>
 /// Make sure packages have their dependencies and assets loaded.
 /// </summary>
 /// <param name="log">The log.</param>
 /// <param name="loadParameters">The load parameters.</param>
 public void LoadMissingReferences(ILogger log, PackageLoadParameters loadParameters = null)
 {
     LoadMissingDependencies(log, loadParameters);
     LoadMissingAssets(log, loadParameters);
 }
示例#24
0
 public YamlForwardLogger(ILogger logger)
 {
     this.logger = logger;
 }
示例#25
0
        public static ICancellableAsyncBuild CompileProjectAssemblyAsync(string fullProjectLocation, ILogger logger, string targets = "Build", string configuration = "Debug", string platform = "AnyCPU", Dictionary <string, string> extraProperties = null, BuildRequestDataFlags flags = BuildRequestDataFlags.None)
        {
            if (fullProjectLocation == null)
            {
                throw new ArgumentNullException("fullProjectLocation");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            var project      = LoadProject(fullProjectLocation, configuration, platform, extraProperties);
            var assemblyPath = project.GetPropertyValue("TargetPath");

            if (!string.IsNullOrWhiteSpace(assemblyPath))
            {
                var asyncBuild = new CancellableAsyncBuild(project, assemblyPath);
                asyncBuild.Build(project, targets, flags, new LoggerRedirect(logger));
                return(asyncBuild);
            }

            return(null);
        }