public sealed override bool Run(PackageTemplateGeneratorParameters parameters)
        {
            if (parameters == null) throw new ArgumentNullException(nameof(parameters));
            parameters.Validate();

            var logger = parameters.Logger;
            var name = parameters.Name;
            var package = parameters.Package;

            // Make sure we have a shared profile
            var sharedProfile = package.Profiles.FindSharedProfile();
            if (sharedProfile == null)
            {
                sharedProfile = PackageProfile.NewShared();
                package.Profiles.Add(sharedProfile);
            }

            // Log progress
            var projectName = name;
            ProjectTemplateGeneratorHelper.Progress(logger, $"Generating {projectName}...", 0, 1);

            // Generate the library
            List<string> generatedFiles;
            ProjectTemplateGeneratorHelper.AddOption(parameters, "Platforms", AssetRegistry.SupportedPlatforms);
            var projectGameRef = ProjectTemplateGeneratorHelper.GenerateTemplate(parameters, package, "ProjectLibrary/ProjectLibrary.ttproj", projectName, PlatformType.Shared, null, ProjectType.Library, out generatedFiles);
            projectGameRef.Type = ProjectType.Library;
            sharedProfile.ProjectReferences.Add(projectGameRef);

            // Log done
            ProjectTemplateGeneratorHelper.Progress(logger, "Done", 1, 1);
            return true;
        }
Esempio n. 2
0
        private static ProjectReference FindSharedGameProject(Package package, PackageProfile sharedProfile, ILogger logger)
        {
            if (sharedProfile == null)
            {
                throw new ArgumentNullException(nameof(sharedProfile));
            }

            // TODO: this is not a reliable way to get a game project see PDX-1128
            var gameProjectRef = sharedProfile.ProjectReferences.FirstOrDefault(projectRef => projectRef.Type == ProjectType.Library && projectRef.Location.FullPath.EndsWith("Game.csproj", StringComparison.InvariantCultureIgnoreCase));

            if (gameProjectRef == null)
            {
                logger.Error($"Unable to find the game project reference from the package [{package.Meta.Name}]");
                return(null);
            }
            return(gameProjectRef);
        }
Esempio n. 3
0
        /// <summary>
        /// Creates a new Xenko package with the specified name
        /// </summary>
        /// <param name="name">Name of the package</param>
        /// <returns>A new package instance</returns>
        public static Package NewPackage(string name)
        {
            var package = new Package
            {
                Meta =
                {
                    Name    = name,
                    Version = new PackageVersion("1.0.0.0")
                },
            };

            // Add dependency to latest Xenko package
            package.Meta.Dependencies.Add(XenkoConfig.GetLatestPackageDependency());

            // Setup the assets folder by default
            package.Profiles.Add(PackageProfile.NewShared());

            return(package);
        }
Esempio n. 4
0
        public ProfileViewModel(SessionViewModel session, Package package, PackageProfile profile, PackageViewModel container)
            : base(session.ServiceProvider)
        {
            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }
            if (profile == null)
            {
                throw new ArgumentNullException(nameof(profile));
            }
            this.session = session;
            this.package = package;
            this.profile = profile;

            Package = container;

            foreach (var projectReference in profile.ProjectReferences)
            {
                var viewModel = new ProjectViewModel(projectReference, this);
                Projects.Add(viewModel);
            }
        }
Esempio n. 5
0
        public static void Build(Package package, string outputDirectory = null)
        {
            if (package == null) throw new ArgumentNullException("package");

            var meta = new NuGet.ManifestMetadata();
            package.Meta.ToNugetManifest(meta);

            var builder = new NuGet.PackageBuilder();
            builder.Populate(meta);

            // TODO this is not working 
            var files = new List<NuGet.ManifestFile>()
                {
                    NewFile(@"Bin\**\*.exe", "Bin"),
                    NewFile(@"Bin\**\*.vsix", "Bin"),
                    NewFile(@"Bin\**\*.so", "Bin"),
                    NewFile(@"Bin\**\*.a", "Bin"),
                    NewFile(@"Bin\**\*.md", "Bin"),
                    NewFile(@"Bin\**\*.html", "Bin"),
                    NewFile(@"Bin\**\*.config", "Bin"),
                    NewFile(@"Bin\**\*.dll", "Bin"),
                    NewFile(@"Bin\**\*.xml", "Bin"),
                    NewFile(@"Bin\**\*.winmd", "Bin"),
                    NewFile(@"Targets\*.targets", "Targets"),
                };

            // Handle Assets
            var rootDir = package.RootDirectory;

            var newPackage = new Package { Meta = package.Meta };

            foreach (var profile in package.Profiles)
            {
                var target = "Assets/" + profile.Name;
                foreach (var assetFolder in profile.AssetFolders)
                {
                    // TODO: handle exclude in asset folders
                    //files.Add(NewFile(source, target, @"**\*.cs;**\*.hlsl;**\*.csproj;**\*.csproj.user;**\obj\**"));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.pdxsl", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.pdxfx", target));
                }

                var targetProfile = new PackageProfile(profile.Name);
                targetProfile.AssetFolders.Add(new AssetFolder(target));
                newPackage.Profiles.Add(targetProfile);
            }

            // Handle templates
            var targetFolder = new TemplateFolder("Templates");

            foreach (var templateFolder in package.TemplateFolders)
            {
                var source = templateFolder.Path.MakeRelative(rootDir) + "/**";
                UDirectory target = targetFolder.Path;
                if (templateFolder.Group != null)
                {
                    target = UPath.Combine(target, templateFolder.Group);
                }

                var excludeFiles = templateFolder.Exclude;
                files.Add(NewFile(source, target, excludeFiles));

                // Add template files
                foreach (var templateFile in templateFolder.Files)
                {
                    var newTemplateFile = templateFile.MakeRelative(templateFolder.Path);
                    if (templateFolder.Group != null)
                    {
                        newTemplateFile = UPath.Combine(templateFolder.Group, newTemplateFile);
                    }

                    newTemplateFile = UPath.Combine(targetFolder.Path, newTemplateFile);
                    targetFolder.Files.Add(newTemplateFile);
                }
            }

            // Create temp package for archive
            newPackage.TemplateFolders.Add(targetFolder);
            var newPackageFileName = "temp" + Guid.NewGuid() + ".pdxpkg";
            newPackage.FullPath = package.RootDirectory + "/" + newPackageFileName;
            var result = newPackage.Save();
            if (result.HasErrors)
            {
                throw new InvalidOperationException(result.ToText());
                // TODO throw error
            }
            files.Add(NewFile(newPackageFileName, package.Meta.Name + Package.PackageFileExtension));

            // Add files
            builder.PopulateFiles(package.RootDirectory, files);

            outputDirectory = outputDirectory ?? Environment.CurrentDirectory;

            // Save the nupkg
            var outputPath = GetOutputPath(builder,  outputDirectory);
            bool isExistingPackage = File.Exists(outputPath);
            if (isExistingPackage)
            {
                File.Delete(outputPath);
            }
            try
            {
                using (Stream stream = File.Create(outputPath))
                {
                    builder.Save(stream);
                }
            }
            catch
            {
                if (!isExistingPackage && File.Exists(outputPath))
                {
                    File.Delete(outputPath);
                }
                throw;
            }

            File.Delete(newPackage.FullPath);
        }
Esempio n. 6
0
        public void TestBasicPackageCreateSaveLoad()
        {
            var dirPath = DirectoryTestBase + @"TestBasicPackageCreateSaveLoad";

            string testGenerated1 = Path.Combine(dirPath, "TestPackage_TestBasicPackageCreateSaveLoad_Generated1.pdxpkg");
            string testGenerated2 = Path.Combine(dirPath,"TestPackage_TestBasicPackageCreateSaveLoad_Generated2.pdxpkg");
            string referenceFilePath = Path.Combine(dirPath,"TestPackage_TestBasicPackageCreateSaveLoad_Reference.pdxpkg");

            // Force the PackageId to be the same each time we run the test
            // Usually the PackageId is unique and generated each time we create a new project
            var project = new Package { Id = Guid.Empty, FullPath = testGenerated1 };
            var sharedProfile = new PackageProfile("Shared", new AssetFolder("."));
            project.Profiles.Add(sharedProfile);
            var projectReference = new ProjectReference(Guid.Empty, Path.Combine(dirPath, "test.csproj"), ProjectType.Executable);
            sharedProfile.ProjectReferences.Add(projectReference);

            var session = new PackageSession(project);
            // Write the solution when saving
            session.SolutionPath = Path.Combine(dirPath, "TestPackage_TestBasicPackageCreateSaveLoad_Generated1.sln");

            // Delete the solution before saving it 
            if (File.Exists(session.SolutionPath))
            {
                File.Delete(session.SolutionPath);
            }

            var result = session.Save();
            Assert.IsFalse(result.HasErrors);

            // Reload the raw package and if UFile and UDirectory were saved relative
            var rawPackage = (Package)AssetSerializer.Load(testGenerated1);
            var rawPackageSharedProfile = rawPackage.Profiles.FirstOrDefault();
            Assert.IsNotNull(rawPackageSharedProfile);
            var rawSourceFolder = rawPackage.Profiles.First().AssetFolders.FirstOrDefault();
            Assert.IsNotNull(rawSourceFolder);
            Assert.AreEqual(".", (string)rawSourceFolder.Path);
            Assert.AreEqual("test.csproj", (string)rawPackageSharedProfile.ProjectReferences[0].Location);

            // Reload the package directly from the pdxpkg
            var project2Result = PackageSession.Load(testGenerated1);
            AssertResult(project2Result);
            var project2 = project2Result.Session.LocalPackages.FirstOrDefault();
            Assert.IsNotNull(project2);
            Assert.AreEqual(project.Id, project2.Id);
            Assert.IsTrue(project2.Profiles.Count > 0);
            Assert.IsTrue(project2.Profiles.First().AssetFolders.Count > 0);
            var sourceFolder = project.Profiles.First().AssetFolders.First().Path;
            Assert.AreEqual(sourceFolder, project2.Profiles.First().AssetFolders.First().Path);

            // Reload the package from the sln
            var sessionResult = PackageSession.Load(session.SolutionPath);
            Assert.IsFalse(sessionResult.HasErrors);

            var sessionReload = sessionResult.Session;
            Assert.AreEqual(1, sessionReload.LocalPackages.Count());
            Assert.AreEqual(project.Id, sessionReload.LocalPackages.First().Id);
            Assert.AreEqual(1, sessionReload.LocalPackages.First().Profiles.Count);

            var sharedProfileReload = sessionReload.LocalPackages.First().Profiles.First();
            Assert.AreEqual(1, sharedProfileReload.ProjectReferences.Count);
            Assert.AreEqual(projectReference, sharedProfileReload.ProjectReferences[0]);
        }
Esempio n. 7
0
        private static void GenerateUnitTestProject(string outputDirectory, string templateFile, string name, string projectNamespace)
        {
            var projectTemplate = ProjectTemplate.Load(templateFile);

            // Force reference to Xenko.Assets (to have acess to SolutionPlatform)
            projectTemplate.Assemblies.Add(typeof(GraphicsProfile).Assembly.FullName);
            projectTemplate.Assemblies.Add(typeof(XenkoConfig).Assembly.FullName);

            var options = new Dictionary <string, object>();

            // When generating over an existing set of files, retrieve the existing IDs
            // for better incrementality
            Guid projectGuid, assetId;

            GetExistingGuid(outputDirectory, name + ".Windows.csproj", out projectGuid);
            GetExistingAssetId(outputDirectory, name + ".xkpkg", out assetId);

            var session = new PackageSession();
            var result  = new LoggerResult();

            var templateGeneratorParameters = new SessionTemplateGeneratorParameters();

            templateGeneratorParameters.OutputDirectory = outputDirectory;
            templateGeneratorParameters.Session         = session;
            templateGeneratorParameters.Name            = name;
            templateGeneratorParameters.Logger          = result;
            templateGeneratorParameters.Description     = new TemplateDescription();
            templateGeneratorParameters.Id = assetId;

            if (!PackageUnitTestGenerator.Default.PrepareForRun(templateGeneratorParameters).Result)
            {
                Console.WriteLine(@"Error generating package: PackageUnitTestGenerator.PrepareForRun returned false");
                return;
            }
            if (!PackageUnitTestGenerator.Default.Run(templateGeneratorParameters))
            {
                Console.WriteLine(@"Error generating package: PackageUnitTestGenerator.Run returned false");
                return;
            }
            if (result.HasErrors)
            {
                Console.WriteLine($"Error generating package: {result.ToText()}");
                return;
            }

            var package = session.LocalPackages.Single();

            var previousCurrent = session.CurrentPackage;

            session.CurrentPackage = package;

            // Compute Xenko Sdk relative path
            // We are supposed to be in standard output binary folder, so Xenko root should be at ..\..
            var xenkoPath         = UPath.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), new UDirectory(@"..\.."));
            var xenkoRelativePath = new UDirectory(xenkoPath)
                                    .MakeRelative(outputDirectory)
                                    .ToString()
                                    .Replace('/', '\\');

            xenkoRelativePath = xenkoRelativePath.TrimEnd('\\');

            options["Namespace"]           = projectNamespace ?? name;
            options["Package"]             = package;
            options["Platforms"]           = new List <SolutionPlatform>(AssetRegistry.SupportedPlatforms);
            options["XenkoSdkRelativeDir"] = xenkoRelativePath;

            // Generate project template
            result = projectTemplate.Generate(outputDirectory, name, projectGuid, options);
            if (result.HasErrors)
            {
                Console.WriteLine("Error generating solution: {0}", result.ToText());
                return;
            }

            var sharedProfile = package.Profiles.FindSharedProfile();

            // Setup the assets folder
            Directory.CreateDirectory(UPath.Combine(outputDirectory, (UDirectory)"Assets/Shared"));

            // Add Windows test as Shared library
            var projectWindowsRef = new ProjectReference(projectGuid, UPath.Combine(outputDirectory, (UFile)(name + ".Windows.csproj")), SiliconStudio.Assets.ProjectType.Library);

            sharedProfile.ProjectReferences.Add(projectWindowsRef);

            // Generate executable projects for each platform
            foreach (var platform in AssetRegistry.SupportedPlatforms)
            {
                var platformProfile = new PackageProfile(platform.Name)
                {
                    Platform = platform.Type
                };
                platformProfile.AssetFolders.Add(new AssetFolder("Assets/" + platform.Name));

                // Log progress
                var projectName = name + "." + platform.Type;

                // Create project reference
                var projectPlatformRef = new ProjectReference(projectGuid, UPath.Combine(outputDirectory, (UFile)(projectName + ".csproj")), SiliconStudio.Assets.ProjectType.Executable);

                platformProfile.ProjectReferences.Add(projectPlatformRef);

                package.Profiles.Add(platformProfile);
            }

            session.CurrentPackage = previousCurrent;

            session.Save(result);
            if (result.HasErrors)
            {
                Console.WriteLine("Error saving package: {0}", result.ToText());
                return;
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Builds bundles. It will automatically analyze assets and chunks to determine dependencies and what should be embedded in which bundle.
        /// Bundle descriptions will be loaded from <see cref="Package.Bundles" /> provided by the <see cref="packageSession" />, and copied to <see cref="outputDirectory" />.
        /// </summary>
        /// <param name="logger">The builder logger.</param>
        /// <param name="packageSession">The project session.</param>
        /// <param name="profile">The build profile.</param>
        /// <param name="indexName">Name of the index file.</param>
        /// <param name="outputDirectory">The output directory.</param>
        /// <param name="disableCompressionIds">The object id that should be kept uncompressed in the bundle (everything else will be compressed using LZ4).</param>
        /// <exception cref="System.InvalidOperationException">
        /// </exception>
        public void Build(Logger logger, PackageSession packageSession, PackageProfile profile, string indexName, string outputDirectory, ISet <ObjectId> disableCompressionIds)
        {
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }
            if (packageSession == null)
            {
                throw new ArgumentNullException("packageSession");
            }
            if (indexName == null)
            {
                throw new ArgumentNullException("indexName");
            }
            if (outputDirectory == null)
            {
                throw new ArgumentNullException("outputDirectory");
            }
            if (disableCompressionIds == null)
            {
                throw new ArgumentNullException("disableCompressionIds");
            }

            // Load index maps and mount databases
            var objDatabase = new ObjectDatabase("/data/db", indexName, loadDefaultBundle: false);

            logger.Info("Generate bundles: Scan assets and their dependencies...");

            // Prepare list of bundles gathered from all projects
            var bundles = new List <Bundle>();

            foreach (var project in packageSession.Packages)
            {
                bundles.AddRange(project.Bundles);
            }

            var databaseFileProvider = new DatabaseFileProvider(objDatabase.AssetIndexMap, objDatabase);

            AssetManager.GetFileProvider = () => databaseFileProvider;

            // Pass1: Create ResolvedBundle from user Bundle
            var resolvedBundles = new Dictionary <string, ResolvedBundle>();

            foreach (var bundle in bundles)
            {
                if (resolvedBundles.ContainsKey(bundle.Name))
                {
                    throw new InvalidOperationException(string.Format("Two bundles with name {0} found", bundle.Name));
                }

                resolvedBundles.Add(bundle.Name, new ResolvedBundle(bundle));
            }

            // Pass2: Enumerate all assets which directly or indirectly belong to an bundle
            var bundleAssets = new HashSet <string>();

            foreach (var bundle in resolvedBundles)
            {
                // For each project, we apply asset selectors of current bundle
                // This will give us a list of "root assets".
                foreach (var assetSelector in bundle.Value.Source.Selectors)
                {
                    foreach (var assetLocation in assetSelector.Select(packageSession, objDatabase.AssetIndexMap))
                    {
                        bundle.Value.AssetUrls.Add(assetLocation);
                    }
                }

                // Compute asset dependencies, and fill bundleAssets with list of all assets contained in bundles (directly or indirectly).
                foreach (var assetUrl in bundle.Value.AssetUrls)
                {
                    CollectReferences(bundle.Value.Source, bundleAssets, assetUrl, objDatabase.AssetIndexMap);
                }
            }

            // Pass3: Create a default bundle that contains all assets not contained in any bundle (directly or indirectly)
            var defaultBundle = new Bundle {
                Name = "default"
            };
            var resolvedDefaultBundle = new ResolvedBundle(defaultBundle);

            bundles.Add(defaultBundle);
            resolvedBundles.Add(defaultBundle.Name, resolvedDefaultBundle);
            foreach (var asset in objDatabase.AssetIndexMap.GetMergedIdMap())
            {
                if (!bundleAssets.Contains(asset.Key))
                {
                    resolvedDefaultBundle.AssetUrls.Add(asset.Key);
                }
            }

            // Pass4: Resolve dependencies
            foreach (var bundle in resolvedBundles)
            {
                // Every bundle depends implicitely on default bundle
                if (bundle.Key != "default")
                {
                    bundle.Value.Dependencies.Add(resolvedBundles["default"]);
                }

                // Add other explicit dependencies
                foreach (var dependencyName in bundle.Value.Source.Dependencies)
                {
                    ResolvedBundle dependency;
                    if (!resolvedBundles.TryGetValue(dependencyName, out dependency))
                    {
                        throw new InvalidOperationException(string.Format("Could not find dependency {0} when processing bundle {1}", dependencyName, bundle.Value.Name));
                    }

                    bundle.Value.Dependencies.Add(dependency);
                }
            }

            logger.Info("Generate bundles: Assign assets to bundles...");

            // Pass5: Topological sort (a.k.a. build order)
            // If there is a cyclic dependency, an exception will be thrown.
            var sortedBundles = TopologicalSort(resolvedBundles.Values, assetBundle => assetBundle.Dependencies);

            // Pass6: Find which ObjectId belongs to which bundle
            foreach (var bundle in sortedBundles)
            {
                // Add objects created by dependencies
                foreach (var dep in bundle.Dependencies)
                {
                    // ObjectIds
                    bundle.DependencyObjectIds.UnionWith(dep.DependencyObjectIds);
                    bundle.DependencyObjectIds.UnionWith(dep.ObjectIds);

                    // IndexMap
                    foreach (var asset in dep.DependencyIndexMap.Concat(dep.IndexMap))
                    {
                        if (!bundle.DependencyIndexMap.ContainsKey(asset.Key))
                        {
                            bundle.DependencyIndexMap.Add(asset.Key, asset.Value);
                        }
                    }
                }

                // Collect assets (object ids and partial index map) from given asset urls
                // Those not present in dependencies will be added to this bundle
                foreach (var assetUrl in bundle.AssetUrls)
                {
                    CollectBundle(bundle, assetUrl, objDatabase.AssetIndexMap);
                }
            }

            logger.Info("Generate bundles: Compress and save bundles to HDD...");

            // Mount VFS for output database (currently disabled because already done in ProjectBuilder.CopyBuildToOutput)
            VirtualFileSystem.MountFileSystem("/data_output", outputDirectory);
            VirtualFileSystem.CreateDirectory("/data_output/db");

            // Mount output database and delete previous bundles that shouldn't exist anymore (others should be overwritten)
            var outputDatabase = new ObjectDatabase("/data_output/db", loadDefaultBundle: false);

            try
            {
                outputDatabase.LoadBundle("default").GetAwaiter().GetResult();
            }
            catch (Exception)
            {
                logger.Info("Generate bundles: Tried to load previous 'default' bundle but it was invalid. Deleting it...");
                outputDatabase.BundleBackend.DeleteBundles(x => Path.GetFileNameWithoutExtension(x) == "default");
            }
            var outputBundleBackend = outputDatabase.BundleBackend;

            var outputGroupBundleBackends = new Dictionary <string, BundleOdbBackend>();

            if (profile != null && profile.OutputGroupDirectories != null)
            {
                var rootPackage = packageSession.LocalPackages.First();

                foreach (var item in profile.OutputGroupDirectories)
                {
                    var path            = Path.Combine(rootPackage.RootDirectory, item.Value);
                    var vfsPath         = "/data_group_" + item.Key;
                    var vfsDatabasePath = vfsPath + "/db";

                    // Mount VFS for output database (currently disabled because already done in ProjectBuilder.CopyBuildToOutput)
                    VirtualFileSystem.MountFileSystem(vfsPath, path);
                    VirtualFileSystem.CreateDirectory(vfsDatabasePath);

                    outputGroupBundleBackends.Add(item.Key, new BundleOdbBackend(vfsDatabasePath));
                }
            }

            // Pass7: Assign bundle backends
            foreach (var bundle in sortedBundles)
            {
                BundleOdbBackend bundleBackend;
                if (bundle.Source.OutputGroup == null)
                {
                    // No output group, use OutputDirectory
                    bundleBackend = outputBundleBackend;
                }
                else if (!outputGroupBundleBackends.TryGetValue(bundle.Source.OutputGroup, out bundleBackend))
                {
                    // Output group not found in OutputGroupDirectories, let's issue a warning and fallback to OutputDirectory
                    logger.Warning("Generate bundles: Could not find OutputGroup {0} for bundle {1} in ProjectBuildProfile.OutputGroupDirectories", bundle.Source.OutputGroup, bundle.Name);
                    bundleBackend = outputBundleBackend;
                }

                bundle.BundleBackend = bundleBackend;
            }

            CleanUnknownBundles(outputBundleBackend, resolvedBundles);

            foreach (var bundleBackend in outputGroupBundleBackends)
            {
                CleanUnknownBundles(bundleBackend.Value, resolvedBundles);
            }

            // Pass8: Pack actual data
            foreach (var bundle in sortedBundles)
            {
                // Compute dependencies (by bundle names)
                var dependencies = bundle.Dependencies.Select(x => x.Name).Distinct().ToList();

                BundleOdbBackend bundleBackend;
                if (bundle.Source.OutputGroup == null)
                {
                    // No output group, use OutputDirectory
                    bundleBackend = outputBundleBackend;
                }
                else if (!outputGroupBundleBackends.TryGetValue(bundle.Source.OutputGroup, out bundleBackend))
                {
                    // Output group not found in OutputGroupDirectories, let's issue a warning and fallback to OutputDirectory
                    logger.Warning("Generate bundles: Could not find OutputGroup {0} for bundle {1} in ProjectBuildProfile.OutputGroupDirectories", bundle.Source.OutputGroup, bundle.Name);
                    bundleBackend = outputBundleBackend;
                }

                objDatabase.CreateBundle(bundle.ObjectIds.ToArray(), bundle.Name, bundleBackend, disableCompressionIds, bundle.IndexMap, dependencies);
            }

            logger.Info("Generate bundles: Done");
        }
Esempio n. 9
0
        public static void Build(Package package, string specialVersion = null, string outputDirectory = null)
        {
            if (package == null) throw new ArgumentNullException("package");

            var meta = new NuGet.ManifestMetadata();
            package.Meta.ToNugetManifest(meta);

            // Override version with task SpecialVersion (if specified by user)
            if (specialVersion != null)
            {
                meta.Version = new PackageVersion(package.Meta.Version.ToString().Split('-').First() + "-" + specialVersion).ToString();
            }

            var builder = new NuGet.PackageBuilder();
            builder.Populate(meta);

            var currentAssemblyLocation = Assembly.GetExecutingAssembly().Location;
            var mainPlatformDirectory = Path.GetFileName(Path.GetDirectoryName(currentAssemblyLocation));

            // TODO this is not working 
            // We are excluding everything that is in a folder that starts with a dot (ie. .shadow, .vs)
            var files = new List<NuGet.ManifestFile>()
                {
                    NewFile(@"Bin\**\*.exe", "Bin", @"Bin\**\.*\**\*.exe"),
                    NewFile(@"Bin\**\*.vsix", "Bin", @"Bin\**\.*\**\*.vsix"),
                    NewFile(@"Bin\**\*.so", "Bin", @"Bin\**\.*\**\*.so"),
                    NewFile(@"Bin\**\*.a", "Bin", @"Bin\**\.*\**\*.a"),
                    NewFile(@"Bin\**\*.md", "Bin", @"Bin\**\.*\**\*.md"),
                    NewFile(@"Bin\**\*.html", "Bin", @"Bin\**\.*\**\*.html"),
                    NewFile(@"Bin\**\*.config", "Bin", @"Bin\**\.*\**\*.config"),
                    NewFile(@"Bin\**\*.dll", "Bin", @"Bin\**\.*\**\*.dll"),
                    NewFile(@"Bin\**\*.xml", "Bin", @"Bin\**\.*\**\*.xml"),
                    NewFile(@"Bin\**\*.usrdoc", "Bin", @"Bin\**\.*\**\*.usrdoc"),
                    NewFile(@"Bin\**\*.winmd", "Bin", @"Bin\**\.*\**\*.winmd"),
                    NewFile($@"Bin\{mainPlatformDirectory}\ios-tcprelay\*.py",$@"Bin\{mainPlatformDirectory}\ios-tcprelay"),
                    NewFile(@"Targets\*.targets", "Targets"),
                    NewFile($@"Bin\{mainPlatformDirectory}\SiliconStudio.*.pdb", $@"Bin\{mainPlatformDirectory}", @"Bin\**\SiliconStudio.Xenko.Importer*.pdb;Bin\**\SiliconStudio.Assets.Editor.pdb;Bin\**\SiliconStudio.Xenko.Assets.Presentation.pdb;Bin\**\SiliconStudio.Xenko.GameStudio*.pdb;Bin\**\SiliconStudio.Xenko.Assimp.Translation.pdb"),
                };

            // Handle Assets
            var rootDir = package.RootDirectory;

            var newPackage = new Package { Meta = package.Meta };

            foreach (var profile in package.Profiles)
            {
                var target = "Assets/" + profile.Name;
                foreach (var assetFolder in profile.AssetFolders)
                {
                    // TODO: handle exclude in asset folders
                    //files.Add(NewFile(source, target, @"**\*.cs;**\*.hlsl;**\*.csproj;**\*.csproj.user;**\obj\**"));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xksl", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xkfx", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xkfnt", target));
                }

                var targetProfile = new PackageProfile(profile.Name);
                targetProfile.AssetFolders.Add(new AssetFolder(target));
                newPackage.Profiles.Add(targetProfile);
            }

            // Handle templates
            var targetFolder = new TemplateFolder("Templates");

            foreach (var templateFolder in package.TemplateFolders)
            {
                var source = templateFolder.Path.MakeRelative(rootDir) + "/**";
                UDirectory target = targetFolder.Path;
                if (templateFolder.Group != null)
                {
                    target = UPath.Combine(target, templateFolder.Group);
                }

                var excludeFiles = templateFolder.Exclude;
                files.Add(NewFile(source, target, excludeFiles));

                // Add template files
                foreach (var templateFile in templateFolder.Files)
                {
                    var newTemplateFile = templateFile.MakeRelative(templateFolder.Path);
                    if (templateFolder.Group != null)
                    {
                        newTemplateFile = UPath.Combine(templateFolder.Group, newTemplateFile);
                    }

                    newTemplateFile = UPath.Combine(targetFolder.Path, newTemplateFile);
                    targetFolder.Files.Add(newTemplateFile);
                }
            }

            // Create temp package for archive
            newPackage.TemplateFolders.Add(targetFolder);
            var newPackageFileName = "temp" + Guid.NewGuid() + ".xkpkg";
            newPackage.FullPath = package.RootDirectory + "/" + newPackageFileName;
            var result = newPackage.Save();
            if (result.HasErrors)
            {
                throw new InvalidOperationException(result.ToText());
                // TODO throw error
            }
            files.Add(NewFile(newPackageFileName, package.Meta.Name + Package.PackageFileExtension));

            // Add files
            builder.PopulateFiles(package.RootDirectory, files);

            outputDirectory = outputDirectory ?? Environment.CurrentDirectory;

            // Save the nupkg
            var outputPath = GetOutputPath(builder,  outputDirectory);
            bool isExistingPackage = File.Exists(outputPath);
            if (isExistingPackage)
            {
                File.Delete(outputPath);
            }
            try
            {
                using (Stream stream = File.Create(outputPath))
                {
                    builder.Save(stream);
                }
            }
            catch
            {
                if (!isExistingPackage && File.Exists(outputPath))
                {
                    File.Delete(outputPath);
                }
                throw;
            }

            File.Delete(newPackage.FullPath);
        }
Esempio n. 10
0
        public void TestBasicPackageCreateSaveLoad()
        {
            PackageSessionPublicHelper.FindAndSetMSBuildVersion();

            var dirPath = DirectoryTestBase + @"TestBasicPackageCreateSaveLoad";

            string testGenerated1    = Path.Combine(dirPath, "TestPackage_TestBasicPackageCreateSaveLoad_Generated1.xkpkg");
            string testGenerated2    = Path.Combine(dirPath, "TestPackage_TestBasicPackageCreateSaveLoad_Generated2.xkpkg");
            string referenceFilePath = Path.Combine(dirPath, "TestPackage_TestBasicPackageCreateSaveLoad_Reference.xkpkg");

            // Force the PackageId to be the same each time we run the test
            // Usually the PackageId is unique and generated each time we create a new project
            var project = new Package {
                Id = Guid.Empty, FullPath = testGenerated1
            };
            var sharedProfile = new PackageProfile("Shared", new AssetFolder("."));

            project.Profiles.Add(sharedProfile);
            var projectReference = new ProjectReference(Guid.Empty, Path.Combine(dirPath, "test.csproj"), ProjectType.Executable);

            sharedProfile.ProjectReferences.Add(projectReference);

            var session = new PackageSession(project);

            // Write the solution when saving
            session.SolutionPath = Path.Combine(dirPath, "TestPackage_TestBasicPackageCreateSaveLoad_Generated1.sln");

            // Delete the solution before saving it
            if (File.Exists(session.SolutionPath))
            {
                File.Delete(session.SolutionPath);
            }

            var result = new LoggerResult();

            session.Save(result);
            Assert.False(result.HasErrors);

            // Reload the raw package and if UFile and UDirectory were saved relative
            var rawPackage = AssetFileSerializer.Load <Package>(testGenerated1).Asset;
            var rawPackageSharedProfile = rawPackage.Profiles.FirstOrDefault();

            Assert.NotNull(rawPackageSharedProfile);
            var rawSourceFolder = rawPackage.Profiles.First().AssetFolders.FirstOrDefault();

            Assert.NotNull(rawSourceFolder);
            Assert.Equal(".", (string)rawSourceFolder.Path);
            Assert.Equal("test.csproj", (string)rawPackageSharedProfile.ProjectReferences[0].Location);

            // Reload the package directly from the xkpkg
            var project2Result = PackageSession.Load(testGenerated1);

            AssertResult(project2Result);
            var project2 = project2Result.Session.LocalPackages.FirstOrDefault();

            Assert.NotNull(project2);
            Assert.Equal(project.Id, project2.Id);
            Assert.True(project2.Profiles.Count > 0);
            Assert.True(project2.Profiles.First().AssetFolders.Count > 0);
            Assert.Equal(project2, project2Result.Session.CurrentPackage); // Check that the current package is setup when loading a single package
            var sourceFolder = project.Profiles.First().AssetFolders.First().Path;

            Assert.Equal(sourceFolder, project2.Profiles.First().AssetFolders.First().Path);

            // Reload the package from the sln
            var sessionResult = PackageSession.Load(session.SolutionPath);

            Assert.False(sessionResult.HasErrors);

            var sessionReload = sessionResult.Session;

            Assert.Equal(1, sessionReload.LocalPackages.Count());
            Assert.Equal(project.Id, sessionReload.LocalPackages.First().Id);
            Assert.Equal(1, sessionReload.LocalPackages.First().Profiles.Count);

            var sharedProfileReload = sessionReload.LocalPackages.First().Profiles.First();

            Assert.Equal(1, sharedProfileReload.ProjectReferences.Count);
            Assert.Equal(projectReference, sharedProfileReload.ProjectReferences[0]);
        }
Esempio n. 11
0
        public static void Build(Package package, string specialVersion = null, string outputDirectory = null)
        {
            if (package == null)
            {
                throw new ArgumentNullException("package");
            }

            var meta = new NuGet.ManifestMetadata();

            package.Meta.ToNugetManifest(meta);

            // Override version with task SpecialVersion (if specified by user)
            if (specialVersion != null)
            {
                meta.Version = new PackageVersion(package.Meta.Version.ToString().Split('-').First() + "-" + specialVersion).ToString();
            }

            var builder = new NuGet.PackageBuilder();

            builder.Populate(meta);

            var currentAssemblyLocation = Assembly.GetExecutingAssembly().Location;
            var mainPlatformDirectory   = Path.GetFileName(Path.GetDirectoryName(currentAssemblyLocation));

            // TODO this is not working
            // We are excluding everything that is in a folder that starts with a dot (ie. .shadow, .vs)
            var files = new List <NuGet.ManifestFile>()
            {
                NewFile(@"Bin\**\*.exe", "Bin", @"Bin\**\.*\**\*.exe"),
                NewFile(@"Bin\**\*.vsix", "Bin", @"Bin\**\.*\**\*.vsix"),
                NewFile(@"Bin\**\*.so", "Bin", @"Bin\**\.*\**\*.so"),
                NewFile(@"Bin\**\*.a", "Bin", @"Bin\**\.*\**\*.a"),
                NewFile(@"Bin\**\*.md", "Bin", @"Bin\**\.*\**\*.md"),
                NewFile(@"Bin\**\*.html", "Bin", @"Bin\**\.*\**\*.html"),
                NewFile(@"Bin\**\*.config", "Bin", @"Bin\**\.*\**\*.config"),
                NewFile(@"Bin\**\*.dll", "Bin", @"Bin\**\.*\**\*.dll"),
                NewFile(@"Bin\**\*.xml", "Bin", @"Bin\**\.*\**\*.xml"),
                NewFile(@"Bin\**\*.usrdoc", "Bin", @"Bin\**\.*\**\*.usrdoc"),
                NewFile(@"Bin\**\*.winmd", "Bin", @"Bin\**\.*\**\*.winmd"),
                NewFile($@"Bin\{mainPlatformDirectory}\ios-tcprelay\*.py", $@"Bin\{mainPlatformDirectory}\ios-tcprelay"),
                NewFile(@"Targets\*.targets", "Targets"),
                NewFile($@"Bin\{mainPlatformDirectory}\SiliconStudio.*.pdb", $@"Bin\{mainPlatformDirectory}", @"Bin\**\SiliconStudio.Xenko.Importer*.pdb;Bin\**\SiliconStudio.Assets.Editor.pdb;Bin\**\SiliconStudio.Xenko.Assets.Presentation.pdb;Bin\**\SiliconStudio.Xenko.GameStudio*.pdb;Bin\**\SiliconStudio.Xenko.Assimp.Translation.pdb"),
            };

            // Handle Assets
            var rootDir = package.RootDirectory;

            var newPackage = new Package {
                Meta = package.Meta
            };

            foreach (var profile in package.Profiles)
            {
                var target = "Assets/" + profile.Name;
                foreach (var assetFolder in profile.AssetFolders)
                {
                    // TODO: handle exclude in asset folders
                    //files.Add(NewFile(source, target, @"**\*.cs;**\*.hlsl;**\*.csproj;**\*.csproj.user;**\obj\**"));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xksl", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xkfx", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xkfnt", target));
                }

                var targetProfile = new PackageProfile(profile.Name);
                targetProfile.AssetFolders.Add(new AssetFolder(target));
                newPackage.Profiles.Add(targetProfile);
            }

            // Handle templates
            var targetFolder = new TemplateFolder("Templates");

            foreach (var templateFolder in package.TemplateFolders)
            {
                var        source = templateFolder.Path.MakeRelative(rootDir) + "/**";
                UDirectory target = targetFolder.Path;
                if (templateFolder.Group != null)
                {
                    target = UPath.Combine(target, templateFolder.Group);
                }

                var excludeFiles = templateFolder.Exclude;
                files.Add(NewFile(source, target, excludeFiles));

                // Add template files
                foreach (var templateFile in templateFolder.Files)
                {
                    var newTemplateFile = templateFile.MakeRelative(templateFolder.Path);
                    if (templateFolder.Group != null)
                    {
                        newTemplateFile = UPath.Combine(templateFolder.Group, newTemplateFile);
                    }

                    newTemplateFile = UPath.Combine(targetFolder.Path, newTemplateFile);
                    targetFolder.Files.Add(newTemplateFile);
                }
            }

            // Create temp package for archive
            newPackage.TemplateFolders.Add(targetFolder);
            var newPackageFileName = "temp" + Guid.NewGuid() + ".xkpkg";

            newPackage.FullPath = package.RootDirectory + "/" + newPackageFileName;
            var result = newPackage.Save();

            if (result.HasErrors)
            {
                throw new InvalidOperationException(result.ToText());
                // TODO throw error
            }
            files.Add(NewFile(newPackageFileName, package.Meta.Name + Package.PackageFileExtension));

            // Add files
            builder.PopulateFiles(package.RootDirectory, files);

            outputDirectory = outputDirectory ?? Environment.CurrentDirectory;

            // Save the nupkg
            var  outputPath        = GetOutputPath(builder, outputDirectory);
            bool isExistingPackage = File.Exists(outputPath);

            if (isExistingPackage)
            {
                File.Delete(outputPath);
            }
            try
            {
                using (Stream stream = File.Create(outputPath))
                {
                    builder.Save(stream);
                }
            }
            catch
            {
                if (!isExistingPackage && File.Exists(outputPath))
                {
                    File.Delete(outputPath);
                }
                throw;
            }

            File.Delete(newPackage.FullPath);
        }
Esempio n. 12
0
        public static void Build(ILogger log, Package package, string outputDirectory = null)
        {
            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            var meta = new ManifestMetadata();

            PackageStore.ToNugetManifest(package.Meta, meta);

            // Sanity check: Xenko version should be same between NuGet package and Xenko package
            var nugetVersion   = new PackageVersion(XenkoVersion.NuGetVersion).Version;
            var packageVersion = package.Meta.Version.Version;

            if (nugetVersion != packageVersion)
            {
                log.Error($"Package has mismatching version: NuGet package version is {nugetVersion} and Xenko Package version is {packageVersion}");
                return;
            }

            if (nugetVersion.Revision <= 0)
            {
                // If 0, we have special cases with NuGet dropping it in install path, could be dangerous and lead to bugs if not properly tested.
                log.Error($"Package has revision {nugetVersion} but 4th digit needs to be at least 1.");
                return;
            }

            // Override version with NuGet version (4th number is different in Xenko package)
            meta.Version = XenkoVersion.NuGetVersion;

            var builder = new NugetPackageBuilder();

            builder.Populate(meta);

            var currentAssemblyLocation = Assembly.GetExecutingAssembly().Location;
            var mainPlatformDirectory   = Path.GetFileName(Path.GetDirectoryName(currentAssemblyLocation));

            // TODO this is not working
            // We are excluding everything that is in a folder that starts with a dot (ie. .shadow, .vs)
            var files = new List <ManifestFile>()
            {
                NewFile(@"Bin\**\*.exe", "Bin", @"Bin\**\.*\**\*.exe;Bin\**\Tools\**.exe"),
                NewFile(@"Bin\**\*.so", "Bin", @"Bin\**\.*\**\*.so;Bin\Windows\lib\**\*.so"),
                NewFile(@"Bin\**\*.ssdeps", "Bin", @"Bin\**\.*\**\*.ssdeps"),
                NewFile(@"Bin\**\*.a", "Bin", @"Bin\**\.*\**\*.a"),
                NewFile(@"Bin\**\*.md", "Bin", @"Bin\**\.*\**\*.md"),
                NewFile(@"Bin\**\*.html", "Bin", @"Bin\**\.*\**\*.html"),
                NewFile(@"Bin\**\*.config", "Bin", @"Bin\**\.*\**\*.config"),
                NewFile(@"Bin\**\*.dll", "Bin", @"Bin\**\.*\**\*.dll;Bin\Windows\lib\**\*.dll"),
                NewFile(@"Bin\**\*.xml", "Bin", @"Bin\**\.*\**\*.xml"),
                NewFile(@"Bin\**\*.usrdoc", "Bin", @"Bin\**\.*\**\*.usrdoc"),
                NewFile(@"Bin\**\*.winmd", "Bin", @"Bin\**\.*\**\*.winmd"),
                NewFile(@"Bin\**\*.sh", "Bin", @"Bin\**\.*\**\*.sh"),
                NewFile(@"Bin\**\*.json", "Bin", @"Bin\**\.*\**\*.json"),
                NewFile(@"deps\AssemblyProcessor\*.exe", @"deps/AssemblyProcessor"),
                NewFile(@"deps\AssemblyProcessor\*.dll", @"deps/AssemblyProcessor"),
                NewFile($@"Bin\{mainPlatformDirectory}\ios-tcprelay\*.py", $@"Bin\{mainPlatformDirectory}\ios-tcprelay"),
                NewFile(@"Targets\*.targets", "Targets"),
                NewFile(@"Targets\*.props", "Targets"),
                NewFile($@"Bin\**\Xenko*.pdb", $@"Bin", @"Bin\**\.*\**\*.pdb;Bin\**\Xenko.Importer*.pdb;Bin\**\Xenko.Assimp.Translation.pdb"),
                NewFile(@"build\Xenko.targets", @"build"),
                NewFile(@"build\Xenko.props", @"build"),
                NewFile(@"tools\**\*.exe", "tools"),
                NewFile(@"tools\**\*.dll", "tools"),
                NewFile(@"LICENSE.md", @""),
                NewFile(@"THIRD PARTY.md", @""),
                NewFile(@"BACKERS.md", @""),
            };

            // Handle Assets
            var rootDir = package.RootDirectory;

            var newPackage = new Package {
                Meta = AssetCloner.Clone(package.Meta)
            };

            newPackage.Meta.Version = new PackageVersion(meta.Version);

            foreach (var profile in package.Profiles)
            {
                var target = "Assets/" + profile.Name;
                foreach (var assetFolder in profile.AssetFolders)
                {
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xk*", target));
                }
                foreach (var resourceFolder in profile.ResourceFolders)
                {
                    files.Add(NewFile(resourceFolder.MakeRelative(rootDir) + "/**/*.*", "Resources"));
                }

                var targetProfile = new PackageProfile(profile.Name);
                if (profile.AssetFolders.Count > 0)
                {
                    targetProfile.AssetFolders.Add(new AssetFolder(target));
                }
                if (profile.ResourceFolders.Count > 0)
                {
                    targetProfile.ResourceFolders.Add("Resources");
                }

                newPackage.Profiles.Add(targetProfile);
            }

            //Handle RootAssets
            foreach (var rootAsset in package.RootAssets)
            {
                newPackage.RootAssets.Add(rootAsset);
            }

            // Handle templates
            var targetFolder = new TemplateFolder("Templates");

            foreach (var templateFolder in package.TemplateFolders)
            {
                var        source = templateFolder.Path.MakeRelative(rootDir) + "/**";
                UDirectory target = targetFolder.Path;
                if (templateFolder.Group != null)
                {
                    target = UPath.Combine(target, templateFolder.Group);
                }

                var excludeFiles = templateFolder.Exclude;
                files.Add(NewFile(source, target, excludeFiles));

                // Add template files
                foreach (var templateFile in templateFolder.Files)
                {
                    var newTemplateFile = templateFile.MakeRelative(templateFolder.Path);
                    if (templateFolder.Group != null)
                    {
                        newTemplateFile = UPath.Combine(templateFolder.Group, newTemplateFile);
                    }

                    newTemplateFile = UPath.Combine(targetFolder.Path, newTemplateFile);
                    targetFolder.Files.Add(newTemplateFile);
                }
            }

            // Create temp package for archive
            newPackage.TemplateFolders.Add(targetFolder);
            var newPackageFileName = "temp" + Guid.NewGuid() + ".xkpkg";

            newPackage.FullPath = package.RootDirectory + "/" + newPackageFileName;
            var result = new LoggerResult();

            newPackage.Save(result);
            if (result.HasErrors)
            {
                throw new InvalidOperationException(result.ToText());
                // TODO throw error
            }
            files.Add(NewFile(newPackageFileName, package.Meta.Name + Package.PackageFileExtension));

            // Add files
            builder.PopulateFiles(package.RootDirectory, files);

            outputDirectory = outputDirectory ?? Environment.CurrentDirectory;

            // Save the nupkg
            var  outputPath        = GetOutputPath(builder, outputDirectory);
            bool isExistingPackage = File.Exists(outputPath);

            if (isExistingPackage)
            {
                File.Delete(outputPath);
            }
            try
            {
                using (Stream stream = File.Create(outputPath))
                {
                    builder.Save(stream);
                }
            }
            catch
            {
                if (!isExistingPackage && File.Exists(outputPath))
                {
                    File.Delete(outputPath);
                }
                throw;
            }

            File.Delete(newPackage.FullPath);
        }
Esempio n. 13
0
        private static void GenerateUnitTestProject(string outputDirectory, string templateFile, string name)
        {
            var projectTemplate = ProjectTemplate.Load(templateFile);

            // Force reference to Paradox.Assets (to have acess to SolutionPlatform)
            projectTemplate.Assemblies.Add(typeof(GraphicsProfile).Assembly.FullName);
            projectTemplate.Assemblies.Add(typeof(ParadoxConfig).Assembly.FullName);

            var options = new Dictionary<string, object>();

            var session = new PackageSession();
            var result = new LoggerResult();

            var templateGeneratorParameters = new TemplateGeneratorParameters();
            templateGeneratorParameters.OutputDirectory = outputDirectory;
            templateGeneratorParameters.Session = session;
            templateGeneratorParameters.Name = name;
            templateGeneratorParameters.Logger = result;
            templateGeneratorParameters.Description = new TemplateDescription();

            PackageUnitTestGenerator.Default.Generate(templateGeneratorParameters);
            if (result.HasErrors)
            {
                Console.WriteLine("Error generating package: {0}", result.ToText());
                return;
            }

            var package = templateGeneratorParameters.Package;

            var previousCurrent = session.CurrentPackage;
            session.CurrentPackage = package;

            // Compute Paradox Sdk relative path
            // We are supposed to be in standard output binary folder, so Paradox root should be at ..\..
            var paradoxPath = UDirectory.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), new UDirectory(@"..\.."));
            var paradoxRelativePath = new UDirectory(paradoxPath)
                .MakeRelative(outputDirectory)
                .ToString()
                .Replace('/', '\\');
            paradoxRelativePath = paradoxRelativePath.TrimEnd('\\');

            options["Namespace"] = name;
            options["Package"] = package;
            options["Platforms"] = new List<SolutionPlatform>(AssetRegistry.SupportedPlatforms);
            options["ParadoxSdkRelativeDir"] = paradoxRelativePath;

            // Generate project template
            var projectGuid = Guid.NewGuid();
            result = projectTemplate.Generate(outputDirectory, name, projectGuid, options);
            if (result.HasErrors)
            {
                Console.WriteLine("Error generating solution: {0}", result.ToText());
                return;
            }

            var sharedProfile = package.Profiles[PlatformType.Shared];

            // Setup the assets folder
            Directory.CreateDirectory(UPath.Combine(outputDirectory, (UDirectory)"Assets/Shared"));

            // Add Windows test as Shared library
            var projectWindowsRef = new ProjectReference();
            projectWindowsRef.Id = projectGuid;
            projectWindowsRef.Location = UPath.Combine(outputDirectory, (UFile)(name + ".Windows.csproj"));
            projectWindowsRef.Type = SiliconStudio.Assets.ProjectType.Library;
            sharedProfile.ProjectReferences.Add(projectWindowsRef);

            // Generate executable projects for each platform
            foreach (var platform in AssetRegistry.SupportedPlatforms)
            {
                var platformProfile = new PackageProfile(platform.Name) { Platform = platform.Type };
                platformProfile.AssetFolders.Add(new AssetFolder("Assets/"+ platform.Name));
                
                // Log progress
                var projectName = name + "." + platform.Type;

                // Create project reference
                var projectPlatformRef = new ProjectReference();
                projectPlatformRef.Id = projectGuid;
                projectPlatformRef.Location = UPath.Combine(outputDirectory, (UFile)(projectName + ".csproj"));
                projectPlatformRef.Type = SiliconStudio.Assets.ProjectType.Executable;

                platformProfile.ProjectReferences.Add(projectPlatformRef);

                // Add build configuration per platform
                platform.Properties.CopyTo(platformProfile.Properties, true);

                package.Profiles.Add(platformProfile);
            }

            session.CurrentPackage = previousCurrent;

            result = session.Save();
            if (result.HasErrors)
            {
                Console.WriteLine("Error saving package: {0}", result.ToText());
                return;
            }
        }
Esempio n. 14
0
        public static void UpdatePackagePlatforms(TemplateGeneratorParameters parameters, ICollection <SelectedSolutionPlatform> platforms, DisplayOrientation orientation, Guid sharedProjectGuid, string name, Package package, bool forcePlatformRegeneration)
        {
            if (platforms == null)
            {
                throw new ArgumentNullException(nameof(platforms));
            }
            var logger = parameters.Logger;

            // Setup the ProjectGameGuid to be accessible from exec (in order to be able to link to the game project.
            AddOption(parameters, "ProjectGameGuid", sharedProjectGuid);

            // Add projects
            var stepIndex        = 0;
            var stepCount        = platforms.Count + 1;
            var profilesToRemove = package.Profiles.Where(profile => platforms.All(platform => profile.Platform != PlatformType.Shared && platform.Platform.Type != profile.Platform)).ToList();

            stepCount += profilesToRemove.Count;

            foreach (var platform in platforms)
            {
                stepIndex++;

                // Don't add a platform that is already in the package

                var platformProfile = package.Profiles.FirstOrDefault(profile => profile.Platform == platform.Platform.Type);
                if (platformProfile != null && !forcePlatformRegeneration)
                {
                    continue;
                }

                var projectGuid = Guid.NewGuid();

                if (platformProfile == null)
                {
                    platformProfile = new PackageProfile(platform.Platform.Name)
                    {
                        Platform = platform.Platform.Type
                    };
                    platformProfile.AssetFolders.Add(new AssetFolder("Assets/" + platform.Platform.Name));
                }
                else
                {
                    // We are going to regenerate this platform, so we are removing it before
                    var previousExeProject = platformProfile.ProjectReferences.FirstOrDefault(project => project.Type == ProjectType.Executable);
                    if (previousExeProject != null)
                    {
                        projectGuid = previousExeProject.Id;
                        RemoveProject(previousExeProject, logger);
                        platformProfile.ProjectReferences.Remove(previousExeProject);
                    }
                }

                var templatePath = platform.Template?.TemplatePath ?? $"ProjectExecutable.{platform.Platform.Name}/ProjectExecutable.{platform.Platform.Name}.ttproj";

                // Log progress
                var projectName = Utilities.BuildValidNamespaceName(name) + "." + platform.Platform.Name;
                Progress(logger, $"Generating {projectName}...", stepIndex - 1, stepCount);

                var graphicsPlatform = platform.Platform.Type.GetDefaultGraphicsPlatform();
                var newExeProject    = GenerateTemplate(parameters, platforms, package, templatePath, projectName, platform.Platform.Type, platformProfile.Name, graphicsPlatform, ProjectType.Executable, orientation, projectGuid);
                newExeProject.Type = ProjectType.Executable;

                platformProfile.ProjectReferences.Add(newExeProject);

                if (!package.Profiles.Contains(platformProfile))
                {
                    package.Profiles.Add(platformProfile);
                }

                package.IsDirty = true;
            }

            // Remove existing platform profiles
            foreach (var profileToRemove in profilesToRemove)
            {
                package.Profiles.Remove(profileToRemove);
                package.IsDirty = true;

                foreach (var projectReference in profileToRemove.ProjectReferences)
                {
                    // Try to remove the directory
                    Progress(logger, $"Deleting {projectReference.Location}...", stepIndex++, stepCount);
                    RemoveProject(projectReference, logger);
                }

                // We are completely removing references from profile
                profileToRemove.ProjectReferences.Clear();
            }
        }
Esempio n. 15
0
        private static void GenerateUnitTestProject(string outputDirectory, string templateFile, string name, string projectNamespace)
        {
            var projectTemplate = ProjectTemplate.Load(templateFile);

            // Force reference to Xenko.Assets (to have acess to SolutionPlatform)
            projectTemplate.Assemblies.Add(typeof(GraphicsProfile).Assembly.FullName);
            projectTemplate.Assemblies.Add(typeof(XenkoConfig).Assembly.FullName);

            var options = new Dictionary<string, object>();

            // When generating over an existing set of files, retrieve the existing IDs
            // for better incrementality
            Guid projectGuid, assetId;
            GetExistingGuid(outputDirectory, name + ".Windows.csproj", out projectGuid);
            GetExistingAssetId(outputDirectory, name + ".xkpkg", out assetId);

            var session = new PackageSession();
            var result = new LoggerResult();

            var templateGeneratorParameters = new SessionTemplateGeneratorParameters();
            templateGeneratorParameters.OutputDirectory = outputDirectory;
            templateGeneratorParameters.Session = session;
            templateGeneratorParameters.Name = name;
            templateGeneratorParameters.Logger = result;
            templateGeneratorParameters.Description = new TemplateDescription();
            templateGeneratorParameters.Id = assetId;

            if (!PackageUnitTestGenerator.Default.PrepareForRun(templateGeneratorParameters).Result)
            {
                Console.WriteLine(@"Error generating package: PackageUnitTestGenerator.PrepareForRun returned false");
                return;
            }
            if (!PackageUnitTestGenerator.Default.Run(templateGeneratorParameters))
            {
                Console.WriteLine(@"Error generating package: PackageUnitTestGenerator.Run returned false");
                return;
            }
            if (result.HasErrors)
            {
                Console.WriteLine($"Error generating package: {result.ToText()}");
                return;
            }

            var package = session.LocalPackages.Single();

            var previousCurrent = session.CurrentPackage;
            session.CurrentPackage = package;

            // Compute Xenko Sdk relative path
            // We are supposed to be in standard output binary folder, so Xenko root should be at ..\..
            var xenkoPath = UPath.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), new UDirectory(@"..\.."));
            var xenkoRelativePath = new UDirectory(xenkoPath)
                .MakeRelative(outputDirectory)
                .ToString()
                .Replace('/', '\\');
            xenkoRelativePath = xenkoRelativePath.TrimEnd('\\');

            options["Namespace"] = projectNamespace ?? name;
            options["Package"] = package;
            options["Platforms"] = new List<SolutionPlatform>(AssetRegistry.SupportedPlatforms);
            options["XenkoSdkRelativeDir"] = xenkoRelativePath;

            // Generate project template
            result = projectTemplate.Generate(outputDirectory, name, projectGuid, options);
            if (result.HasErrors)
            {
                Console.WriteLine("Error generating solution: {0}", result.ToText());
                return;
            }

            var sharedProfile = package.Profiles.FindSharedProfile();

            // Setup the assets folder
            Directory.CreateDirectory(UPath.Combine(outputDirectory, (UDirectory)"Assets/Shared"));

            // Add Windows test as Shared library
            var projectWindowsRef = new ProjectReference
            {
                Id = projectGuid,
                Location = UPath.Combine(outputDirectory, (UFile)(name + ".Windows.csproj")),
                Type = SiliconStudio.Assets.ProjectType.Library
            };
            sharedProfile.ProjectReferences.Add(projectWindowsRef);

            // Generate executable projects for each platform
            foreach (var platform in AssetRegistry.SupportedPlatforms)
            {
                var platformProfile = new PackageProfile(platform.Name) { Platform = platform.Type };
                platformProfile.AssetFolders.Add(new AssetFolder("Assets/"+ platform.Name));
                
                // Log progress
                var projectName = name + "." + platform.Type;

                // Create project reference
                var projectPlatformRef = new ProjectReference
                {
                    Id = projectGuid,
                    Location = UPath.Combine(outputDirectory, (UFile)(projectName + ".csproj")),
                    Type = SiliconStudio.Assets.ProjectType.Executable
                };

                platformProfile.ProjectReferences.Add(projectPlatformRef);

                // Add build configuration per platform
                platform.Properties.CopyTo(platformProfile.Properties, true);

                package.Profiles.Add(platformProfile);
            }

            session.CurrentPackage = previousCurrent;

            result = session.Save();
            if (result.HasErrors)
            {
                Console.WriteLine("Error saving package: {0}", result.ToText());
                return;
            }
        }
Esempio n. 16
0
        private static void GenerateUnitTestProject(string outputDirectory, string templateFile, string name)
        {
            var projectTemplate = ProjectTemplate.Load(templateFile);

            // Force reference to Paradox.Assets (to have acess to SolutionPlatform)
            projectTemplate.Assemblies.Add(typeof(GraphicsProfile).Assembly.FullName);
            projectTemplate.Assemblies.Add(typeof(ParadoxConfig).Assembly.FullName);

            var options = new Dictionary <string, object>();

            var session = new PackageSession();
            var result  = new LoggerResult();

            var templateGeneratorParameters = new TemplateGeneratorParameters();

            templateGeneratorParameters.OutputDirectory = outputDirectory;
            templateGeneratorParameters.Session         = session;
            templateGeneratorParameters.Name            = name;
            templateGeneratorParameters.Logger          = result;
            templateGeneratorParameters.Description     = new TemplateDescription();

            PackageUnitTestGenerator.Default.Generate(templateGeneratorParameters);
            if (result.HasErrors)
            {
                Console.WriteLine("Error generating package: {0}", result.ToText());
                return;
            }

            var package = templateGeneratorParameters.Package;

            var previousCurrent = session.CurrentPackage;

            session.CurrentPackage = package;

            // Compute Paradox Sdk relative path
            // We are supposed to be in standard output binary folder, so Paradox root should be at ..\..
            var paradoxPath         = UDirectory.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), new UDirectory(@"..\.."));
            var paradoxRelativePath = new UDirectory(paradoxPath)
                                      .MakeRelative(outputDirectory)
                                      .ToString()
                                      .Replace('/', '\\');

            paradoxRelativePath = paradoxRelativePath.TrimEnd('\\');

            options["Namespace"]             = name;
            options["Package"]               = package;
            options["Platforms"]             = new List <SolutionPlatform>(AssetRegistry.SupportedPlatforms);
            options["ParadoxSdkRelativeDir"] = paradoxRelativePath;

            // Generate project template
            var projectGuid = Guid.NewGuid();

            result = projectTemplate.Generate(outputDirectory, name, projectGuid, options);
            if (result.HasErrors)
            {
                Console.WriteLine("Error generating solution: {0}", result.ToText());
                return;
            }

            var sharedProfile = package.Profiles[PlatformType.Shared];

            // Setup the assets folder
            Directory.CreateDirectory(UPath.Combine(outputDirectory, (UDirectory)"Assets/Shared"));

            // Add Windows test as Shared library
            var projectWindowsRef = new ProjectReference();

            projectWindowsRef.Id       = projectGuid;
            projectWindowsRef.Location = UPath.Combine(outputDirectory, (UFile)(name + ".Windows.csproj"));
            projectWindowsRef.Type     = SiliconStudio.Assets.ProjectType.Library;
            sharedProfile.ProjectReferences.Add(projectWindowsRef);

            // Generate executable projects for each platform
            foreach (var platform in AssetRegistry.SupportedPlatforms)
            {
                var platformProfile = new PackageProfile(platform.Name)
                {
                    Platform = platform.Type
                };
                platformProfile.AssetFolders.Add(new AssetFolder("Assets/" + platform.Name));

                // Log progress
                var projectName = name + "." + platform.Type;

                // Create project reference
                var projectPlatformRef = new ProjectReference();
                projectPlatformRef.Id       = projectGuid;
                projectPlatformRef.Location = UPath.Combine(outputDirectory, (UFile)(projectName + ".csproj"));
                projectPlatformRef.Type     = SiliconStudio.Assets.ProjectType.Executable;

                platformProfile.ProjectReferences.Add(projectPlatformRef);

                // Add build configuration per platform
                platform.Properties.CopyTo(platformProfile.Properties, true);

                package.Profiles.Add(platformProfile);
            }

            session.CurrentPackage = previousCurrent;

            result = session.Save();
            if (result.HasErrors)
            {
                Console.WriteLine("Error saving package: {0}", result.ToText());
                return;
            }
        }
Esempio n. 17
0
        public static void Build(ILogger log, Package package, string outputDirectory = null)
        {
            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            var meta = new ManifestMetadata();

            PackageStore.ToNugetManifest(package.Meta, meta);

            // Sanity check: Xenko version should be same between NuGet package and Xenko package
            var nugetVersion   = new PackageVersion(XenkoVersion.NuGetVersion).Version;
            var packageVersion = package.Meta.Version.Version;

            if (nugetVersion != packageVersion)
            {
                log.Error($"Package has mismatching version: NuGet package version is {nugetVersion} and Xenko Package version is {packageVersion}");
                return;
            }

            if (nugetVersion.Revision <= 0)
            {
                // If 0, we have special cases with NuGet dropping it in install path, could be dangerous and lead to bugs if not properly tested.
                log.Error($"Package has revision {nugetVersion} but 4th digit needs to be at least 1.");
                return;
            }

            // Override version with NuGet version (4th number is different in Xenko package)
            meta.Version = XenkoVersion.NuGetVersion;

            var builder = new NugetPackageBuilder();

            builder.Populate(meta);

            var currentAssemblyLocation = Assembly.GetExecutingAssembly().Location;
            var mainPlatformDirectory   = Path.GetFileName(Path.GetDirectoryName(currentAssemblyLocation));

            // TODO this is not working
            // We are excluding everything that is in a folder that starts with a dot (ie. .shadow, .vs)
            var files = new List <ManifestFile>()
            {
                NewFile(@"Bin\**\*.exe", "Bin", @"Bin\**\.*\**\*.exe;Bin\**\Tools\**.exe"),
                NewFile(@"Bin\**\*.so", "Bin", @"Bin\**\.*\**\*.so;Bin\Windows\lib\**\*.so"),
                NewFile(@"Bin\**\*.ssdeps", "Bin", @"Bin\**\.*\**\*.ssdeps"),
                NewFile(@"Bin\**\*.a", "Bin", @"Bin\**\.*\**\*.a"),
                NewFile(@"Bin\**\*.md", "Bin", @"Bin\**\.*\**\*.md"),
                NewFile(@"Bin\**\*.html", "Bin", @"Bin\**\.*\**\*.html"),
                NewFile(@"Bin\**\*.config", "Bin", @"Bin\**\.*\**\*.config"),
                NewFile(@"Bin\**\*.dll", "Bin", @"Bin\**\.*\**\*.dll;Bin\Windows\lib\**\*.dll"),
                NewFile(@"Bin\**\*.xml", "Bin", @"Bin\**\.*\**\*.xml"),
                NewFile(@"Bin\**\*.usrdoc", "Bin", @"Bin\**\.*\**\*.usrdoc"),
                NewFile(@"Bin\**\*.winmd", "Bin", @"Bin\**\.*\**\*.winmd"),
                NewFile(@"Bin\**\*.sh", "Bin", @"Bin\**\.*\**\*.sh"),
                NewFile(@"Bin\**\*.json", "Bin", @"Bin\**\.*\**\*.json"),
                NewFile(@"deps\AssemblyProcessor\*.exe", @"deps/AssemblyProcessor"),
                NewFile(@"deps\AssemblyProcessor\*.dll", @"deps/AssemblyProcessor"),
                NewFile(@"deps\CoreFX\**\*.*", @"deps\CoreFX"),
                NewFile($@"Bin\{mainPlatformDirectory}\ios-tcprelay\*.py", $@"Bin\{mainPlatformDirectory}\ios-tcprelay"),
                NewFile(@"Targets\*.targets", "Targets"),
                NewFile($@"Bin\{mainPlatformDirectory}\SiliconStudio.*.pdb", $@"Bin\{mainPlatformDirectory}", @"Bin\**\SiliconStudio.Xenko.Importer*.pdb;Bin\**\SiliconStudio.Xenko.Assimp.Translation.pdb"),
            };

            // Handle Assets
            var rootDir = package.RootDirectory;


            var newPackage = new Package {
                Meta = package.Meta
            };

            foreach (var profile in package.Profiles)
            {
                var target = "Assets/" + profile.Name;
                foreach (var assetFolder in profile.AssetFolders)
                {
                    // TODO: handle exclude in asset folders
                    //files.Add(NewFile(source, target, @"**\*.cs;**\*.hlsl;**\*.csproj;**\*.csproj.user;**\obj\**"));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xksl", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xkfx", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xkfnt", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xksheet", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xkuilib", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xkgfxcomp", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.xktex", target));
                    var resourceFolder = UPath.Combine(assetFolder.Path, new UDirectory("../../Resources"));
                    if (Directory.Exists(resourceFolder.ToWindowsPath()))
                    {
                        files.Add(NewFile(resourceFolder.MakeRelative(rootDir) + "/**/*.*", "Resources"));
                    }
                }
                var targetProfile = new PackageProfile(profile.Name);
                targetProfile.AssetFolders.Add(new AssetFolder(target));
                newPackage.Profiles.Add(targetProfile);
            }

            //Handle RootAssets
            foreach (var rootAsset in package.RootAssets)
            {
                newPackage.RootAssets.Add(rootAsset);
            }

            // Handle templates
            var targetFolder = new TemplateFolder("Templates");

            foreach (var templateFolder in package.TemplateFolders)
            {
                var        source = templateFolder.Path.MakeRelative(rootDir) + "/**";
                UDirectory target = targetFolder.Path;
                if (templateFolder.Group != null)
                {
                    target = UPath.Combine(target, templateFolder.Group);
                }

                var excludeFiles = templateFolder.Exclude;
                files.Add(NewFile(source, target, excludeFiles));

                // Add template files
                foreach (var templateFile in templateFolder.Files)
                {
                    var newTemplateFile = templateFile.MakeRelative(templateFolder.Path);
                    if (templateFolder.Group != null)
                    {
                        newTemplateFile = UPath.Combine(templateFolder.Group, newTemplateFile);
                    }

                    newTemplateFile = UPath.Combine(targetFolder.Path, newTemplateFile);
                    targetFolder.Files.Add(newTemplateFile);
                }
            }

            // Add files
            builder.PopulateFiles(package.RootDirectory, files);
            files.Clear();

            var dataFiles = builder.Files.ToList();

            builder.ClearFiles();

            // Create temp package for archive
            newPackage.TemplateFolders.Add(targetFolder);
            var newPackageFileName = "temp" + Guid.NewGuid() + ".xkpkg";

            newPackage.FullPath = package.RootDirectory + "/" + newPackageFileName;
            var result = new LoggerResult();

            newPackage.Save(result);
            if (result.HasErrors)
            {
                throw new InvalidOperationException(result.ToText());
                // TODO throw error
            }

            // Add the package file
            files.Add(NewFile(newPackageFileName, package.Meta.Name + Package.PackageFileExtension));
            // Add entry point to decompress LZMA
            files.Add(NewFile(@"tools\**\*.exe", "tools"));
            files.Add(NewFile(@"tools\**\*.dll", "tools"));
            // Add an empty .xz file so that it gets added to [Content_Types].xml
            // This file will be removed later
            files.Add(NewFile(@"tools\data_empty.xz", string.Empty));

            // Repopulate with .xkpkg file
            builder.PopulateFiles(package.RootDirectory, files);

            outputDirectory = outputDirectory ?? Environment.CurrentDirectory;

            // Save the nupkg
            var  outputPath        = GetOutputPath(builder, outputDirectory);
            bool isExistingPackage = File.Exists(outputPath);

            if (isExistingPackage)
            {
                File.Delete(outputPath);
            }
            try
            {
                using (Stream stream = File.Create(outputPath))
                {
                    builder.Save(stream);

                    stream.Position = 0;

                    // Add LZMA file as update so that it is stored without compression
                    using (var archive = new ZipArchive(stream, ZipArchiveMode.Update, true))
                    {
                        // Delete data_empty.xz
                        var dataEntry = archive.GetEntry("data_empty.xz");
                        dataEntry.Delete();

                        // Create data.xz (no compression since .xz is already compressed)
                        dataEntry = archive.CreateEntry("data.xz", CompressionLevel.NoCompression);
                        using (var dataStream = dataEntry.Open())
                        {
                            // Generate LZMA
                            using (var indexedArchive = new IndexedArchive())
                            {
                                foreach (var file in dataFiles)
                                {
                                    indexedArchive.AddFile(Path.Combine(package.RootDirectory, file.SourcePath), file.Path);
                                }
                                indexedArchive.Save(dataStream, new ConsoleProgressReport());
                            }
                        }
                    }
                }
            }
            catch
            {
                if (!isExistingPackage && File.Exists(outputPath))
                {
                    File.Delete(outputPath);
                }
                throw;
            }

            File.Delete(newPackage.FullPath);
        }