blob: 7c30e579cf12aedaaf04d6239370a0760657af97 [file] [log] [blame]
mistachkin7aa3ebe2016-02-24 21:42:03 +00001#!/usr/bin/tclsh
2#
3# This script is used to quickly test a VSIX (Visual Studio Extension) file
4# with Visual Studio 2015 on Windows.
5#
6# PREREQUISITES
7#
mistachkin6ae4d842016-02-25 02:56:53 +00008# 1. This tool must be executed with "elevated administrator" privileges.
mistachkin7aa3ebe2016-02-24 21:42:03 +00009#
mistachkin6ae4d842016-02-25 02:56:53 +000010# 2. Tcl 8.4 and later are supported, earlier versions have not been tested.
11#
12# 3. The "sqlite-UWP-output.vsix" file is assumed to exist in the parent
mistachkin7aa3ebe2016-02-24 21:42:03 +000013# directory of the directory containing this script. The [optional] first
14# command line argument to this script may be used to specify an alternate
15# file. However, currently, the file must be compatible with both Visual
16# Studio 2015 and the Universal Windows Platform.
17#
mistachkin6ae4d842016-02-25 02:56:53 +000018# 4. The "VERSION" file is assumed to exist in the parent directory of the
mistachkinc32db462016-02-25 02:49:58 +000019# directory containing this script. It must contain a version number that
20# matches the VSIX file being tested.
21#
mistachkin6ae4d842016-02-25 02:56:53 +000022# 5. The temporary directory specified in the TEMP or TMP environment variables
mistachkin7aa3ebe2016-02-24 21:42:03 +000023# must refer to an existing directory writable by the current user.
24#
mistachkin6ae4d842016-02-25 02:56:53 +000025# 6. The VS140COMNTOOLS environment variable must refer to the Visual Studio
mistachkin7aa3ebe2016-02-24 21:42:03 +000026# 2015 common tools directory.
27#
28# USAGE
29#
30# The first argument to this script is optional. If specified, it must be the
31# name of the VSIX file to test.
32#
33package require Tcl 8.4
34
35proc fail { {error ""} {usage false} } {
36 if {[string length $error] > 0} then {
37 puts stdout $error
38 if {!$usage} then {exit 1}
39 }
40
41 puts stdout "usage:\
42[file tail [info nameofexecutable]]\
43[file tail [info script]] \[vsixFile\]"
44
45 exit 1
46}
47
48proc getEnvironmentVariable { name } {
49 #
50 # NOTE: Returns the value of the specified environment variable or an empty
51 # string for environment variables that do not exist in the current
52 # process environment.
53 #
54 return [expr {[info exists ::env($name)] ? $::env($name) : ""}]
55}
56
57proc getTemporaryPath {} {
58 #
59 # NOTE: Returns the normalized path to the first temporary directory found
60 # in the typical set of environment variables used for that purpose
61 # or an empty string to signal a failure to locate such a directory.
62 #
63 set names [list]
64
65 foreach name [list TEMP TMP] {
66 lappend names [string toupper $name] [string tolower $name] \
67 [string totitle $name]
68 }
69
70 foreach name $names {
71 set value [getEnvironmentVariable $name]
72
73 if {[string length $value] > 0} then {
74 return [file normalize $value]
75 }
76 }
77
78 return ""
79}
80
81proc appendArgs { args } {
82 #
83 # NOTE: Returns all passed arguments joined together as a single string with
84 # no intervening spaces between arguments.
85 #
86 eval append result $args
87}
88
mistachkinc32db462016-02-25 02:49:58 +000089proc readFile { fileName } {
90 #
91 # NOTE: Reads and returns the entire contents of the specified file, which
92 # may contain binary data.
93 #
94 set file_id [open $fileName RDONLY]
95 fconfigure $file_id -encoding binary -translation binary
96 set result [read $file_id]
97 close $file_id
98 return $result
99}
100
101proc writeFile { fileName data } {
102 #
103 # NOTE: Writes the entire contents of the specified file, which may contain
104 # binary data.
105 #
106 set file_id [open $fileName {WRONLY CREAT TRUNC}]
107 fconfigure $file_id -encoding binary -translation binary
108 puts -nonewline $file_id $data
109 close $file_id
110 return ""
111}
112
113proc putsAndEval { command } {
114 catch {puts stdout $command}
115 return [uplevel 1 $command]
116}
117
mistachkin7aa3ebe2016-02-24 21:42:03 +0000118#
119# NOTE: This is the entry point for this script.
120#
121set script [file normalize [info script]]
122
123if {[string length $script] == 0} then {
124 fail "script file currently being evaluated is unknown" true
125}
126
127set path [file dirname $script]
128
129###############################################################################
130
131#
132# NOTE: Process and verify all the command line arguments.
133#
134set argc [llength $argv]
135if {$argc > 1} then {fail}
136
137if {$argc == 1} then {
mistachkinc32db462016-02-25 02:49:58 +0000138 set vsixFileName [lindex $argv 0]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000139} else {
mistachkinc32db462016-02-25 02:49:58 +0000140 set vsixFileName [file join [file dirname $path] sqlite-UWP-output.vsix]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000141}
142
mistachkinc32db462016-02-25 02:49:58 +0000143if {[string length $vsixFileName] == 0} then {
mistachkin7aa3ebe2016-02-24 21:42:03 +0000144 fail "invalid VSIX file name"
145}
146
mistachkinc32db462016-02-25 02:49:58 +0000147if {![file exists $vsixFileName] || ![file isfile $vsixFileName]} then {
148 fail [appendArgs "VSIX file \"" $vsixFileName "\" does not exist"]
149}
150
151set versionFileName [file join [file dirname $path] VERSION]
152
153if {![file exists $versionFileName] || ![file isfile $versionFileName]} then {
154 fail [appendArgs "Version file \"" $versionFileName "\" does not exist"]
155}
156
157set projectTemplateFileName [file join $path vsixtest.vcxproj.data]
158set projectFileName [file join $path vsixtest.vcxproj]
159
160if {![file exists $projectTemplateFileName] || \
161 ![file isfile $projectTemplateFileName]} then {
162 fail [appendArgs \
163 "Project template file \"" $projectTemplateFileName "\" does not exist"]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000164}
165
166set envVarName VS140COMNTOOLS
167set vsDirectory [getEnvironmentVariable $envVarName]
168
169if {[string length $vsDirectory] == 0} then {
170 fail [appendArgs \
171 "Visual Studio 2015 environment variable \"" $envVarName "\" missing"]
172}
173
174if {![file exists $vsDirectory] || ![file isdirectory $vsDirectory]} then {
175 fail [appendArgs \
176 "Visual Studio 2015 directory \"" $vsDirectory \
177 "\" does not exist"]
178}
179
180set vsixInstaller [file join [file dirname $vsDirectory] IDE VSIXInstaller.exe]
181
182if {![file exists $vsixInstaller] || ![file isfile $vsixInstaller]} then {
183 fail [appendArgs \
184 "Visual Studio 2015 VSIX installer \"" $vsixInstaller \
185 "\" does not exist"]
186}
187
188set envVarName ProgramFiles
189set programFiles [getEnvironmentVariable $envVarName]
190
191if {[string length $programFiles] == 0} then {
192 fail [appendArgs \
193 "Windows environment variable \"" $envVarName "\" missing"]
194}
195
196if {![file exists $programFiles] || ![file isdirectory $programFiles]} then {
197 fail [appendArgs \
198 "Program Files directory \"" $programFiles "\" does not exist"]
199}
200
201set msBuild [file join $programFiles MSBuild 14.0 Bin MSBuild.exe]
202
203if {![file exists $msBuild] || ![file isfile $msBuild]} then {
204 fail [appendArgs \
205 "MSBuild 14.0 executable file \"" $msBuild "\" does not exist"]
206}
207
208set temporaryDirectory [getTemporaryPath]
209
210if {[string length $temporaryDirectory] == 0 || \
211 ![file exists $temporaryDirectory] || \
212 ![file isdirectory $temporaryDirectory]} then {
213 fail "cannot locate a usable temporary directory"
214}
215
216set installLogFileName [appendArgs \
mistachkinc32db462016-02-25 02:49:58 +0000217 [file rootname [file tail $vsixFileName]] -install- [pid] .log]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000218
219set buildLogFileName [appendArgs \
mistachkinc32db462016-02-25 02:49:58 +0000220 [file rootname [file tail $vsixFileName]] \
mistachkin78007b22016-02-24 23:25:23 +0000221 -build-%configuration%-%platform%- [pid] .log]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000222
223set uninstallLogFileName [appendArgs \
mistachkinc32db462016-02-25 02:49:58 +0000224 [file rootname [file tail $vsixFileName]] -uninstall- [pid] .log]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000225
mistachkin78007b22016-02-24 23:25:23 +0000226set commands(1) [list exec [file nativename $vsixInstaller] /quiet /norepair]
227lappend commands(1) [appendArgs /logFile: $installLogFileName]
mistachkinc32db462016-02-25 02:49:58 +0000228lappend commands(1) [file nativename $vsixFileName]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000229
mistachkin78007b22016-02-24 23:25:23 +0000230set commands(2) [list exec [file nativename $msBuild]]
231lappend commands(2) [file nativename [file join $path vsixtest.sln]]
232lappend commands(2) /target:Rebuild
233lappend commands(2) /property:Configuration=%configuration%
mistachkin5dad68d2016-02-24 23:31:14 +0000234lappend commands(2) /property:Platform=%platform%
mistachkin7aa3ebe2016-02-24 21:42:03 +0000235
mistachkin78007b22016-02-24 23:25:23 +0000236lappend commands(2) [appendArgs \
mistachkin7aa3ebe2016-02-24 21:42:03 +0000237 /logger:FileLogger,Microsoft.Build.Engine\;Logfile= \
238 [file nativename [file join $temporaryDirectory $buildLogFileName]] \
239 \;Verbosity=diagnostic]
240
mistachkin78007b22016-02-24 23:25:23 +0000241set commands(3) [list exec [file nativename $vsixInstaller] /quiet /norepair]
242lappend commands(3) [appendArgs /logFile: $uninstallLogFileName]
243lappend commands(3) [appendArgs /uninstall:SQLite.UWP.2015]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000244
mistachkinc32db462016-02-25 02:49:58 +0000245###############################################################################
mistachkin7aa3ebe2016-02-24 21:42:03 +0000246
mistachkin5dad68d2016-02-24 23:31:14 +0000247if {1} then {
mistachkinc32db462016-02-25 02:49:58 +0000248 puts stdout [appendArgs \
249 "Install log will be \"" [file nativename [file join \
250 $temporaryDirectory $installLogFileName]] "\"."]
mistachkin78007b22016-02-24 23:25:23 +0000251
mistachkinc32db462016-02-25 02:49:58 +0000252 puts stdout [appendArgs \
253 "Build log will be \"" [file nativename [file join \
254 $temporaryDirectory $buildLogFileName]] "\"."]
255
256 puts stdout [appendArgs \
257 "Uninstall log will be \"" [file nativename [file join \
258 $temporaryDirectory $uninstallLogFileName]] "\"."]
259}
260
261###############################################################################
262
263if {1} then {
mistachkin6ae4d842016-02-25 02:56:53 +0000264 putsAndEval $commands(1)
mistachkinc32db462016-02-25 02:49:58 +0000265
266 set versionNumber [string trim [readFile $versionFileName]]
267 set data [readFile $projectTemplateFileName]
268 set data [string map [list %versionNumber% $versionNumber] $data]
269 writeFile $projectFileName $data
270
271 set platforms [list x86 x64 ARM]
mistachkin78007b22016-02-24 23:25:23 +0000272 set configurations [list Debug Release]
273
274 foreach platform $platforms {
275 foreach configuration $configurations {
mistachkinc32db462016-02-25 02:49:58 +0000276 putsAndEval [string map [list \
mistachkin78007b22016-02-24 23:25:23 +0000277 %platform% $platform %configuration% \
278 $configuration] $commands(2)]
279 }
280 }
281
mistachkin6ae4d842016-02-25 02:56:53 +0000282 putsAndEval $commands(3)
mistachkin78007b22016-02-24 23:25:23 +0000283}