1 module dlangide.builders.builder; 2 3 import dlangui.core.logger; 4 import dlangide.workspace.project; 5 import dlangide.workspace.workspace; 6 import dlangide.ui.outputpanel; 7 import dlangide.builders.extprocess; 8 import dlangui.widgets.appframe; 9 import std.algorithm; 10 import core.thread; 11 import std..string; 12 import std.conv; 13 14 class Builder : BackgroundOperationWatcher { 15 protected Project _project; 16 protected ExternalProcess _extprocess; 17 protected OutputPanel _log; 18 protected ProtectedTextStorage _box; 19 protected BuildConfiguration _buildConfig; 20 protected BuildOperation _buildOp; 21 protected bool _verbose; 22 23 @property Project project() { return _project; } 24 @property void project(Project p) { _project = p; } 25 26 this(AppFrame frame, Project project, OutputPanel log, BuildConfiguration buildConfig, BuildOperation buildOp, bool verbose) { 27 super(frame); 28 _buildConfig = buildConfig; 29 _buildOp = buildOp; 30 _verbose = verbose; 31 _project = project; 32 _log = log; 33 _extprocess = new ExternalProcess(); 34 _box = new ProtectedTextStorage(); 35 } 36 /// log lines 37 void pollText() { 38 dstring text = _box.readText(); 39 if (text.length) { 40 _log.appendText(null, text); 41 } 42 } 43 44 /// returns icon of background operation to show in status line 45 override @property string icon() { return "folder"; } 46 /// update background operation status 47 override void update() { 48 scope(exit)pollText(); 49 ExternalProcessState state = _extprocess.state; 50 if (state == ExternalProcessState.None) { 51 _log.clear(); 52 _box.writeText("Running dub\n"d); 53 char[] program = "dub".dup; 54 char[][] params; 55 char[] dir = _project.dir.dup; 56 57 if (_buildOp == BuildOperation.Build || _buildOp == BuildOperation.Rebuild) { 58 params ~= "build".dup; 59 if (_buildOp == BuildOperation.Rebuild) { 60 params ~= "--force".dup; 61 } 62 } else if (_buildOp == BuildOperation.Clean) { 63 params ~= "clean".dup; 64 } else if (_buildOp == BuildOperation.Run) { 65 params ~= "run".dup; 66 } else if (_buildOp == BuildOperation.Upgrade) { 67 params ~= "upgrade".dup; 68 params ~= "--force-remove".dup; 69 } 70 71 if (_buildOp != BuildOperation.Clean && _buildOp != BuildOperation.Upgrade) { 72 switch (_buildConfig) { 73 default: 74 case BuildConfiguration.Debug: 75 params ~= "--build=debug".dup; 76 break; 77 case BuildConfiguration.Release: 78 params ~= "--build=release".dup; 79 break; 80 case BuildConfiguration.Unittest: 81 params ~= "--build=unittest".dup; 82 break; 83 } 84 } 85 86 if (_verbose) 87 params ~= "-v".dup; 88 89 state = _extprocess.run(program, params, dir, _box, null); 90 if (state != ExternalProcessState.Running) { 91 _box.writeText("Failed to run builder tool\n"d); 92 _finished = true; 93 destroy(_extprocess); 94 _extprocess = null; 95 return; 96 } 97 } 98 state = _extprocess.poll(); 99 if (state == ExternalProcessState.Stopped) { 100 _box.writeText("Builder finished with result "d ~ to!dstring(_extprocess.result) ~ "\n"d); 101 _finished = true; 102 return; 103 } 104 if (_cancelRequested) { 105 _extprocess.kill(); 106 _extprocess.wait(); 107 _finished = true; 108 return; 109 } 110 super.update(); 111 } 112 }