Newer
Older
dub_jkp / source / dub / recipe / io.d
@Sönke Ludwig Sönke Ludwig on 4 Dec 2017 5 KB Rename Path to NativePath.
  1. /**
  2. Package recipe reading/writing facilities.
  3.  
  4. Copyright: © 2015-2016, Sönke Ludwig
  5. License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
  6. Authors: Sönke Ludwig
  7. */
  8. module dub.recipe.io;
  9.  
  10. import dub.recipe.packagerecipe;
  11. import dub.internal.vibecompat.inet.path;
  12.  
  13.  
  14. /** Reads a package recipe from a file.
  15.  
  16. The file format (JSON/SDLang) will be determined from the file extension.
  17.  
  18. Params:
  19. filename = NativePath of the package recipe file
  20. parent_name = Optional name of the parent package (if this is a sub package)
  21.  
  22. Returns: Returns the package recipe contents
  23. Throws: Throws an exception if an I/O or syntax error occurs
  24. */
  25. PackageRecipe readPackageRecipe(string filename, string parent_name = null)
  26. {
  27. return readPackageRecipe(NativePath(filename), parent_name);
  28. }
  29. /// ditto
  30. PackageRecipe readPackageRecipe(NativePath filename, string parent_name = null)
  31. {
  32. import dub.internal.utils : stripUTF8Bom;
  33. import dub.internal.vibecompat.core.file : openFile, FileMode;
  34.  
  35. string text;
  36.  
  37. {
  38. auto f = openFile(filename.toNativeString(), FileMode.read);
  39. scope(exit) f.close();
  40. text = stripUTF8Bom(cast(string)f.readAll());
  41. }
  42.  
  43. return parsePackageRecipe(text, filename.toNativeString(), parent_name);
  44. }
  45.  
  46. /** Parses an in-memory package recipe.
  47.  
  48. The file format (JSON/SDLang) will be determined from the file extension.
  49.  
  50. Params:
  51. contents = The contents of the recipe file
  52. filename = Name associated with the package recipe - this is only used
  53. to determine the file format from the file extension
  54. parent_name = Optional name of the parent package (if this is a sub
  55. package)
  56. default_package_name = Optional default package name (if no package name
  57. is found in the recipe this value will be used)
  58.  
  59. Returns: Returns the package recipe contents
  60. Throws: Throws an exception if an I/O or syntax error occurs
  61. */
  62. PackageRecipe parsePackageRecipe(string contents, string filename, string parent_name = null,
  63. string default_package_name = null)
  64. {
  65. import std.algorithm : endsWith;
  66. import dub.internal.vibecompat.data.json;
  67. import dub.recipe.json : parseJson;
  68. import dub.recipe.sdl : parseSDL;
  69.  
  70. PackageRecipe ret;
  71.  
  72. ret.name = default_package_name;
  73.  
  74. if (filename.endsWith(".json")) parseJson(ret, parseJsonString(contents, filename), parent_name);
  75. else if (filename.endsWith(".sdl")) parseSDL(ret, contents, parent_name, filename);
  76. else assert(false, "readPackageRecipe called with filename with unknown extension: "~filename);
  77. return ret;
  78. }
  79.  
  80.  
  81. unittest { // issue #711 - configuration default target type not correct for SDL
  82. import dub.compilers.buildsettings : TargetType;
  83. auto inputs = [
  84. "dub.sdl": "name \"test\"\nconfiguration \"a\" {\n}",
  85. "dub.json": "{\"name\": \"test\", \"configurations\": [{\"name\": \"a\"}]}"
  86. ];
  87. foreach (file, content; inputs) {
  88. auto pr = parsePackageRecipe(content, file);
  89. assert(pr.name == "test");
  90. assert(pr.configurations.length == 1);
  91. assert(pr.configurations[0].name == "a");
  92. assert(pr.configurations[0].buildSettings.targetType == TargetType.library);
  93. }
  94. }
  95.  
  96. unittest { // issue #711 - configuration default target type not correct for SDL
  97. import dub.compilers.buildsettings : TargetType;
  98. auto inputs = [
  99. "dub.sdl": "name \"test\"\ntargetType \"autodetect\"\nconfiguration \"a\" {\n}",
  100. "dub.json": "{\"name\": \"test\", \"targetType\": \"autodetect\", \"configurations\": [{\"name\": \"a\"}]}"
  101. ];
  102. foreach (file, content; inputs) {
  103. auto pr = parsePackageRecipe(content, file);
  104. assert(pr.name == "test");
  105. assert(pr.configurations.length == 1);
  106. assert(pr.configurations[0].name == "a");
  107. assert(pr.configurations[0].buildSettings.targetType == TargetType.library);
  108. }
  109. }
  110.  
  111. unittest { // issue #711 - configuration default target type not correct for SDL
  112. import dub.compilers.buildsettings : TargetType;
  113. auto inputs = [
  114. "dub.sdl": "name \"test\"\ntargetType \"executable\"\nconfiguration \"a\" {\n}",
  115. "dub.json": "{\"name\": \"test\", \"targetType\": \"executable\", \"configurations\": [{\"name\": \"a\"}]}"
  116. ];
  117. foreach (file, content; inputs) {
  118. auto pr = parsePackageRecipe(content, file);
  119. assert(pr.name == "test");
  120. assert(pr.configurations.length == 1);
  121. assert(pr.configurations[0].name == "a");
  122. assert(pr.configurations[0].buildSettings.targetType == TargetType.executable);
  123. }
  124. }
  125.  
  126.  
  127. /** Writes the textual representation of a package recipe to a file.
  128.  
  129. Note that the file extension must be either "json" or "sdl".
  130. */
  131. void writePackageRecipe(string filename, in ref PackageRecipe recipe)
  132. {
  133. import dub.internal.vibecompat.core.file : openFile, FileMode;
  134. auto f = openFile(filename, FileMode.createTrunc);
  135. scope(exit) f.close();
  136. serializePackageRecipe(f, recipe, filename);
  137. }
  138.  
  139. /// ditto
  140. void writePackageRecipe(NativePath filename, in ref PackageRecipe recipe)
  141. {
  142. writePackageRecipe(filename.toNativeString, recipe);
  143. }
  144.  
  145. /** Converts a package recipe to its textual representation.
  146.  
  147. The extension of the supplied `filename` must be either "json" or "sdl".
  148. The output format is chosen accordingly.
  149. */
  150. void serializePackageRecipe(R)(ref R dst, in ref PackageRecipe recipe, string filename)
  151. {
  152. import std.algorithm : endsWith;
  153. import dub.internal.vibecompat.data.json : writeJsonString;
  154. import dub.recipe.json : toJson;
  155. import dub.recipe.sdl : toSDL;
  156.  
  157. if (filename.endsWith(".json"))
  158. dst.writeJsonString!(R, true)(toJson(recipe));
  159. else if (filename.endsWith(".sdl"))
  160. toSDL(recipe).toSDLDocument(dst);
  161. else assert(false, "writePackageRecipe called with filename with unknown extension: "~filename);
  162. }
  163.