Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
PackageArchive.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.IO;
6 using SiliconStudio.Core.IO;
7 
8 namespace SiliconStudio.Assets
9 {
10  public sealed class PackageArchive
11  {
12  public static void Build(Package package, string outputDirectory = null)
13  {
14  if (package == null) throw new ArgumentNullException("package");
15 
16  var meta = new NuGet.ManifestMetadata();
17  package.Meta.ToNugetManifest(meta);
18 
19  var builder = new NuGet.PackageBuilder();
20  builder.Populate(meta);
21 
22  // TODO this is not working
23  var files = new List<NuGet.ManifestFile>()
24  {
25  NewFile(@"Bin\**\*.exe", "Bin"),
26  NewFile(@"Bin\**\*.vsix", "Bin"),
27  NewFile(@"Bin\**\*.so", "Bin"),
28  NewFile(@"Bin\**\*.a", "Bin"),
29  NewFile(@"Bin\**\*.md", "Bin"),
30  NewFile(@"Bin\**\*.html", "Bin"),
31  NewFile(@"Bin\**\*.config", "Bin"),
32  NewFile(@"Bin\**\*.dll", "Bin"),
33  NewFile(@"Bin\**\*.xml", "Bin"),
34  NewFile(@"Bin\**\*.winmd", "Bin"),
35  NewFile(@"Targets\*.targets", "Targets"),
36  };
37 
38  // Handle Assets
39  var rootDir = package.RootDirectory;
40 
41  var newPackage = new Package { Meta = package.Meta };
42 
43  foreach (var profile in package.Profiles)
44  {
45  var target = "Assets/" + profile.Name;
46  foreach (var assetFolder in profile.AssetFolders)
47  {
48  // TODO: handle exclude in asset folders
49  //files.Add(NewFile(source, target, @"**\*.cs;**\*.hlsl;**\*.csproj;**\*.csproj.user;**\obj\**"));
50  files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.pdxsl", target));
51  files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.pdxfx", target));
52  }
53 
54  // TODO: Hardcoded because of lack of file/regex-pattern (gitignore-style?) in PackageProfile.AssetFolders
55  files.Add(NewFile(@"sources\shaders\SiliconStudio.Paradox.Shaders.csproj", target));
56  files.Add(NewFile(@"sources\shaders\SiliconStudio.Paradox.Shaders.sln", target));
57 
58  var targetProfile = new PackageProfile(profile.Name);
59  targetProfile.AssetFolders.Add(new AssetFolder(target));
60  newPackage.Profiles.Add(targetProfile);
61  }
62 
63  // Handle templates
64  var targetFolder = new TemplateFolder("Templates");
65 
66  foreach (var templateFolder in package.TemplateFolders)
67  {
68  var source = templateFolder.Path.MakeRelative(rootDir) + "/**";
69  UDirectory target = targetFolder.Path;
70  if (templateFolder.Group != null)
71  {
72  target = UPath.Combine(target, templateFolder.Group);
73  }
74 
75  var excludeFiles = templateFolder.Exclude;
76  files.Add(NewFile(source, target, excludeFiles));
77 
78  // Add template files
79  foreach (var templateFile in templateFolder.Files)
80  {
81  var newTemplateFile = templateFile.MakeRelative(templateFolder.Path);
82  if (templateFolder.Group != null)
83  {
84  newTemplateFile = UPath.Combine(templateFolder.Group, newTemplateFile);
85  }
86 
87  newTemplateFile = UPath.Combine(targetFolder.Path, newTemplateFile);
88  targetFolder.Files.Add(newTemplateFile);
89  }
90  }
91 
92  // Create temp package for archive
93  newPackage.TemplateFolders.Add(targetFolder);
94  var newPackageFileName = "temp" + Guid.NewGuid() + ".pdxpkg";
95  newPackage.FullPath = package.RootDirectory + "/" + newPackageFileName;
96  var result = newPackage.Save();
97  if (result.HasErrors)
98  {
99  throw new InvalidOperationException(result.ToText());
100  // TODO throw error
101  }
102  files.Add(NewFile(newPackageFileName, package.Meta.Name + Package.PackageFileExtension));
103 
104  // Add files
105  builder.PopulateFiles(package.RootDirectory, files);
106 
107  outputDirectory = outputDirectory ?? Environment.CurrentDirectory;
108 
109  // Save the nupkg
110  var outputPath = GetOutputPath(builder, outputDirectory);
111  bool isExistingPackage = File.Exists(outputPath);
112  if (isExistingPackage)
113  {
114  File.Delete(outputPath);
115  }
116  try
117  {
118  using (Stream stream = File.Create(outputPath))
119  {
120  builder.Save(stream);
121  }
122  }
123  catch
124  {
125  if (!isExistingPackage && File.Exists(outputPath))
126  {
127  File.Delete(outputPath);
128  }
129  throw;
130  }
131 
132  File.Delete(newPackage.FullPath);
133  }
134 
135  private static NuGet.ManifestFile NewFile(string source, string target, string exclude = null)
136  {
137  return new NuGet.ManifestFile()
138  {
139  Source = source.Replace('/', '\\'),
140  Target = target.Replace('/', '\\'),
141  Exclude = exclude
142  };
143  }
144 
145  private static string GetOutputPath(NuGet.PackageBuilder builder, string outputDirectory)
146  {
147  string version = builder.Version.ToString();
148 
149  // Output file is {id}.{version}
150  string outputFile = builder.Id + "." + version;
151  outputFile += NuGet.Constants.PackageExtension;
152 
153  return Path.Combine(outputDirectory, outputFile);
154  }
155  }
156 }
static void Build(Package package, string outputDirectory=null)
A location relative to a package from where assets will be loaded
Definition: AssetFolder.cs:16
Defines a normalized directory path. See UPath for details. This class cannot be inherited.
Definition: UDirectory.cs:13
const string PackageFileExtension
The file extension used for Package.
Definition: Package.cs:46
System.IO.File File
Describes a template folder.
Describes buld parameters used when building assets.
A package managing assets.
Definition: Package.cs:28