Newer
Older
dub_jkp / source / dub / init.d
@Sönke Ludwig Sönke Ludwig on 23 Nov 2016 5 KB Update vibe.d template for 0.7.30.
  1. /**
  2. Package skeleton initialization code.
  3.  
  4. Copyright: © 2013-2016 rejectedsoftware e.K.
  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.init;
  9.  
  10. import dub.internal.vibecompat.core.file;
  11. import dub.internal.vibecompat.core.log;
  12. import dub.package_ : PackageFormat, packageInfoFiles, defaultPackageFilename;
  13. import dub.recipe.packagerecipe;
  14. import dub.dependency;
  15.  
  16. import std.datetime;
  17. import std.exception;
  18. import std.file;
  19. import std.format;
  20. import std.process;
  21. import std.string;
  22.  
  23.  
  24. /** Intializes a new package in the given directory.
  25.  
  26. The given `root_path` will be checked for any of the files that will be
  27. created by this function. If any exist, an exception will be thrown before
  28. altering the directory.
  29.  
  30. Params:
  31. root_path = Directory in which to create the new package. If the
  32. directory doesn't exist, a new one will be created.
  33. deps = A set of extra dependencies to add to the package recipe. The
  34. associative array is expected to map from package name to package
  35. version.
  36. type = The type of package skeleton to create. Can currently be
  37. "minimal", "vibe.d" or "deimos"
  38. recipe_callback = Optional callback that can be used to customize the
  39. package recipe and the file format used to store it prior to
  40. writing it to disk.
  41. */
  42. void initPackage(Path root_path, string[string] deps, string type,
  43. PackageFormat format, scope RecipeCallback recipe_callback = null)
  44. {
  45. import std.conv : to;
  46. import dub.recipe.io : writePackageRecipe;
  47.  
  48. void enforceDoesNotExist(string filename) {
  49. enforce(!existsFile(root_path ~ filename), "The target directory already contains a '"~filename~"' file. Aborting.");
  50. }
  51.  
  52. string username = getUserName();
  53.  
  54. PackageRecipe p;
  55. p.name = root_path.head.toString().toLower();
  56. p.authors ~= username;
  57. p.license = "proprietary";
  58. p.copyright = .format("Copyright © %s, %s", Clock.currTime().year, username);
  59. foreach (pack, v; deps) {
  60. import std.ascii : isDigit;
  61. p.buildSettings.dependencies[pack] = Dependency(v);
  62. }
  63.  
  64. //Check to see if a target directory needs to be created
  65. if (!root_path.empty) {
  66. if (!existsFile(root_path))
  67. createDirectory(root_path);
  68. }
  69.  
  70. //Make sure we do not overwrite anything accidentally
  71. foreach (fil; packageInfoFiles)
  72. enforceDoesNotExist(fil.filename);
  73.  
  74. auto files = ["source/", "views/", "public/", "dub.json", ".gitignore"];
  75. foreach (fil; files)
  76. enforceDoesNotExist(fil);
  77.  
  78. void processRecipe()
  79. {
  80. if (recipe_callback)
  81. recipe_callback(p, format);
  82. }
  83.  
  84. switch (type) {
  85. default: throw new Exception("Unknown package init type: "~type);
  86. case "minimal": initMinimalPackage(root_path, p, &processRecipe); break;
  87. case "vibe.d": initVibeDPackage(root_path, p, &processRecipe); break;
  88. case "deimos": initDeimosPackage(root_path, p, &processRecipe); break;
  89. }
  90.  
  91. writePackageRecipe(root_path ~ ("dub."~format.to!string), p);
  92. writeGitignore(root_path);
  93. }
  94.  
  95. alias RecipeCallback = void delegate(ref PackageRecipe, ref PackageFormat);
  96.  
  97. private void initMinimalPackage(Path root_path, ref PackageRecipe p, scope void delegate() pre_write_callback)
  98. {
  99. p.description = "A minimal D application.";
  100. pre_write_callback();
  101.  
  102. createDirectory(root_path ~ "source");
  103. write((root_path ~ "source/app.d").toNativeString(),
  104. q{import std.stdio;
  105.  
  106. void main()
  107. {
  108. writeln("Edit source/app.d to start your project.");
  109. }
  110. });
  111. }
  112.  
  113. private void initVibeDPackage(Path root_path, ref PackageRecipe p, scope void delegate() pre_write_callback)
  114. {
  115. if ("vibe-d" !in p.buildSettings.dependencies)
  116. p.buildSettings.dependencies["vibe-d"] = Dependency("~>0.7.30");
  117. p.description = "A simple vibe.d server application.";
  118. pre_write_callback();
  119.  
  120. createDirectory(root_path ~ "source");
  121. createDirectory(root_path ~ "views");
  122. createDirectory(root_path ~ "public");
  123. write((root_path ~ "source/app.d").toNativeString(),
  124. q{import vibe.vibe;
  125.  
  126. void main()
  127. {
  128. auto settings = new HTTPServerSettings;
  129. settings.port = 8080;
  130. settings.bindAddresses = ["::1", "127.0.0.1"];
  131. listenHTTP(settings, &hello);
  132.  
  133. logInfo("Please open http://127.0.0.1:8080/ in your browser.");
  134. runApplication();
  135. }
  136.  
  137. void hello(HTTPServerRequest req, HTTPServerResponse res)
  138. {
  139. res.writeBody("Hello, World!");
  140. }
  141. });
  142. }
  143.  
  144. private void initDeimosPackage(Path root_path, ref PackageRecipe p, scope void delegate() pre_write_callback)
  145. {
  146. import dub.compilers.buildsettings : TargetType;
  147.  
  148. auto name = root_path.head.toString().toLower();
  149. p.description = format("Deimos Bindings for "~p.name~".");
  150. p.buildSettings.importPaths[""] ~= ".";
  151. p.buildSettings.targetType = TargetType.sourceLibrary;
  152. pre_write_callback();
  153.  
  154. createDirectory(root_path ~ "C");
  155. createDirectory(root_path ~ "deimos");
  156. }
  157.  
  158. private void writeGitignore(Path root_path)
  159. {
  160. write((root_path ~ ".gitignore").toNativeString(),
  161. ".dub\ndocs.json\n__dummy.html\n*.o\n*.obj\n__test__*__\n");
  162. }
  163.  
  164. private string getUserName()
  165. {
  166. version (Windows)
  167. return environment.get("USERNAME", "Peter Parker");
  168. else version (Posix)
  169. {
  170. import core.sys.posix.pwd, core.sys.posix.unistd, core.stdc.string : strlen;
  171. import std.algorithm : splitter;
  172.  
  173. if (auto pw = getpwuid(getuid))
  174. {
  175. auto uinfo = pw.pw_gecos[0 .. strlen(pw.pw_gecos)].splitter(',');
  176. if (!uinfo.empty && uinfo.front.length)
  177. return uinfo.front.idup;
  178. }
  179. return environment.get("USER", "Peter Parker");
  180. }
  181. else
  182. static assert(0);
  183. }