1 /**
2  * Copyright: Copyright (c) 2011 Jacob Carlborg. All rights reserved.
3  * Authors: Jacob Carlborg
4  * Version: Initial created: Jan 19, 2011
5  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
6  */
7 module dvm.commands.DvmInstall;
8 
9 import std.file : thisExePath;
10 
11 import tango.io.device.File;
12 import tango.sys.HomeFolder;
13 import tango.text.Util;
14 
15 import mambo.core._;
16 import Path = dvm.io.Path;
17 import dvm.commands.Command;
18 import dvm.dvm.Exceptions;
19 import dvm.dvm.ShellScript;
20 import dvm.util.Util;
21 version (Windows) import DvmRegistry = dvm.util.DvmRegistry;
22 version (Windows) import dvm.util.Windows;
23 
24 class DvmInstall : Command
25 {
26     private
27     {
28         enum postInstallInstructions = import("post_install_instructions.txt");
29         enum failedInstallInstructions = import("failed_install_instructions.txt");
30 
31         version (Posix)
32             enum dvmScript = import("dvm.sh");
33 
34         else
35             enum dvmScript = import("dvm.bat");
36     }
37 
38     override void execute ()
39     {
40         install;
41     }
42 
43 private:
44 
45     void install ()
46     {
47         if (Path.exists(options.path.dvm))
48             return update;
49 
50         verbose("Installing dvm to: ", options.path.dvm);
51         createPaths;
52         copyExecutable;
53         writeScript;
54 
55         version (Posix)
56         {
57             setPermissions;
58             installBashInclude(createBashInclude);
59         }
60 
61         version (Windows)
62             setupRegistry;
63     }
64 
65     void update ()
66     {
67         createPaths;
68         copyExecutable;
69         writeScript;
70         setPermissions;
71 
72         version (Windows)
73             setupRegistry;
74     }
75 
76     void createPaths ()
77     {
78         verbose("Creating paths:");
79 
80         createPath(options.path.dvm);
81         createPath(options.path.archives);
82         createPath(Path.join(options.path.dvm, options.path.bin).assumeUnique);
83         createPath(options.path.compilers);
84         createPath(options.path.env);
85         createPath(options.path.scripts);
86 
87         verbose();
88     }
89 
90     void copyExecutable ()
91     {
92         verbose("Copying executable:");
93         verbose("thisExePath: ", thisExePath);
94         copy(thisExePath, options.path.dvmExecutable);
95     }
96 
97     void writeScript ()
98     {
99         verbose("Writing script to: ", options.path.dvmScript);
100         File.set(options.path.dvmScript, dvmScript);
101     }
102 
103     void setPermissions ()
104     {
105         verbose("Setting permissions:");
106         permission(options.path.dvmScript, "+x");
107         permission(options.path.dvmExecutable, "+x");
108     }
109 
110     version (Posix)
111         void installBashInclude (ShellScript sh)
112         {
113             auto home = homeFolder.assumeUnique;
114             auto bashrc = Path.join(home, ".bashrc");
115             auto bash_profile = Path.join(home, ".bash_profile");
116             string shPath;
117 
118             if (Path.exists(bashrc))
119                 shPath = bashrc;
120 
121             else if (Path.exists(bash_profile))
122                 shPath = bash_profile;
123 
124             else
125                 throw new DvmException(format(`Cannot find "{}" or "{}". Please perform the post installation manually by following the instructions below:{}{}`,
126                                                 bashrc, bash_profile, "\n\n", failedInstallInstructions), __FILE__, __LINE__);
127 
128             verbose("Installing dvm in the shell loading file: ", shPath);
129             File.append(shPath, sh.content);
130 
131             println(postInstallInstructions);
132         }
133 
134     void createPath (string path)
135     {
136         verbose(options.indentation, path);
137         if(!Path.exists(path))
138             Path.createFolder(path);
139     }
140 
141     void permission (string path, string mode)
142     {
143         version (Posix)
144         {
145             verbose(options.indentation, "mode: " ~ mode);
146             verbose(options.indentation, "file: " ~ path, '\n');
147 
148             Path.permission(path, mode);
149         }
150     }
151 
152     void copy (string source, string destination)
153     {
154         verbose(options.indentation, "source: ", source);
155         verbose(options.indentation, "destination: ", destination, '\n');
156 
157         Path.copy(source, destination);
158     }
159 
160     ShellScript createBashInclude ()
161     {
162         auto sh = new ShellScript;
163         sh.nl.nl;
164         sh.comment("This loads DVM into a shell session.").nl;
165 
166         sh.ifFileIsNotEmpty(options.path.dvmScript, {
167             sh.source(options.path.dvmScript);
168         });
169 
170         return sh;
171     }
172 
173     version (Windows)
174         void setupRegistry ()
175         {
176             auto defaultCompilerPath = DvmRegistry.getDefaultCompilerPath();
177             DvmRegistry.updateEnvironment(options.path.binDir, defaultCompilerPath);
178             DvmRegistry.checkSystemPath();
179             broadcastSettingChange("Environment");
180             println("DVM has now been installed.");
181             println("To use dvm, you may need to open a new command prompt.");
182         }
183 }