blob: d25c51d9b6e0c0592476d37d67bb9a7506a571ca [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#
8# 1. Tcl 8.4 and later are supported, earlier versions have not been tested.
9#
10# 2. The "sqlite-UWP-output.vsix" file is assumed to exist in the parent
11# directory of the directory containing this script. The [optional] first
12# command line argument to this script may be used to specify an alternate
13# file. However, currently, the file must be compatible with both Visual
14# Studio 2015 and the Universal Windows Platform.
15#
mistachkinc32db462016-02-25 02:49:58 +000016# 3. The "VERSION" file is assumed to exist in the parent directory of the
17# directory containing this script. It must contain a version number that
18# matches the VSIX file being tested.
19#
20# 4. The temporary directory specified in the TEMP or TMP environment variables
mistachkin7aa3ebe2016-02-24 21:42:03 +000021# must refer to an existing directory writable by the current user.
22#
mistachkinc32db462016-02-25 02:49:58 +000023# 5. The VS140COMNTOOLS environment variable must refer to the Visual Studio
mistachkin7aa3ebe2016-02-24 21:42:03 +000024# 2015 common tools directory.
25#
26# USAGE
27#
28# The first argument to this script is optional. If specified, it must be the
29# name of the VSIX file to test.
30#
31package require Tcl 8.4
32
33proc fail { {error ""} {usage false} } {
34 if {[string length $error] > 0} then {
35 puts stdout $error
36 if {!$usage} then {exit 1}
37 }
38
39 puts stdout "usage:\
40[file tail [info nameofexecutable]]\
41[file tail [info script]] \[vsixFile\]"
42
43 exit 1
44}
45
46proc getEnvironmentVariable { name } {
47 #
48 # NOTE: Returns the value of the specified environment variable or an empty
49 # string for environment variables that do not exist in the current
50 # process environment.
51 #
52 return [expr {[info exists ::env($name)] ? $::env($name) : ""}]
53}
54
55proc getTemporaryPath {} {
56 #
57 # NOTE: Returns the normalized path to the first temporary directory found
58 # in the typical set of environment variables used for that purpose
59 # or an empty string to signal a failure to locate such a directory.
60 #
61 set names [list]
62
63 foreach name [list TEMP TMP] {
64 lappend names [string toupper $name] [string tolower $name] \
65 [string totitle $name]
66 }
67
68 foreach name $names {
69 set value [getEnvironmentVariable $name]
70
71 if {[string length $value] > 0} then {
72 return [file normalize $value]
73 }
74 }
75
76 return ""
77}
78
79proc appendArgs { args } {
80 #
81 # NOTE: Returns all passed arguments joined together as a single string with
82 # no intervening spaces between arguments.
83 #
84 eval append result $args
85}
86
mistachkinc32db462016-02-25 02:49:58 +000087proc readFile { fileName } {
88 #
89 # NOTE: Reads and returns the entire contents of the specified file, which
90 # may contain binary data.
91 #
92 set file_id [open $fileName RDONLY]
93 fconfigure $file_id -encoding binary -translation binary
94 set result [read $file_id]
95 close $file_id
96 return $result
97}
98
99proc writeFile { fileName data } {
100 #
101 # NOTE: Writes the entire contents of the specified file, which may contain
102 # binary data.
103 #
104 set file_id [open $fileName {WRONLY CREAT TRUNC}]
105 fconfigure $file_id -encoding binary -translation binary
106 puts -nonewline $file_id $data
107 close $file_id
108 return ""
109}
110
111proc putsAndEval { command } {
112 catch {puts stdout $command}
113 return [uplevel 1 $command]
114}
115
mistachkin7aa3ebe2016-02-24 21:42:03 +0000116#
117# NOTE: This is the entry point for this script.
118#
119set script [file normalize [info script]]
120
121if {[string length $script] == 0} then {
122 fail "script file currently being evaluated is unknown" true
123}
124
125set path [file dirname $script]
126
127###############################################################################
128
129#
130# NOTE: Process and verify all the command line arguments.
131#
132set argc [llength $argv]
133if {$argc > 1} then {fail}
134
135if {$argc == 1} then {
mistachkinc32db462016-02-25 02:49:58 +0000136 set vsixFileName [lindex $argv 0]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000137} else {
mistachkinc32db462016-02-25 02:49:58 +0000138 set vsixFileName [file join [file dirname $path] sqlite-UWP-output.vsix]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000139}
140
mistachkinc32db462016-02-25 02:49:58 +0000141if {[string length $vsixFileName] == 0} then {
mistachkin7aa3ebe2016-02-24 21:42:03 +0000142 fail "invalid VSIX file name"
143}
144
mistachkinc32db462016-02-25 02:49:58 +0000145if {![file exists $vsixFileName] || ![file isfile $vsixFileName]} then {
146 fail [appendArgs "VSIX file \"" $vsixFileName "\" does not exist"]
147}
148
149set versionFileName [file join [file dirname $path] VERSION]
150
151if {![file exists $versionFileName] || ![file isfile $versionFileName]} then {
152 fail [appendArgs "Version file \"" $versionFileName "\" does not exist"]
153}
154
155set projectTemplateFileName [file join $path vsixtest.vcxproj.data]
156set projectFileName [file join $path vsixtest.vcxproj]
157
158if {![file exists $projectTemplateFileName] || \
159 ![file isfile $projectTemplateFileName]} then {
160 fail [appendArgs \
161 "Project template file \"" $projectTemplateFileName "\" does not exist"]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000162}
163
164set envVarName VS140COMNTOOLS
165set vsDirectory [getEnvironmentVariable $envVarName]
166
167if {[string length $vsDirectory] == 0} then {
168 fail [appendArgs \
169 "Visual Studio 2015 environment variable \"" $envVarName "\" missing"]
170}
171
172if {![file exists $vsDirectory] || ![file isdirectory $vsDirectory]} then {
173 fail [appendArgs \
174 "Visual Studio 2015 directory \"" $vsDirectory \
175 "\" does not exist"]
176}
177
178set vsixInstaller [file join [file dirname $vsDirectory] IDE VSIXInstaller.exe]
179
180if {![file exists $vsixInstaller] || ![file isfile $vsixInstaller]} then {
181 fail [appendArgs \
182 "Visual Studio 2015 VSIX installer \"" $vsixInstaller \
183 "\" does not exist"]
184}
185
186set envVarName ProgramFiles
187set programFiles [getEnvironmentVariable $envVarName]
188
189if {[string length $programFiles] == 0} then {
190 fail [appendArgs \
191 "Windows environment variable \"" $envVarName "\" missing"]
192}
193
194if {![file exists $programFiles] || ![file isdirectory $programFiles]} then {
195 fail [appendArgs \
196 "Program Files directory \"" $programFiles "\" does not exist"]
197}
198
199set msBuild [file join $programFiles MSBuild 14.0 Bin MSBuild.exe]
200
201if {![file exists $msBuild] || ![file isfile $msBuild]} then {
202 fail [appendArgs \
203 "MSBuild 14.0 executable file \"" $msBuild "\" does not exist"]
204}
205
206set temporaryDirectory [getTemporaryPath]
207
208if {[string length $temporaryDirectory] == 0 || \
209 ![file exists $temporaryDirectory] || \
210 ![file isdirectory $temporaryDirectory]} then {
211 fail "cannot locate a usable temporary directory"
212}
213
214set installLogFileName [appendArgs \
mistachkinc32db462016-02-25 02:49:58 +0000215 [file rootname [file tail $vsixFileName]] -install- [pid] .log]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000216
217set buildLogFileName [appendArgs \
mistachkinc32db462016-02-25 02:49:58 +0000218 [file rootname [file tail $vsixFileName]] \
mistachkin78007b22016-02-24 23:25:23 +0000219 -build-%configuration%-%platform%- [pid] .log]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000220
221set uninstallLogFileName [appendArgs \
mistachkinc32db462016-02-25 02:49:58 +0000222 [file rootname [file tail $vsixFileName]] -uninstall- [pid] .log]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000223
mistachkin78007b22016-02-24 23:25:23 +0000224set commands(1) [list exec [file nativename $vsixInstaller] /quiet /norepair]
225lappend commands(1) [appendArgs /logFile: $installLogFileName]
mistachkinc32db462016-02-25 02:49:58 +0000226lappend commands(1) [file nativename $vsixFileName]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000227
mistachkin78007b22016-02-24 23:25:23 +0000228set commands(2) [list exec [file nativename $msBuild]]
229lappend commands(2) [file nativename [file join $path vsixtest.sln]]
230lappend commands(2) /target:Rebuild
231lappend commands(2) /property:Configuration=%configuration%
mistachkin5dad68d2016-02-24 23:31:14 +0000232lappend commands(2) /property:Platform=%platform%
mistachkin7aa3ebe2016-02-24 21:42:03 +0000233
mistachkin78007b22016-02-24 23:25:23 +0000234lappend commands(2) [appendArgs \
mistachkin7aa3ebe2016-02-24 21:42:03 +0000235 /logger:FileLogger,Microsoft.Build.Engine\;Logfile= \
236 [file nativename [file join $temporaryDirectory $buildLogFileName]] \
237 \;Verbosity=diagnostic]
238
mistachkin78007b22016-02-24 23:25:23 +0000239set commands(3) [list exec [file nativename $vsixInstaller] /quiet /norepair]
240lappend commands(3) [appendArgs /logFile: $uninstallLogFileName]
241lappend commands(3) [appendArgs /uninstall:SQLite.UWP.2015]
mistachkin7aa3ebe2016-02-24 21:42:03 +0000242
mistachkinc32db462016-02-25 02:49:58 +0000243###############################################################################
mistachkin7aa3ebe2016-02-24 21:42:03 +0000244
mistachkin5dad68d2016-02-24 23:31:14 +0000245if {1} then {
mistachkinc32db462016-02-25 02:49:58 +0000246 puts stdout [appendArgs \
247 "Install log will be \"" [file nativename [file join \
248 $temporaryDirectory $installLogFileName]] "\"."]
mistachkin78007b22016-02-24 23:25:23 +0000249
mistachkinc32db462016-02-25 02:49:58 +0000250 puts stdout [appendArgs \
251 "Build log will be \"" [file nativename [file join \
252 $temporaryDirectory $buildLogFileName]] "\"."]
253
254 puts stdout [appendArgs \
255 "Uninstall log will be \"" [file nativename [file join \
256 $temporaryDirectory $uninstallLogFileName]] "\"."]
257}
258
259###############################################################################
260
261if {1} then {
262 # putsAndEval $commands(1)
263
264 set versionNumber [string trim [readFile $versionFileName]]
265 set data [readFile $projectTemplateFileName]
266 set data [string map [list %versionNumber% $versionNumber] $data]
267 writeFile $projectFileName $data
268
269 set platforms [list x86 x64 ARM]
mistachkin78007b22016-02-24 23:25:23 +0000270 set configurations [list Debug Release]
271
272 foreach platform $platforms {
273 foreach configuration $configurations {
mistachkinc32db462016-02-25 02:49:58 +0000274 putsAndEval [string map [list \
mistachkin78007b22016-02-24 23:25:23 +0000275 %platform% $platform %configuration% \
276 $configuration] $commands(2)]
277 }
278 }
279
mistachkinc32db462016-02-25 02:49:58 +0000280 # putsAndEval $commands(3)
mistachkin78007b22016-02-24 23:25:23 +0000281}