/// <summary>
        /// Initializes a new instance of the <see cref="PackageStore"/> class.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">Unable to find a valid Xenko installation path</exception>
        private PackageStore(string installationPath = null, string defaultPackageName = "Xenko", string defaultPackageVersion = XenkoVersion.CurrentAsText)
        {
            // TODO: these are currently hardcoded to Xenko
            DefaultPackageName      = defaultPackageName;
            DefaultPackageVersion   = new PackageVersion(defaultPackageVersion);
            defaultPackageDirectory = DirectoryHelper.GetPackageDirectory(defaultPackageName);

            // 1. Try to use the specified installation path
            if (installationPath != null)
            {
                if (!DirectoryHelper.IsInstallationDirectory(installationPath))
                {
                    throw new ArgumentException("Invalid Xenko installation path [{0}]".ToFormat(installationPath), "installationPath");
                }

                globalInstallationPath = installationPath;
            }

            // 2. Try to resolve an installation path from the path of this assembly
            // We need to be able to use the package manager from an official Xenko install as well as from a developer folder
            if (globalInstallationPath == null)
            {
                globalInstallationPath = DirectoryHelper.GetInstallationDirectory(DefaultPackageName);
            }

            // If there is no root, this is an error
            if (globalInstallationPath == null)
            {
                throw new InvalidOperationException("Unable to find a valid Xenko installation or dev path");
            }

            // Preload default package
            var logger             = new LoggerResult();
            var defaultPackageFile = DirectoryHelper.GetPackageFile(defaultPackageDirectory, DefaultPackageName);

            defaultPackage = Package.Load(logger, defaultPackageFile, GetDefaultPackageLoadParameters());
            if (defaultPackage == null)
            {
                throw new InvalidOperationException("Error while loading default package from [{0}]: {1}".ToFormat(defaultPackageFile, logger.ToText()));
            }
            defaultPackage.IsSystem = true;

            // A flag variable just to know if it is a bare bone development directory
            isDev = defaultPackageDirectory != null && DirectoryHelper.IsRootDevDirectory(defaultPackageDirectory);

            // Check if we are in a root directory with store/packages facilities
            if (NugetStore.IsStoreDirectory(globalInstallationPath))
            {
                packagesDirectory = UPath.Combine(globalInstallationPath, (UDirectory)NugetStore.DefaultGamePackagesDirectory);
                store             = new NugetStore(globalInstallationPath);
            }
            else
            {
                // We should exit from here if NuGet is not configured.
                MessageBox.Show($"Unexpected installation. Cannot find a proper NuGet configuration for [{defaultPackageName}] in [{globalInstallationPath}]", "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(1);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Gets the paradox SDK dir.
        /// </summary>
        /// <param name="paradoxVersion">The paradox version. If null, it will get latest version.</param>
        /// <returns></returns>
        public static string FindParadoxSdkDir(string paradoxVersion = null)
        {
            // TODO: Almost duplicate of ParadoxCommandsProxy.FindParadoxSdkDir!!
            // TODO: Maybe move it in some common class somewhere? (in this case it would be included with "Add as link" in VSPackage)
            var paradoxSdkDir = DirectoryHelper.GetInstallationDirectory("Paradox");

            if (paradoxSdkDir == null)
            {
                paradoxSdkDir = Environment.GetEnvironmentVariable("SiliconStudioParadoxDir");
            }

            if (paradoxSdkDir == null)
            {
                return null;
            }

            // Check if it is a dev directory
            if (File.Exists(Path.Combine(paradoxSdkDir, "build\\Paradox.sln")))
                return paradoxSdkDir;

            // Check if we are in a root directory with store/packages facilities
            if (NugetStore.IsStoreDirectory(paradoxSdkDir))
            {
                var store = new NugetStore(paradoxSdkDir);

                var paradoxPackages = store.GetPackagesInstalled(store.MainPackageId);
                var paradoxPackage = paradoxVersion != null
                    ? (paradoxPackages.FirstOrDefault(p => p.Version.ToString() == paradoxVersion)
                        ?? paradoxPackages.FirstOrDefault(p => VersionWithoutSpecialPart(p.Version.ToString()) == VersionWithoutSpecialPart(paradoxVersion))) // If no exact match, try a second time without the special version tag (beta, alpha, etc...)
                    : paradoxPackages.FirstOrDefault();
                if (paradoxPackage == null)
                    return null;

                var packageDirectory = store.PathResolver.GetPackageDirectory(paradoxPackage);
                return Path.Combine(paradoxSdkDir, store.RepositoryPath, packageDirectory);
            }

            return null;
        }
        /// <summary>
        /// Gets the paradox SDK dir.
        /// </summary>
        /// <returns></returns>
        private static string FindParadoxSdkDir()
        {
            // TODO: Get the Paradox SDK from the current selected package

            // TODO: Maybe move it in some common class somewhere? (in this case it would be included with "Add as link" in VSPackage)
            var paradoxSdkDir = Environment.GetEnvironmentVariable("SiliconStudioParadoxDir");

            if (paradoxSdkDir == null)
            {
                return null;
            }

            // Check if it is a dev directory
            if (File.Exists(Path.Combine(paradoxSdkDir, "build\\Paradox.sln")))
                return paradoxSdkDir;

            // Check if we are in a root directory with store/packages facilities
            if (NugetStore.IsStoreDirectory(paradoxSdkDir))
            {
                var store = new NugetStore(paradoxSdkDir);

                var paradoxPackage = store.GetLatestPackageInstalled(store.MainPackageId);
                if (paradoxPackage == null)
                    return null;

                var packageDirectory = store.PathResolver.GetPackageDirectory(paradoxPackage);
                return Path.Combine(paradoxSdkDir, store.RepositoryPath, packageDirectory);
            }

            return null;
        }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PackageStore"/> class.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">Unable to find a valid Xenko installation path</exception>
        private PackageStore(string installationPath = null, string defaultPackageName = "Xenko", string defaultPackageVersion = XenkoVersion.CurrentAsText)
        {
            // TODO: these are currently hardcoded to Xenko
            DefaultPackageName = defaultPackageName;
            DefaultPackageVersion = new PackageVersion(defaultPackageVersion);
            defaultPackageDirectory = DirectoryHelper.GetPackageDirectory(defaultPackageName);
   
            // 1. Try to use the specified installation path
            if (installationPath != null)
            {
                if (!DirectoryHelper.IsInstallationDirectory(installationPath))
                {
                    throw new ArgumentException("Invalid Xenko installation path [{0}]".ToFormat(installationPath), "installationPath");
                }

                globalInstallationPath = installationPath;
            }

            // 2. Try to resolve an installation path from the path of this assembly
            // We need to be able to use the package manager from an official Xenko install as well as from a developer folder
            if (globalInstallationPath == null)
            {
                globalInstallationPath = DirectoryHelper.GetInstallationDirectory(DefaultPackageName);
            }

            // If there is no root, this is an error
            if (globalInstallationPath == null)
            {
                throw new InvalidOperationException("Unable to find a valid Xenko installation or dev path");
            }

            // Preload default package
            var logger = new LoggerResult();
            var defaultPackageFile = DirectoryHelper.GetPackageFile(defaultPackageDirectory, DefaultPackageName);
            defaultPackage = Package.Load(logger, defaultPackageFile, GetDefaultPackageLoadParameters());
            if (defaultPackage == null)
            {
                throw new InvalidOperationException("Error while loading default package from [{0}]: {1}".ToFormat(defaultPackageFile, logger.ToText()));
            }
            defaultPackage.IsSystem = true;

            // A flag variable just to know if it is a bare bone development directory
            isDev = defaultPackageDirectory != null && DirectoryHelper.IsRootDevDirectory(defaultPackageDirectory);

            // Check if we are in a root directory with store/packages facilities
            if (NugetStore.IsStoreDirectory(globalInstallationPath))
            {
                packagesDirectory = UPath.Combine(globalInstallationPath, (UDirectory)NugetStore.DefaultGamePackagesDirectory);
                store = new NugetStore(globalInstallationPath);
            }
            else
            {
                // We should exit from here if NuGet is not configured.
                MessageBox.Show($"Unexpected installation. Cannot find a proper NuGet configuration for [{defaultPackageName}] in [{globalInstallationPath}]", "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(1);
            }
        }
Beispiel #5
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);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Gets the paradox SDK dir.
        /// </summary>
        /// <returns></returns>
        private static PackageInfo FindParadoxSdkDir()
        {
            // Resolve the sdk version to load from the solution's package
            var packageInfo = new PackageInfo { ExpectedVersion = PackageSessionHelper.GetPackageVersion(solution) };

            // TODO: Maybe move it in some common class somewhere? (in this case it would be included with "Add as link" in VSPackage)
            var paradoxSdkDir = Environment.GetEnvironmentVariable("SiliconStudioParadoxDir");

            // Failed to locate paradox
            if (paradoxSdkDir == null)
                return packageInfo;

            // If we are in a dev directory, assume we have the right version
            if (File.Exists(Path.Combine(paradoxSdkDir, "build\\Paradox.sln")))
            {
                packageInfo.SdkPath = paradoxSdkDir;
                packageInfo.LoadedVersion = packageInfo.ExpectedVersion;
                return packageInfo;
            }

            // Check if we are in a root directory with store/packages facilities
            if (NugetStore.IsStoreDirectory(paradoxSdkDir))
            {
                var store = new NugetStore(paradoxSdkDir);
                IPackage paradoxPackage = null;

                // Try to find the package with the expected version
                if (packageInfo.ExpectedVersion != null && packageInfo.ExpectedVersion >= MinimumVersion)
                    paradoxPackage = store.GetPackagesInstalled(store.MainPackageId).FirstOrDefault(package => GetVersion(package) == packageInfo.ExpectedVersion);

                // If the expected version is not found, get the latest package
                if (paradoxPackage == null)
                    paradoxPackage = store.GetLatestPackageInstalled(store.MainPackageId);

                // If no package was found, return no sdk path
                if (paradoxPackage == null)
                    return packageInfo;

                // Return the loaded version and the sdk path
                var packageDirectory = store.PathResolver.GetPackageDirectory(paradoxPackage);
                packageInfo.LoadedVersion = GetVersion(paradoxPackage);
                packageInfo.SdkPath = Path.Combine(paradoxSdkDir, store.RepositoryPath, packageDirectory);
            }

            return packageInfo;
        }
Beispiel #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PackageStore"/> class.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">Unable to find a valid Paradox installation path</exception>
        private PackageStore(string installationPath = null, string defaultPackageName = "Paradox", string defaultPackageVersion = ParadoxVersion.CurrentAsText)
        {
            // 1. Try to use the specified installation path
            if (installationPath != null)
            {
                if (!IsRootDirectory(installationPath))
                {
                    throw new ArgumentException("Invalid Paradox installation path [{0}]".ToFormat(installationPath), "installationPath");
                }

                globalInstallationPath = installationPath;
            }

            // TODO: these are currently hardcoded to Paradox
            DefaultPackageName    = defaultPackageName;
            DefaultPackageVersion = new PackageVersion(defaultPackageVersion);

            // 2. Try to resolve an installation path from the path of this assembly
            // We need to be able to use the package manager from an official Paradox install as well as from a developer folder

            // Try to determine the root package manager from the current assembly
            var thisAssemblyLocation = typeof(PackageStore).Assembly.Location;
            var binDirectory         = !string.IsNullOrWhiteSpace(thisAssemblyLocation) ? new FileInfo(thisAssemblyLocation).Directory : null;

            if (binDirectory != null && binDirectory.Parent != null && binDirectory.Parent.Parent != null)
            {
                var defaultPackageDirectoryTemp = binDirectory.Parent.Parent;

                // If we have a root directory, then store it as the default package directory
                if (IsPackageDirectory(defaultPackageDirectoryTemp.FullName, DefaultPackageName))
                {
                    defaultPackageDirectory = defaultPackageDirectoryTemp.FullName;
                }
                else
                {
                    throw new InvalidOperationException("The current assembly [{0}] is not part of the package [{1}]".ToFormat(thisAssemblyLocation, DefaultPackageName));
                }

                if (globalInstallationPath == null)
                {
                    // Check if we have a regular distribution
                    if (defaultPackageDirectoryTemp.Parent != null && IsRootDirectory(defaultPackageDirectoryTemp.Parent.FullName))
                    {
                        globalInstallationPath = defaultPackageDirectoryTemp.Parent.FullName;
                    }
                    else if (IsRootDirectory(defaultPackageDirectory))
                    {
                        // we have a dev distribution
                        globalInstallationPath = defaultPackageDirectory;
                    }
                }
            }

            // 3. Try from the environement variable
            if (globalInstallationPath == null)
            {
                var rootDirectory = Environment.GetEnvironmentVariable(DefaultEnvironmentSdkDir);
                if (!string.IsNullOrWhiteSpace(rootDirectory) && IsRootDirectory(rootDirectory))
                {
                    globalInstallationPath = rootDirectory;
                    if (defaultPackageDirectory == null)
                    {
                        defaultPackageDirectory = globalInstallationPath;
                    }
                }
            }

            // If there is no root, this is an error
            if (globalInstallationPath == null)
            {
                throw new InvalidOperationException("Unable to find a valid Paradox installation or dev path");
            }

            // Preload default package
            var logger             = new LoggerResult();
            var defaultPackageFile = GetPackageFile(defaultPackageDirectory, DefaultPackageName);

            defaultPackage = Package.Load(logger, defaultPackageFile, GetDefaultPackageLoadParameters());
            if (defaultPackage == null)
            {
                throw new InvalidOperationException("Error while loading default package from [{0}]: {1}".ToFormat(defaultPackageFile, logger.ToText()));
            }
            defaultPackage.IsSystem = true;

            // A flag variable just to know if it is a bare bone development directory
            isDev = defaultPackageDirectory != null && IsRootDevDirectory(defaultPackageDirectory);

            // Check if we are in a root directory with store/packages facilities
            if (NugetStore.IsStoreDirectory(globalInstallationPath))
            {
                packagesDirectory = UPath.Combine(globalInstallationPath, (UDirectory)NugetStore.DefaultGamePackagesDirectory);
                store             = new NugetStore(globalInstallationPath);
            }
        }
Beispiel #8
0
        public LauncherApp()
        {
            clock = Stopwatch.StartNew();
            IsProcessing = false;

            // TODO: Add a way to clear the cache more othen than the default nuget (>= 200 files)

            // Check config file
            DebugStep("Load store");

            // Get the package name and executable to launch/update
            var thisExeDirectory = Path.GetDirectoryName(typeof(LauncherApp).Assembly.Location);

            store = new NugetStore(thisExeDirectory);
            store.Manager.Logger = this;
            store.SourceRepository.Logger = this;

            mainPackage = store.MainPackageId;
            vsixPackage = store.VSIXPluginId;

            SdkVersionManager = new SDKVersionManager(store.Manager, mainPackage, vsixPackage);

            mainExecutable = store.Settings.GetConfigValue(MainExecutableKey);
            if (string.IsNullOrWhiteSpace(mainExecutable))
            {
                throw new LauncherAppException("Invalid configuration. Expecting [{0}] in config", MainExecutableKey);
            }

            var aggregateRepo = (AggregateRepository)store.Manager.SourceRepository;
            foreach (var repo in aggregateRepo.Repositories)
            {
                var progressProvider = repo as IProgressProvider;
                if (progressProvider != null)
                {
                    progressProvider.ProgressAvailable += OnProgressAvailable;
                }
            }

            downloadThreads = new List<Thread>();

            // Update the targets everytime the launcher is used in order to make sure targets are up-to-date
            // with packages installed (rewrite for example after a self-update)
            store.UpdateTargets();
        }