1 /**
2  * GnuWin32 installer
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <ae@cy.md>
12  */
13 
14 module ae.sys.install.gnuwin32;
15 
16 import std.file;
17 import std.path;
18 import std..string : format, split;
19 
20 import ae.utils.meta : singleton, I;
21 
22 public import ae.sys.install.common;
23 
24 /// Installs a GnuWin32 component.
25 final class GnuWin32Component : Installer
26 {
27 	/// Template for component .zip files.
28 	string urlTemplate = "http://gnuwin32.sourceforge.net/downlinks/%s-%s-zip.php";
29 
30 	/// Component to install.
31 	string componentName;
32 
33 	this(string componentName) { this.componentName = componentName; } ///
34 	@property override string name() { return "%s (GnuWin32)".format(componentName); }
35 	@property override string subdirectory() { return "gnuwin32"; }
36 	@property override string[] binPaths() { return ["bin"]; }
37 
38 	override @property bool installedLocally()
39 	{
40 		auto manifestDir = directory.buildPath("manifest");
41 		return manifestDir.exists && !manifestDir.dirEntries(componentName ~ "-*-bin.ver", SpanMode.shallow).empty;
42 	}
43 
44 	override void atomicInstallImpl()
45 	{
46 		windowsOnly();
47 		if (!directory.exists)
48 			directory.mkdir();
49 		installUrl(urlTemplate.format(componentName, "bin"));
50 		installUrl(urlTemplate.format(componentName, "dep"));
51 		assert(installedLocally);
52 	}
53 
54 	void installUrl(string url)
55 	{
56 		url
57 			.I!saveAs(url.split("/")[$-1][0..$-8] ~ ".zip")
58 			.I!unpack()
59 			.atomicMoveInto(directory);
60 	}
61 }
62 
63 /// `opDispatch` constructor for GnuWin32 component installers.
64 struct GnuWin32
65 {
66 	/// Example: `GnuWin32.make.requireLocal(false);`.
67 	static GnuWin32Component opDispatch(string name)()
68 	{
69 		alias component = singleton!(GnuWin32Component, name);
70 		return component;
71 	}
72 }