A tool that tries to build every Dub package against a wide range of DMD versions.

git.d 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. module backporter.git;
  2. import core.time;
  3. import std.datetime.systime;
  4. import std.experimental.logger;
  5. import std.process;
  6. import std.stdio : File;
  7. static this()
  8. {
  9. import std.file : getcwd;
  10. import std.path : absolutePath, buildPath;
  11. dataDir = buildPath(getcwd, "projects").absolutePath;
  12. }
  13. void cd(string dir)
  14. {
  15. procDir = dir;
  16. tracef("cd %s", dir);
  17. }
  18. ProcessResult cmd(string name)(string[] args...)
  19. {
  20. // If a project has been deleted, github (at least) asks you to log in,
  21. // because it might instead have been made private.
  22. // 30 seconds should be plenty to get the data when it's available and
  23. // not terribly long to wait otherwise.
  24. return run(30.seconds, ["git", name] ~ args);
  25. }
  26. ProcessResult run(string[] args...)
  27. {
  28. tracef("running: %s", args);
  29. auto start = Clock.currTime;
  30. auto p = execute(args, env, Config.init, size_t.max, procDir);
  31. auto end = Clock.currTime;
  32. return ProcessResult(p.status, end - start, false);
  33. }
  34. ProcessResult run(Duration maxTime, string[] args...)
  35. {
  36. tracef("running@%s: %s", procDir, args);
  37. ProcessResult result;
  38. import std.path : buildPath;
  39. auto stderrPath = buildPath(procDir, ".stderr");
  40. auto childStderr = File(stderrPath, "w");
  41. auto start = Clock.currTime;
  42. auto deadline = start + maxTime;
  43. auto pid = spawnProcess(
  44. args,
  45. // stdin / stdout / stderr
  46. File("/dev/null", "r"),
  47. File(buildPath(procDir, ".stdout"), "w"),
  48. childStderr,
  49. env,
  50. Config.none,
  51. procDir);
  52. SysTime end;
  53. while (true)
  54. {
  55. auto p = tryWait(pid);
  56. end = Clock.currTime;
  57. if (p.terminated)
  58. {
  59. result.status = p.status;
  60. break;
  61. }
  62. if (end >= deadline)
  63. {
  64. result.timedOut = true;
  65. result.status = int.max;
  66. return result;
  67. }
  68. import core.thread : Thread;
  69. Thread.sleep(500.msecs);
  70. }
  71. import std.file : read;
  72. result.stderr = cast(const(ubyte)[])read(stderrPath);
  73. result.runningTime = end - start;
  74. return result;
  75. }
  76. alias clone = cmd!"clone";
  77. alias reset = cmd!"reset";
  78. private string procDir;
  79. string dataDir;
  80. string[string] env;
  81. import std.traits : ReturnType;
  82. struct ProcessResult
  83. {
  84. int status;
  85. Duration runningTime;
  86. bool timedOut;
  87. //
  88. const(ubyte)[] stderr;
  89. }