1 /**
2  * Copyright: Copyright (c) 2010-2011 Jacob Carlborg. All rights reserved.
3  * Authors: Jacob Carlborg
4  * Version: Initial created: Nov 8, 2010
5  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
6  */
7 module dvm.commands.Use;
8 
9 import std.exception : assumeUnique;
10 import std.format : format;
11 
12 import dvm.util.Util;
13 import tango.core.Exception;
14 
15 import dvm.dvm.Options;
16 import dvm.dvm.ShellScript;
17 import dvm.dvm.Wrapper;
18 import dvm.commands.Command;
19 import dvm.io.Path;
20 version (Windows) import DvmRegistry = dvm.util.DvmRegistry;
21 version (Windows) import dvm.util.Windows;
22 
23 class Use : Command
24 {
25     private
26     {
27         string envPath_;
28         Wrapper wrapper;
29     }
30 
31     this ()
32     {
33         super("use", "Setup current shell to use a specific D compiler version.");
34     }
35 
36     override void execute ()
37     {
38         loadEnvironment;
39         installWrapper;
40 
41         version (Posix)
42             setPermissions;
43 
44         version (Windows)
45             updateRegistry;
46     }
47 
48 private:
49 
50     void loadEnvironment ()
51     {
52         auto shellScript = createShellScript;
53 
54         auto current = options.isDefault ? "default" : "current";
55         verbose(format(`Installing "%s" as the %s D compiler`, args.first, current));
56 
57         writeShellScript(shellScript, options.path.result);
58 
59         version (Posix)
60             if (options.isDefault)
61             {
62                 verbose("Installing environment: ", options.path.defaultEnv);
63                 copy(options.path.result, options.path.defaultEnv);
64             }
65     }
66 
67     void installWrapper ()
68     {
69         wrapper.target = wrapperTarget(args.first);
70         wrapper.path = join(options.path.dvm, options.path.bin, "dvm-current-dc" ~ options.path.scriptExtension).assumeUnique;
71 
72         verbose("Installing wrapper: " ~ wrapper.path);
73 
74         if (exists(wrapper.path))
75             dvm.io.Path.remove(wrapper.path);
76 
77         wrapper.write;
78 
79         if (options.isDefault)
80         {
81             verbose("Installing wrapper: ", options.path.defaultBin);
82             copy(wrapper.path, options.path.defaultBin);
83         }
84     }
85 
86     version (Windows)
87         void updateRegistry ()
88         {
89             if (options.isDefault)
90             {
91                 auto dmdDir = join(options.path.compilers, "dmd-" ~ args.first, options.platform, options.path.bin);
92                 DvmRegistry.updateEnvironment(options.path.binDir, dmdDir);
93 
94                 DvmRegistry.checkSystemPath();
95 
96                 broadcastSettingChange("Environment");
97             }
98         }
99 
100     version (Posix)
101         void setPermissions ()
102         {
103             verbose("Setting permissions:");
104 
105             setPermission(wrapper.path, "+x");
106 
107             if (options.isDefault)
108                 setPermission(options.path.defaultBin, "+x");
109         }
110 
111     version (Posix)
112         void setPermission (string path, string mode)
113         {
114             verbose(options.indentation, "mode: ", mode);
115             verbose(options.indentation, "file: ", path);
116 
117             permission(path, mode);
118         }
119 
120     ShellScript createShellScript ()
121     {
122         verbose("Creating shell script");
123         auto sh = new ShellScript;
124         sh.echoOff;
125         sh.source(Sh.quote(envPath));
126 
127         return sh;
128     }
129 
130     void writeShellScript (ShellScript sh, string path)
131     {
132         validatePath(envPath);
133         sh.path = path;
134 
135         if (!exists(options.path.tmp))
136             createFolder(options.path.tmp);
137 
138         sh.write;
139     }
140 
141     string envPath ()
142     {
143         if (envPath_.length > 0)
144             return envPath_;
145 
146         return envPath_ = native(join(options.path.env, "dmd-" ~ args.first ~ options.path.scriptExtension)).assumeUnique;
147     }
148 
149     string wrapperTarget (string compilerVersion)
150     {
151         auto basePath = join(options.path.compilers, "dmd-" ~ compilerVersion);
152         auto executable = "dmd" ~ options.path.executableExtension;
153         auto path = join(basePath, options.platform, options.path.bin, executable);
154 
155         return exists(path) ? path : join(basePath, options.path.bin, executable);
156     }
157 }
158 
159 template UseImpl ()
160 {
161 
162 
163 
164 }