PageRenderTime 42ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/rake-tasks/crazy_fun/mappings/visualstudio.rb

https://bitbucket.org/abahdanovich/selenium
Ruby | 734 lines | 626 code | 88 blank | 20 comment | 46 complexity | 3b4537983469b3dc4df563f3e594ba23 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, AGPL-1.0, MIT, Apache-2.0, BSD-3-Clause, GPL-2.0
  1. require 'iconv'
  2. require 'albacore'
  3. require 'rake-tasks/crazy_fun/mappings/common'
  4. require 'rake-tasks/checks'
  5. # Monkey patch NUnitTestRunner.execute so as not to fail the build
  6. # when encountering a test failure and to redirect output from NUnit.
  7. class NUnitTestRunner
  8. attr_accessor :output_redirect, :ignore_test_fail
  9. def execute
  10. command_params = get_command_parameters().join(" ")
  11. unless output_redirect.nil?
  12. command_params = command_params + " > " + @output_redirect
  13. end
  14. result = run_command "NUnit", command_params
  15. failure_message = 'NUnit Failed. See Build Log For Detail'
  16. fail_with_message failure_message if !result and !@ignore_test_fail
  17. end
  18. end
  19. # Monkey patch NuGetPack.execute to pass correct command line options.
  20. # This patch can be removed when Albacore issue is fixed.
  21. class NuGetPack
  22. def execute
  23. fail_with_message 'nuspec must be specified.' if @nuspec.nil?
  24. params = []
  25. params << "pack"
  26. params << "#{nuspec}"
  27. params << "-BasePath #{base_folder}" unless @base_folder.nil?
  28. params << "-OutputDirectory #{output}" unless @output.nil?
  29. merged_params = params.join(' ')
  30. @logger.debug "Build NuGet pack Command Line: #{merged_params}"
  31. result = run_command "NuGet", merged_params
  32. failure_message = 'NuGet Failed. See Build Log For Detail'
  33. fail_with_message failure_message if !result
  34. end
  35. end
  36. class VisualStudioMappings
  37. def add_all(fun)
  38. fun.add_mapping("visualc_library", CrazyFunVisualC::VisualCLibrary.new)
  39. fun.add_mapping("visualc_release", CrazyFunVisualC::VisualCLibrary.new)
  40. fun.add_mapping("visualc_release", CrazyFunVisualC::VisualCRelease.new)
  41. fun.add_mapping("dotnet_library", CrazyFunDotNet::DotNetLibrary.new)
  42. fun.add_mapping("dotnet_library", CrazyFunDotNet::CreateShortTaskName.new)
  43. fun.add_mapping("dotnet_library", CrazyFunDotNet::MergeAssemblies.new)
  44. fun.add_mapping("dotnet_package", CrazyFunDotNet::CreateNuSpec.new)
  45. fun.add_mapping("dotnet_package", CrazyFunDotNet::PackNuGetPackage.new)
  46. fun.add_mapping("dotnet_package", CrazyFunDotNet::PublishNuGetPackage.new)
  47. fun.add_mapping("dotnet_docs", CrazyFunDotNet::GenerateDotNetDocs.new)
  48. fun.add_mapping("dotnet_docs", CrazyFunDotNet::MoveDotNetHelpFile.new)
  49. fun.add_mapping("dotnet_test", CrazyFunDotNet::DotNetLibrary.new)
  50. fun.add_mapping("dotnet_test", CrazyFunDotNet::RunDotNetTests.new)
  51. fun.add_mapping("dotnet_release", CrazyFunDotNet::DotNetRelease.new)
  52. end
  53. end
  54. module CrazyFunVisualStudio
  55. class UploadFile < Tasks
  56. def handle(fun, dir, args)
  57. # Empty handle method as this will be a base class for tasks
  58. # requiring upload of their outputs.
  59. end
  60. def upload_file(file_name, file_description, featured_file)
  61. py = "java -jar third_party/py/jython.jar"
  62. if (python?)
  63. py = "python"
  64. end
  65. if ENV["googlecodeusername"].nil?
  66. print "Enter your googlecode username:"
  67. googlecode_username = STDIN.gets.chomp
  68. else
  69. googlecode_username = ENV["googlecodeusername"]
  70. end
  71. if ENV["googlecodepassword"].nil?
  72. print "Enter your googlecode password (NOT your gmail password, the one you use for svn, available at https://code.google.com/hosting/settings):"
  73. googlecode_password = STDIN.gets.chomp
  74. else
  75. googlecode_password = ENV["googlecodepassword"]
  76. end
  77. featured = ""
  78. if featured_file
  79. featured = " -l Featured"
  80. end
  81. puts "Uploading file #{file_name}..."
  82. platform_file_name = file_name.gsub("/", Platform.dir_separator)
  83. command_line = "#{py} third_party/py/googlecode/googlecode_upload.py -s \"#{file_description}\"#{featured} -p selenium #{platform_file_name} -u #{googlecode_username} -w #{googlecode_password}"
  84. sh command_line
  85. end
  86. end
  87. end
  88. module CrazyFunDotNet
  89. class DotNetTasks < Tasks
  90. def get_reference_assemblies_dir()
  91. @reference_assemblies_dir ||= (
  92. program_files_dir = find_environment_variable(['ProgramFiles(x86)', 'programfiles(x86)', 'PROGRAMFILES(X86)'], "C:/Program Files (x86)")
  93. unless File.exists? program_files_dir
  94. program_files_dir = find_environment_variable(['ProgramFiles', 'programfiles', 'PROGRAMFILES'], "C:/Program Files")
  95. end
  96. File.join(program_files_dir, 'Reference Assemblies', 'Microsoft', 'Framework')
  97. )
  98. end
  99. def get_framework_dir()
  100. @framework_dir ||= (
  101. windows_dir = find_environment_variable(['WinDir', 'windir', 'WINDIR'], "C:/Windows")
  102. File.join(windows_dir, 'Microsoft.NET', 'Framework')
  103. )
  104. end
  105. def get_reference_assemblies_version_dir(version)
  106. if version == "net35"
  107. return File.join(get_reference_assemblies_dir(), "v3.5").to_s
  108. end
  109. return File.join(get_reference_assemblies_dir(), '.NETFramework', "v4.0").to_s
  110. end
  111. def resolve_framework_reference(ref, version)
  112. if version == "net35"
  113. assembly = File.join(get_reference_assemblies_version_dir(version), ref)
  114. unless File.exists? assembly
  115. assembly = File.join(get_framework_dir(), "v2.0.50727", ref)
  116. end
  117. return assembly.to_s
  118. end
  119. return File.join(get_reference_assemblies_version_dir(version), ref).to_s
  120. end
  121. def find_environment_variable(possible_vars, fallback)
  122. var_name = possible_vars.find { |e| ENV[e] }
  123. if var_name.nil?
  124. return fallback
  125. end
  126. return ENV[var_name]
  127. end
  128. end
  129. class DotNetLibrary < DotNetTasks
  130. def handle(fun, dir, args)
  131. base_dir = "build/dotnet"
  132. framework_ver = "net40"
  133. unless args[:framework_ver].nil?
  134. framework_ver = args[:framework_ver]
  135. end
  136. output_dir = base_dir
  137. unless args[:merge_refs].nil?
  138. output_dir = File.join(output_dir, "unmerged")
  139. end
  140. output_dir = File.join(output_dir, framework_ver)
  141. full_path = File.join(output_dir, args[:out])
  142. desc_path = full_path.gsub("/", Platform.dir_separator)
  143. desc "Build #{desc_path}"
  144. task_name = task_name(dir, args[:name])
  145. # Default parameters to csc.exe that we will use.
  146. # These should decline as more functionality is added
  147. # to the Albacore csc task.
  148. params = ["/nostdlib+",
  149. "/nologo",
  150. "/noconfig",
  151. "/filealign:512"]
  152. args[:refs].insert(0, "mscorlib.dll")
  153. embedded_resources = []
  154. buildable_references = resolve_buildable_targets(args[:refs])
  155. buildable_resources = resolve_buildable_targets(args[:resources])
  156. target = csc task_name do |csc_task|
  157. puts "Compiling: #{task_name} as #{desc_path}"
  158. FileUtils.mkdir_p output_dir
  159. to_copy = []
  160. references = resolve_references(dir, args[:refs], framework_ver, to_copy)
  161. references << args[:merge_refs] unless args[:merge_refs].nil?
  162. # For each resource key-value pair in the resources Hash, assume
  163. # the key to the hash represents the name of the file to embed
  164. # as a resource. If the key in the Hash is a Task, the name of
  165. # the file to embed should be output of that Task.
  166. unless args[:resources].nil?
  167. args[:resources].each do |resource|
  168. resource_file = resource.keys[0]
  169. resource_identifier = resource.fetch(resource_file)
  170. resource_task_name = task_name(dir, resource_file)
  171. if Rake::Task.task_defined? resource_task_name
  172. resource_file = Rake::Task[resource_task_name].out
  173. end
  174. embedded_resources << "#{resource_file},#{resource_identifier}"
  175. end
  176. end
  177. csc_task.use :net40
  178. csc_task.parameters params
  179. csc_task.compile FileList[[dir, args[:srcs]].join(File::SEPARATOR)]
  180. csc_task.output = full_path
  181. csc_task.target = :library
  182. if args[:omitdocxml].nil?
  183. csc_task.doc = full_path.chomp(File.extname(args[:out])) + ".xml"
  184. end
  185. csc_task.optimize = true
  186. csc_task.debug = :pdbonly
  187. csc_task.references references
  188. csc_task.resources embedded_resources
  189. csc_task.keyfile = args[:keyfile] unless args[:keyfile].nil?
  190. copy_resources(dir, to_copy, output_dir)
  191. unless args[:files].nil?
  192. copy_resources(dir, args[:files], output_dir)
  193. end
  194. end
  195. add_dependencies(target, dir, buildable_references)
  196. add_dependencies(target, dir, buildable_resources)
  197. add_dependencies(target, dir, args[:deps])
  198. target.out = full_path
  199. end
  200. private
  201. def resolve_references(dir, refs, framework_ver, assemblies_to_copy)
  202. references = []
  203. unless refs.nil?
  204. refs.each do |reference|
  205. reference_task_name = task_name(dir, reference)
  206. if Rake::Task.task_defined? reference_task_name
  207. references << Rake::Task[reference_task_name].out
  208. else
  209. if reference.include? "/"
  210. assemblies_to_copy << reference
  211. references << reference
  212. else
  213. references << resolve_framework_reference(reference, framework_ver)
  214. end
  215. end
  216. end
  217. end
  218. return references
  219. end
  220. def resolve_buildable_targets(target_candidates)
  221. buildable_targets = []
  222. unless target_candidates.nil?
  223. target_candidates.each do |target_candidate|
  224. if target_candidate.to_s.start_with? "//" or target_candidate.is_a? Symbol
  225. buildable_targets << target_candidate
  226. end
  227. end
  228. end
  229. return buildable_targets
  230. end
  231. end
  232. class MergeAssemblies < DotNetTasks
  233. def handle(fun, dir, args)
  234. base_dir = "build/dotnet"
  235. framework_ver = "net40"
  236. unless args[:framework_ver].nil?
  237. framework_ver = args[:framework_ver]
  238. end
  239. output_dir = File.join(base_dir, framework_ver)
  240. unmerged_dir = File.join(base_dir, "unmerged")
  241. unmerged_dir = File.join(unmerged_dir, framework_ver)
  242. unmerged_path = File.join(unmerged_dir, args[:out])
  243. full_path = File.join(output_dir, args[:out])
  244. desc_path = full_path.gsub("/", Platform.dir_separator)
  245. desc "Merge #{desc_path}"
  246. task_name = task_name(dir, args[:name])
  247. unless args[:merge_refs].nil?
  248. params = ["/t:library",
  249. "/xmldocs",
  250. "/align:512"]
  251. if framework_ver == "net35"
  252. params << "/v2"
  253. else
  254. mscorlib_location = get_reference_assemblies_version_dir("net40").gsub('/', Platform.dir_separator)
  255. params << "/targetplatform:v4,\"#{mscorlib_location}\""
  256. end
  257. params << "/keyfile:#{args[:keyfile]}" unless args[:keyfile].nil?
  258. params << "/out:#{full_path.gsub('/', Platform.dir_separator)}"
  259. params << unmerged_path.gsub("/", Platform.dir_separator)
  260. args[:merge_refs].each do |assembly|
  261. params << assembly.gsub("/", Platform.dir_separator)
  262. end
  263. target = exec task_name do |cmd|
  264. puts "Merging: #{task_name} as #{desc_path}"
  265. FileUtils.mkdir_p output_dir
  266. if args[:exclude_merge_types].nil?
  267. params << "/internalize"
  268. else
  269. exclude_types_file = File.join(unmerged_dir, "#{args[:out]}.mergeexclude.txt")
  270. f = File.open(exclude_types_file, 'w')
  271. args[:exclude_merge_types].each do |exclude_type|
  272. f.write exclude_type + "\n"
  273. end
  274. f.close
  275. params << "/internalize:#{exclude_types_file.gsub('/', Platform.dir_separator)}"
  276. end
  277. cmd.command = "third_party/dotnet/ilmerge/ILMerge.exe"
  278. cmd.parameters = params.join " "
  279. end
  280. target.out = full_path
  281. end
  282. end
  283. private
  284. def resolve_merge_assemblies(dir, refs)
  285. to_merge = []
  286. unless refs.nil?
  287. refs.each do |reference|
  288. reference_task_name = task_name(dir, reference)
  289. unless Rake::Task.task_defined? reference_task_name
  290. if reference.include? "/"
  291. to_merge << reference
  292. end
  293. end
  294. end
  295. end
  296. return to_merge
  297. end
  298. end
  299. class CreateShortTaskName < Tasks
  300. def handle(fun, dir, args)
  301. name = task_name(dir, args[:name])
  302. if name.end_with? "#{args[:name]}:#{args[:name]}"
  303. name = name.sub(/:.*$/, "")
  304. task name => task_name(dir, args[:name])
  305. end
  306. end
  307. end
  308. class RunDotNetTests < Tasks
  309. def handle(fun, dir, args)
  310. base_output_dir = 'build'
  311. output_dir = base_output_dir + '/dotnet/net40'
  312. test_log_dir = base_output_dir + '/test_logs'
  313. task_name = task_name(dir, args[:name])
  314. desc "Run the tests for #{task_name}"
  315. target = nunit "#{task_name}:run" do |nunit_task|
  316. mkdir_p test_log_dir
  317. puts "Testing: #{task_name}"
  318. nunit_task.command = "third_party/dotnet/nunit-2.6.2/nunit-console.exe"
  319. nunit_task.assemblies << [output_dir, args[:project]].join(File::SEPARATOR)
  320. nunit_task.options << "/nologo"
  321. nunit_task.options << "/nodots"
  322. nunit_task.options << "/xml=#{[test_log_dir, args[:project]].join(File::SEPARATOR)}.xml"
  323. nunit_task.output_redirect = "#{[test_log_dir, args[:project]].join(File::SEPARATOR)}.log"
  324. nunit_task.ignore_test_fail = !([nil, 'true'].include? ENV['haltonfailure'])
  325. end
  326. add_dependencies(target, dir, args[:deps])
  327. add_dependencies(target, dir, ["#{task_name}"])
  328. end
  329. end
  330. class GenerateDotNetDocs < Tasks
  331. def handle(fun, dir, args)
  332. task_name = task_name(dir, args[:name])
  333. desc "Generate documentation for #{task_name}"
  334. web_documentation_path = args[:website]
  335. web_documentation_path_desc = web_documentation_path.gsub("/", Platform.dir_separator)
  336. doc_sources = resolve_doc_sources(dir, args[:srcs])
  337. target_task = msbuild task_name do |msb|
  338. puts "Generating help website: at #{web_documentation_path_desc}"
  339. if ENV['DXROOT'].nil?
  340. fail "Sandcastle documentation tools not found. Documentation will not be created."
  341. end
  342. if ENV['SHFBROOT'].nil?
  343. fail "Sandcastle Help File Builder not found. Documentation will not be created."
  344. end
  345. msb.use :net40
  346. msb.properties = {
  347. "OutputPath" => File.expand_path(web_documentation_path).gsub("/", Platform.dir_separator),
  348. "DocumentationSources" => build_doc_sources_parameter(doc_sources),
  349. "HtmlHelpName" => File.basename(args[:helpfile], File.extname(args[:helpfile])),
  350. "HelpTitle" => File.basename(args[:helpfile], File.extname(args[:helpfile]))
  351. }
  352. msb.targets ["CoreCleanHelp", "CoreBuildHelp"]
  353. msb.solution = File.join(dir, args[:project]).gsub("/", Platform.dir_separator)
  354. msb.parameters "/nologo"
  355. msb.verbosity = "quiet"
  356. end
  357. end
  358. def resolve_doc_sources(dir, doc_source_targets)
  359. doc_sources = []
  360. doc_source_targets.each do |doc_source_target|
  361. doc_source_task_name = task_name(dir, doc_source_target)
  362. if Rake::Task.task_defined? doc_source_task_name
  363. assembly_doc_source = File.expand_path(Rake::Task[doc_source_task_name].out)
  364. xml_doc_source = assembly_doc_source.chomp(File.extname(assembly_doc_source)) + ".xml"
  365. doc_sources << assembly_doc_source
  366. doc_sources << xml_doc_source
  367. end
  368. end
  369. return doc_sources
  370. end
  371. def build_doc_sources_parameter(doc_sources)
  372. doc_sources_parameter = ""
  373. doc_sources.each do |doc_source|
  374. if File.exists? doc_source
  375. doc_sources_parameter << "<DocumentationSource sourceFile='#{doc_source.gsub("/", Platform.dir_separator)}' xmlns='' />"
  376. else
  377. puts "WARNING: Could not find #{doc_source}. Documentation will not include these objects."
  378. end
  379. end
  380. return doc_sources_parameter
  381. end
  382. end
  383. class MoveDotNetHelpFile < Tasks
  384. def handle(fun, dir, args)
  385. task_name = task_name(dir, args[:name])
  386. help_file_path_desc = args[:out].gsub("/", Platform.dir_separator)
  387. web_documentation_path = args[:website]
  388. file task_name do
  389. puts "Generating help file: at #{help_file_path_desc}"
  390. mv File.join(web_documentation_path, args[:helpfile]), File.dirname(args[:out])
  391. File.rename(File.join(web_documentation_path, "Index.html"), File.join(web_documentation_path, "index.html"))
  392. end
  393. end
  394. end
  395. class CreateNuSpec < Tasks
  396. def handle(fun, dir, args)
  397. output_dir = "build/dotnet"
  398. spec_file = "#{output_dir}/nuget/#{args[:packageid]}.nuspec"
  399. task_name = task_name(dir, args[:name])
  400. desc "Creates and optionally publishes the NuGet package for #{args[:out]}"
  401. target = nuspec "#{task_name}" do |nuspec_task|
  402. mkdir_p "#{output_dir}/nuget"
  403. puts "Creating .nuspec for: #{task_name}"
  404. nuspec_task.output_file = spec_file
  405. nuspec_task.id = args[:packageid]
  406. nuspec_task.version = get_version(dir)
  407. nuspec_task.authors = "Selenium Committers"
  408. nuspec_task.description = args[:description]
  409. nuspec_task.owners = "Software Freedom Conservancy"
  410. nuspec_task.title = args[:title] unless args[:title].nil?
  411. nuspec_task.summary = args[:summary] unless args[:summary].nil?
  412. nuspec_task.projectUrl = "http://code.google.com/p/selenium/"
  413. nuspec_task.licenseUrl = "http://www.apache.org/licenses/LICENSE-2.0"
  414. nuspec_task.iconUrl = "http://seleniumhq.org/images/big-logo.png"
  415. nuspec_task.requireLicenseAcceptance = "false"
  416. nuspec_task.tags = args[:tags] unless args[:tags].nil?
  417. args[:deps].each do |dependency|
  418. file_dependency_task = task_name(dir, dependency)
  419. if Rake::Task.task_defined? file_dependency_task
  420. relative_output_file = Rake::Task[file_dependency_task].out.sub(output_dir + "/", "").gsub("/", Platform.dir_separator)
  421. output_subdir = File.dirname(relative_output_file)
  422. dest_dir = "lib"
  423. if output_subdir.length > 0
  424. dest_dir << "/#{output_subdir}"
  425. end
  426. nuspec_task.file relative_output_file, dest_dir
  427. nuspec_task.file relative_output_file.chomp(File.extname(relative_output_file)) + ".xml", dest_dir
  428. end
  429. end
  430. unless args[:packagedeps].nil?
  431. args[:packagedeps].each do |dep|
  432. package_id = dep.keys[0]
  433. package_version = version
  434. package_dependency_task = task_name(dir, package_id)
  435. if Rake::Task.task_defined? package_dependency_task
  436. package_id = Rake::Task[package_dependency_task].out
  437. else
  438. package_version = "#{dep.fetch(package_id)}"
  439. end
  440. nuspec_task.dependency package_id, package_version
  441. end
  442. end
  443. unless args[:assemblies].nil?
  444. args[:assemblies].each do |assembly|
  445. assembly_id = assembly.keys[0]
  446. framework_version = assembly.fetch(assembly_id)
  447. nuspec_task.framework_assembly assembly_id, framework_version
  448. end
  449. end
  450. end
  451. target.out = args[:packageid]
  452. add_dependencies(target, dir, args[:deps])
  453. end
  454. def get_version(dir)
  455. found_version = version
  456. list = FileList.new(dir + "/**/AssemblyInfo.cs").to_a
  457. if list.length > 0
  458. regexp = /^.*AssemblyVersion\(\"(.*)\"\).*$/
  459. assembly_info = File.open list[0]
  460. assembly_info.each do |line|
  461. match = line.match regexp
  462. if (not match.nil?)
  463. found_version = match[1]
  464. found_version = found_version[0..found_version.rindex(".") - 1]
  465. end
  466. end
  467. assembly_info.close
  468. end
  469. found_version
  470. end
  471. end
  472. class PackNuGetPackage < Tasks
  473. def handle(fun, dir, args)
  474. output_dir = "build/dotnet"
  475. spec_file = "#{output_dir}/nuget/#{args[:packageid]}.nuspec"
  476. task_name = task_name(dir, args[:name])
  477. target = nugetpack "#{task_name}" do |nugetpack_task|
  478. puts "Packaging: #{task_name}"
  479. nugetpack_task.command = "third_party/dotnet/nuget/NuGet.exe"
  480. nugetpack_task.nuspec = spec_file
  481. nugetpack_task.base_folder = output_dir
  482. nugetpack_task.output = "#{output_dir}/nuget"
  483. end
  484. end
  485. end
  486. class PublishNuGetPackage < Tasks
  487. def handle(fun, dir, args)
  488. output_dir = "build/dotnet"
  489. package_file = "#{output_dir}/nuget/#{args[:packageid]}.#{version}.nupkg".gsub("/", Platform.dir_separator)
  490. task_name = task_name(dir, args[:name])
  491. desc "Publishes NuGet package for #{task_name} to NuGet Gallery"
  492. target = task "#{task_name}" do
  493. if ENV["apikey"].nil?
  494. puts "No API key specified. NuGet packages will not be published."
  495. else
  496. # Create an "immediate execution" task so that the build won't
  497. # fail if the API key is not specified.
  498. nugetpush! "#{task_name}.publish" do |nugetpush_task|
  499. nugetpush_task.command = "third_party/dotnet/nuget/NuGet.exe"
  500. puts "Publishing NuGet package for: #{task_name}"
  501. nugetpush_task.package = package_file
  502. nugetpush_task.apikey = ENV["apikey"]
  503. end
  504. end
  505. end
  506. end
  507. end
  508. class DotNetRelease < CrazyFunVisualStudio::UploadFile
  509. def handle(fun, dir, args)
  510. output_dir = 'build/dotnet'
  511. file_name = args[:out].chomp(File.extname(args[:out])) + "-" + get_version(dir) + File.extname(args[:out])
  512. output_file = File.join(output_dir, file_name)
  513. full_path = output_file.gsub("/", Platform.dir_separator)
  514. desc "Prepares release file #{full_path}"
  515. task_name = task_name(dir, args[:name])
  516. target = file task_name do
  517. puts "Preparing release file: #{full_path}"
  518. if File.exists? output_file
  519. File.delete output_file
  520. end
  521. tmp_dir = File.join(output_dir, "temp")
  522. mkdir_p tmp_dir
  523. lst = FileList[output_dir + "/*"].exclude(/.*(nuget|temp|unmerged).*/)
  524. puts lst
  525. cp_r lst, tmp_dir
  526. zip(tmp_dir, output_file)
  527. rm_rf tmp_dir
  528. upload_file output_file, args[:desc], args.has_key?(:featured)
  529. end
  530. add_dependencies(target, dir, args[:deps])
  531. target.out = output_file
  532. end
  533. def get_version(dir)
  534. found_version = version
  535. list = FileList.new(dir + "/**/AssemblyInfo.cs").to_a
  536. if list.length > 0
  537. regexp = /^.*AssemblyVersion\(\"(.*)\"\).*$/
  538. assembly_info = File.open list[0], 'rb'
  539. assembly_info.each do |line|
  540. match = line.match regexp
  541. if (not match.nil?)
  542. found_version = match[1]
  543. found_version = found_version[0..found_version.rindex(".") - 1]
  544. end
  545. end
  546. assembly_info.close
  547. end
  548. found_version
  549. end
  550. end
  551. end
  552. module CrazyFunVisualC
  553. class VisualCLibrary < Tasks
  554. def handle(fun, dir, args)
  555. full_path = File.join("build", dir, args[:out])
  556. desc_path = full_path.gsub("/", Platform.dir_separator)
  557. desc "Build #{desc_path}"
  558. task_name = task_name(dir, args[:name])
  559. if !msbuild_installed?
  560. # overwrite the msbuild task with one that just copies prebuilts
  561. file full_path do
  562. copy_prebuilt(fun, full_path)
  563. end
  564. target_task = task task_name => full_path
  565. target_task.out = full_path
  566. else
  567. file desc_path do
  568. begin
  569. msbuild! "#{task_name}.compile" do |msb|
  570. puts "Compiling: #{task_name} as #{desc_path}"
  571. msb.use :net40
  572. msb.properties :configuration => :Release, :platform => args[:platform]
  573. msb.solution = File.join(dir, args[:project])
  574. msb.targets = ["Build"]
  575. msb.parameters "/nologo"
  576. msb.verbosity = "quiet"
  577. end
  578. rescue
  579. puts "Compilation of #{desc_path} failed."
  580. copy_prebuilt(fun, full_path)
  581. end
  582. end
  583. task task_name => desc_path
  584. Rake::Task[task_name].out = desc_path
  585. target_task = Rake::Task[desc_path]
  586. end
  587. add_dependencies(target_task, dir, args[:deps])
  588. target_task.enhance [ args[:file_deps] ] if args[:file_deps]
  589. end
  590. end
  591. class VisualCRelease < CrazyFunVisualStudio::UploadFile
  592. def handle(fun, dir, args)
  593. output_dir = 'build/cpp'
  594. file_name = args[:out].chomp(File.extname(args[:out])) + "_" + args[:platform] + "_" + get_version(dir) + ".zip"
  595. output_file = File.join(output_dir, file_name)
  596. full_path = output_file.gsub("/", Platform.dir_separator)
  597. desc "Prepares release file #{full_path}"
  598. task_name = task_name(dir, args[:name])
  599. release_task_name = task_name(dir, args[:name] + ":release")
  600. target = file release_task_name do
  601. puts "Preparing release file: #{full_path}"
  602. if File.exists? output_file
  603. File.delete output_file
  604. end
  605. if Rake::Task.task_defined? task_name
  606. dependency_output_file = Rake::Task[task_name].out
  607. do_zip(dependency_output_file, output_file)
  608. upload_file output_file, args[:desc], args.has_key?(:featured)
  609. end
  610. end
  611. add_dependencies(target, dir, [task_name])
  612. target.out = output_file
  613. end
  614. def get_version(dir)
  615. found_version = version
  616. list = FileList.new(dir + "/**/*.rc").to_a
  617. if list.length > 0
  618. regexp = /^.*\"FileVersion\",\s*\"(.*)\".*$/
  619. rc = File.open list[0], 'rb'
  620. rc.each do |data|
  621. line = data.gsub(/\x00/, "")
  622. match = line.match regexp
  623. if (not match.nil?)
  624. found_version = match[1]
  625. found_version = found_version[0..found_version.rindex(".") - 1]
  626. end
  627. end
  628. rc.close
  629. end
  630. found_version
  631. end
  632. def do_zip(src, dest)
  633. # Need our own zip implementation as zip in common.rb only
  634. # handles directories, not individual files.
  635. src_dir = File.dirname(Platform.path_for(File.expand_path(src)))
  636. src_file = File.basename(Platform.path_for(File.expand_path(src)))
  637. out = Platform.path_for(File.expand_path(dest))
  638. Dir.chdir(src_dir) {
  639. # TODO(jari): something very weird going on here on windows
  640. # the 2>&1 is needed for some reason
  641. ok = system(%{jar cMf "#{out}" "#{src_file}" 2>&1})
  642. ok or raise "could not zip #{src} => #{dest}"
  643. }
  644. end
  645. end
  646. end