Newer
Older
dub_jkp / source / dub / init.d
@Sönke Ludwig Sönke Ludwig on 24 Jan 2016 4 KB Avoid possible range error.
  1. /**
  2. Empty package initialization code.
  3.  
  4. Copyright: © 2013-2015 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. void initPackage(Path root_path, string[string] deps, string type, PackageFormat format, scope void delegate(ref PackageRecipe, ref PackageFormat) recipe_callback = null)
  24. {
  25. import std.conv : to;
  26. import dub.recipe.io : writePackageRecipe;
  27.  
  28. void enforceDoesNotExist(string filename) {
  29. enforce(!existsFile(root_path ~ filename), "The target directory already contains a '"~filename~"' file. Aborting.");
  30. }
  31.  
  32. string username = getUserName();
  33.  
  34. PackageRecipe p;
  35. p.name = root_path.head.toString().toLower();
  36. p.authors ~= username;
  37. p.license = "proprietary";
  38. p.copyright = .format("Copyright © %s, %s", Clock.currTime().year, username);
  39. foreach (pack, v; deps) {
  40. import std.ascii : isDigit;
  41. p.buildSettings.dependencies[pack] = Dependency(v);
  42. }
  43.  
  44. //Check to see if a target directory needs to be created
  45. if( !root_path.empty ){
  46. if( !existsFile(root_path) )
  47. createDirectory(root_path);
  48. }
  49.  
  50. //Make sure we do not overwrite anything accidentally
  51. foreach (fil; packageInfoFiles)
  52. enforceDoesNotExist(fil.filename);
  53.  
  54. auto files = ["source/", "views/", "public/", "dub.json", ".gitignore"];
  55. foreach (fil; files)
  56. enforceDoesNotExist(fil);
  57.  
  58. switch (type) {
  59. default: throw new Exception("Unknown package init type: "~type);
  60. case "minimal": initMinimalPackage(root_path, p); break;
  61. case "vibe.d": initVibeDPackage(root_path, p); break;
  62. case "deimos": initDeimosPackage(root_path, p); break;
  63. }
  64.  
  65. if (recipe_callback) recipe_callback(p, format);
  66. writePackageRecipe(root_path ~ ("dub."~format.to!string), p);
  67. writeGitignore(root_path);
  68. }
  69.  
  70. private void initMinimalPackage(Path root_path, ref PackageRecipe p)
  71. {
  72. p.description = "A minimal D application.";
  73. createDirectory(root_path ~ "source");
  74. write((root_path ~ "source/app.d").toNativeString(),
  75. q{import std.stdio;
  76.  
  77. void main()
  78. {
  79. writeln("Edit source/app.d to start your project.");
  80. }
  81. });
  82. }
  83.  
  84. private void initVibeDPackage(Path root_path, ref PackageRecipe p)
  85. {
  86. if("vibe-d" !in p.dependencies)
  87. p.buildSettings.dependencies["vibe-d"] = Dependency("~>0.7.26");
  88. p.description = "A simple vibe.d server application.";
  89. p.buildSettings.versions[""] ~= "VibeDefaultMain";
  90.  
  91. createDirectory(root_path ~ "source");
  92. createDirectory(root_path ~ "views");
  93. createDirectory(root_path ~ "public");
  94. write((root_path ~ "source/app.d").toNativeString(),
  95. q{import vibe.d;
  96.  
  97. shared static this()
  98. {
  99. auto settings = new HTTPServerSettings;
  100. settings.port = 8080;
  101. settings.bindAddresses = ["::1", "127.0.0.1"];
  102. listenHTTP(settings, &hello);
  103.  
  104. logInfo("Please open http://127.0.0.1:8080/ in your browser.");
  105. }
  106.  
  107. void hello(HTTPServerRequest req, HTTPServerResponse res)
  108. {
  109. res.writeBody("Hello, World!");
  110. }
  111. });
  112. }
  113.  
  114. private void initDeimosPackage(Path root_path, ref PackageRecipe p)
  115. {
  116. import dub.compilers.buildsettings : TargetType;
  117.  
  118. auto name = root_path.head.toString().toLower();
  119. p.description = format("Deimos Bindings for "~p.name~".");
  120. p.buildSettings.importPaths[""] ~= ".";
  121. p.buildSettings.targetType = TargetType.sourceLibrary;
  122. createDirectory(root_path ~ "C");
  123. createDirectory(root_path ~ "deimos");
  124. }
  125.  
  126. void writeGitignore(Path root_path)
  127. {
  128. write((root_path ~ ".gitignore").toNativeString(),
  129. ".dub\ndocs.json\n__dummy.html\n*.o\n*.obj\n");
  130. }
  131.  
  132. private string getUserName()
  133. {
  134. version (Windows)
  135. return environment.get("USERNAME", "Peter Parker");
  136. else version (Posix)
  137. {
  138. import core.sys.posix.pwd, core.sys.posix.unistd, core.stdc.string : strlen;
  139. import std.algorithm : splitter;
  140.  
  141. if (auto pw = getpwuid(getuid))
  142. {
  143. auto uinfo = pw.pw_gecos[0 .. strlen(pw.pw_gecos)].splitter(',');
  144. if (!uinfo.empty && uinfo.front.length)
  145. return uinfo.front.idup;
  146. }
  147. return environment.get("USER", "Peter Parker");
  148. }
  149. else
  150. static assert(0);
  151. }