1 module dls.updater;
2 
3 void update()
4 {
5     import dls.protocol.interfaces : MessageActionItem, MessageType,
6         ShowMessageParams, ShowMessageRequestParams;
7     import dls.protocol.messages : Util;
8     import dls.server : Server;
9     import dub.compilers.buildsettings : BuildSettings;
10     import dub.compilers.compiler : getCompiler;
11     import dub.dependency : Dependency;
12     import dub.dub : Dub, FetchOptions;
13     import dub.generators.generator : GeneratorSettings;
14     import dub.package_ : Package;
15     import std.concurrency : ownerTid, receiveOnly, register, send, thisTid;
16     import std.file : thisExePath;
17     import std.path : buildNormalizedPath, dirName;
18 
19     auto currentDlsPath = dirName(thisExePath());
20     auto dub = new Dub(currentDlsPath);
21     dub.loadPackage();
22     const currentDls = dub.project.rootPackage;
23     Package[] toRemove;
24 
25     auto latestDlsPath = currentDlsPath;
26     scope (exit)
27     {
28         Server.send("telemetry/event", latestDlsPath);
29     }
30 
31     foreach (dls; dub.packageManager.getPackageIterator("dls"))
32     {
33         if (dls.version_ < currentDls.version_)
34         {
35             toRemove ~= dls;
36         }
37     }
38 
39     foreach (dls; toRemove)
40     {
41         dub.remove(dls);
42     }
43 
44     const latestVersion = dub.getLatestVersion("dls");
45 
46     if (latestVersion.isUnknown() || currentDls.version_ == latestVersion)
47     {
48         return;
49     }
50 
51     auto requestParams = new ShowMessageRequestParams();
52     requestParams.type = MessageType.info;
53     requestParams.message = "DLS version " ~ latestVersion.toString() ~ " available";
54     requestParams.actions = [new MessageActionItem()];
55     requestParams.actions[0].title = "Upgrade";
56 
57     auto id = Server.send("window/showMessageRequest", requestParams);
58     auto threadName = "updater";
59     register(threadName, thisTid());
60     send(ownerTid(), Util.ThreadMessageData(id,
61             Util.ShowMessageRequestType.upgradeDls, threadName));
62 
63     const shouldUpgrade = receiveOnly!bool();
64 
65     if (!shouldUpgrade)
66     {
67         return;
68     }
69 
70     FetchOptions fetchOpts;
71     fetchOpts |= FetchOptions.forceBranchUpgrade;
72     const pack = dub.fetch("dls", Dependency(">=0.0.0"), dub.defaultPlacementLocation, fetchOpts);
73     dub = new Dub(pack.path.toString());
74     dub.loadPackage();
75 
76     GeneratorSettings settings;
77     BuildSettings buildSettings;
78 
79     version (Windows)
80     {
81         const arch = "x86_mscoff";
82     }
83     else
84     {
85         const arch = dub.defaultArchitecture;
86     }
87 
88     auto compiler = getCompiler(dub.defaultCompiler);
89     auto buildPlatform = compiler.determinePlatform(buildSettings, dub.defaultCompiler, arch);
90 
91     settings.platform = buildPlatform;
92     settings.config = "application";
93     settings.buildType = "release";
94     settings.compiler = compiler;
95     settings.buildSettings = buildSettings;
96     settings.combined = false;
97     settings.run = false;
98     settings.force = false;
99     settings.rdmd = false;
100     settings.tempBuild = false;
101     settings.parallelBuild = false;
102     dub.generateProject("build", settings);
103     latestDlsPath = buildNormalizedPath(pack.path.toString(), "dls");
104 
105     auto notificationParams = new ShowMessageParams();
106     notificationParams.type = MessageType.info;
107     notificationParams.message = "DLS " ~ latestVersion.toString() ~ " built";
108     Server.send("window/showMessage", notificationParams);
109 }