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 }