delphivm 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +20 -0
- data/README.md +15 -0
- data/Thorfile.thor +24 -0
- data/bin/delphivm.rb +28 -0
- data/delphi_PROJECTICON.ico +0 -0
- data/delphivm.gemspec +25 -0
- data/dvmimports.org/.gitignore +10 -0
- data/dvmimports.org/404.html +1 -0
- data/dvmimports.org/Rakefile +294 -0
- data/dvmimports.org/_config.yml +124 -0
- data/dvmimports.org/_includes/JB/analytics +12 -0
- data/dvmimports.org/_includes/JB/analytics-providers/getclicky +12 -0
- data/dvmimports.org/_includes/JB/analytics-providers/google +11 -0
- data/dvmimports.org/_includes/JB/categories_list +37 -0
- data/dvmimports.org/_includes/JB/comments +16 -0
- data/dvmimports.org/_includes/JB/comments-providers/disqus +13 -0
- data/dvmimports.org/_includes/JB/comments-providers/facebook +9 -0
- data/dvmimports.org/_includes/JB/comments-providers/intensedebate +6 -0
- data/dvmimports.org/_includes/JB/comments-providers/livefyre +6 -0
- data/dvmimports.org/_includes/JB/liquid_raw +32 -0
- data/dvmimports.org/_includes/JB/pages_list +37 -0
- data/dvmimports.org/_includes/JB/posts_collate +55 -0
- data/dvmimports.org/_includes/JB/setup +22 -0
- data/dvmimports.org/_includes/JB/sharing +8 -0
- data/dvmimports.org/_includes/JB/tags_list +33 -0
- data/dvmimports.org/_includes/themes/twitter/default.html +59 -0
- data/dvmimports.org/_includes/themes/twitter/page.html +9 -0
- data/dvmimports.org/_includes/themes/twitter/post.html +40 -0
- data/dvmimports.org/_includes/themes/twitter/settings.yml +2 -0
- data/dvmimports.org/_layouts/default.html +6 -0
- data/dvmimports.org/_layouts/page.html +5 -0
- data/dvmimports.org/_layouts/post.html +5 -0
- data/dvmimports.org/_plugins/debug.rb +38 -0
- data/dvmimports.org/_plugins/gallery.rb +41 -0
- data/dvmimports.org/archive.html +10 -0
- data/dvmimports.org/assets/themes/twitter/css/1.4.0/bootstrap.css +356 -0
- data/dvmimports.org/assets/themes/twitter/css/style.css +71 -0
- data/dvmimports.org/atom.xml +28 -0
- data/dvmimports.org/categories.html +22 -0
- data/dvmimports.org/download.md +16 -0
- data/dvmimports.org/index.md +21 -0
- data/dvmimports.org/pages.html +13 -0
- data/dvmimports.org/sitemap.txt +8 -0
- data/dvmimports.org/tags.html +21 -0
- data/lib/delphivm/dsl.rb +93 -0
- data/lib/delphivm/ide_services.rb +152 -0
- data/lib/delphivm/version.rb +7 -0
- data/lib/delphivm.rb +167 -0
- data/lib/extensions.rb +37 -0
- data/lib/tasks/ide.thor +38 -0
- data/lib/tasks/project.thor +73 -0
- data/lib/tasks/vendor.thor +73 -0
- data/vendor/imports.dvm +11 -0
- metadata +128 -0
data/lib/delphivm/dsl.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
class Delphivm
|
3
|
+
|
4
|
+
module DSL
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def uses(path_to_file)
|
8
|
+
source = File.read(path_to_file)
|
9
|
+
class_eval(source, path_to_file, 1)
|
10
|
+
end
|
11
|
+
|
12
|
+
def idever(value = nil, &block)
|
13
|
+
return @idever unless value
|
14
|
+
@idever = value
|
15
|
+
class_eval(&block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def source(value = nil)
|
19
|
+
return @source unless value
|
20
|
+
@source = value
|
21
|
+
end
|
22
|
+
|
23
|
+
def import(libname, libver, options={})
|
24
|
+
configs = options[:config]
|
25
|
+
configs ||= ''
|
26
|
+
configs = ['Release', 'Debug'] if configs == '*'
|
27
|
+
configs = [configs] unless configs.is_a?Array
|
28
|
+
source_uri = source
|
29
|
+
configs.each do |config|
|
30
|
+
cfg_segment = config.strip
|
31
|
+
cfg_segment = "-#{cfg_segment}" unless cfg_segment.empty?
|
32
|
+
lib_file = "#{libname}-#{libver}-#{idever}#{cfg_segment}.zip"
|
33
|
+
result = download(source_uri, PATH_TO_VENDOR_CACHE, lib_file)
|
34
|
+
path_to_lib = PATH_TO_VENDOR_CACHE + lib_file
|
35
|
+
unzip(path_to_lib, PATH_TO_VENDOR_IMPORTS + idever) if result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def download(source_uri, dowonlad_root_path, file_name)
|
42
|
+
full_url = source_uri + '/' + file_name
|
43
|
+
to_here = dowonlad_root_path + file_name
|
44
|
+
pb = nil
|
45
|
+
puts "Downloading: #{full_url}"
|
46
|
+
start = lambda do |length, hint=''|
|
47
|
+
pb = ProgressBar.new("#{file_name}", length);
|
48
|
+
pb.instance_variable_set "@title_width", file_name.length + 2
|
49
|
+
pb.format = "\s\s%-s #{hint} %3d%% %s %s"
|
50
|
+
pb.clear
|
51
|
+
pb.send :show
|
52
|
+
end
|
53
|
+
|
54
|
+
progress = lambda {|s| pb.set(s)}
|
55
|
+
|
56
|
+
if Pathname(to_here).exist?
|
57
|
+
start.call(0, "(cached)")
|
58
|
+
else
|
59
|
+
begin
|
60
|
+
content = open(full_url, "rb", content_length_proc: start, progress_proc: progress).read
|
61
|
+
File.open(to_here, "wb") do |wfile|
|
62
|
+
wfile.write(content)
|
63
|
+
end
|
64
|
+
rescue Exception => e
|
65
|
+
puts e
|
66
|
+
Pathname(to_here).delete if File.exist?(to_here)
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
return true
|
71
|
+
ensure
|
72
|
+
pb.finish if pb
|
73
|
+
end
|
74
|
+
|
75
|
+
def unzip(file, destination)
|
76
|
+
Zip::ZipFile.open(file) do |zip_file|
|
77
|
+
pb = ProgressBar.new("", zip_file.size)
|
78
|
+
pb.format = "\s\s\s\sextracting: %3d%% %s file: %-34s"
|
79
|
+
pb.format_arguments = [:percentage, :bar, :title]
|
80
|
+
zip_file.each do |f|
|
81
|
+
f_path = destination + f.name
|
82
|
+
next if Pathname(f_path).directory?
|
83
|
+
f_path.dirname.mkpath
|
84
|
+
pb.instance_variable_set "@title", "#{f_path.basename}"
|
85
|
+
pb.inc
|
86
|
+
Pathname(f_path).delete if File.exist?(f_path)
|
87
|
+
zip_file.extract(f, f_path)
|
88
|
+
end
|
89
|
+
pb.finish
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
SendMessageTimeout = Win32API.new('user32', 'SendMessageTimeout', 'LLLPLLP', 'L')
|
4
|
+
HWND_BROADCAST = 0xffff
|
5
|
+
WM_SETTINGCHANGE = 0x001A
|
6
|
+
SMTO_ABORTIFHUNG = 2
|
7
|
+
|
8
|
+
class Delphivm
|
9
|
+
|
10
|
+
class IDEServices
|
11
|
+
attr :idever
|
12
|
+
attr :workdir
|
13
|
+
GROUP_FILE_EXT = ['groupproj', 'bdsgroup']
|
14
|
+
IDEInfos = {
|
15
|
+
'D100' => {regkey: 'Software\Borland\BDS\4.0', name: '2006', desc: 'Borland Developer Stuido 4.0'},
|
16
|
+
'D150' => {regkey: 'Software\Embarcadero\BDS\8.0', name: 'XE', desc: 'Embarcadero RAD Stuido XE'},
|
17
|
+
'D160' => {regkey: 'Software\Embarcadero\BDS\9.0', name: 'XE2', desc: 'Embarcadero RAD Stuido XE2'},
|
18
|
+
'D170' => {regkey: 'Software\Embarcadero\BDS\10.0', name: 'XE3', desc: 'Embarcadero RAD Stuido XE3'}
|
19
|
+
}
|
20
|
+
|
21
|
+
def self.idelist
|
22
|
+
result = []
|
23
|
+
IDEInfos.each {|ide, info| result << ide if (Win32::Registry::HKEY_CURRENT_USER.open(info[:regkey]) {|reg| reg} rescue false)}
|
24
|
+
result.sort.reverse
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.ideused
|
28
|
+
#TODO ensure we return only ides listed at IDEInfos
|
29
|
+
ROOT.glob("{src,samples}/**/*.{#{GROUP_FILE_EXT.join(',')}}").map {|f| f.dirname.basename.to_s.split('-')[0]}.uniq.sort
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.use(ide_tag)
|
33
|
+
bin_paths = ide_paths.map{ |p| p + 'bin' }
|
34
|
+
path = Win32::Registry::HKEY_CURRENT_USER.open('Environment'){|r| r['PATH']}
|
35
|
+
|
36
|
+
path = path.split(';')
|
37
|
+
path.reject! { |p| bin_paths.include?(p) }
|
38
|
+
new_path = ide_paths(ide_tag.upcase).map{ |p| p + 'bin' }.first
|
39
|
+
path.unshift new_path
|
40
|
+
path = path.join(';')
|
41
|
+
self.winpath= path
|
42
|
+
return new_path
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize(idever, workdir)
|
46
|
+
@idever = idever.upcase
|
47
|
+
@workdir = workdir
|
48
|
+
@reg = Win32::Registry::HKEY_CURRENT_USER
|
49
|
+
end
|
50
|
+
|
51
|
+
def [](key)
|
52
|
+
@reg.open(IDEInfos[idever][:regkey]) {|r| r[key] }
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_env
|
56
|
+
ENV["PATH"] = '$(BDSCOMMONDIR)\bpl;' + ENV["PATH"]
|
57
|
+
ENV["PATH"] = self['RootDir'] + 'bin;' + ENV["PATH"]
|
58
|
+
ENV["BDSPROJECTGROUPDIR"] = workdir.win
|
59
|
+
ENV["IDEVERSION"] = idever
|
60
|
+
end
|
61
|
+
|
62
|
+
def start
|
63
|
+
set_env
|
64
|
+
Process.detach(spawn "#{self['App']}", "-r#{prj_slug}")
|
65
|
+
say "started bds -r#{prj_slug}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def prj_slug
|
69
|
+
workdir.basename.to_s.upcase
|
70
|
+
end
|
71
|
+
|
72
|
+
def supports_msbuild?(idever)
|
73
|
+
ide_number = idever[1..-1].to_i
|
74
|
+
ide_number > 140
|
75
|
+
end
|
76
|
+
|
77
|
+
def msbuild(config, target)
|
78
|
+
set_env
|
79
|
+
self.class.winshell(out_filter: ->(line){line =~ /(error)/}) do |i|
|
80
|
+
Pathname.glob(workdir + "{src,samples}/#{idever}**/*.{#{GROUP_FILE_EXT.join(',')}}") do |f|
|
81
|
+
f_to_show = f.relative_path_from(workdir)
|
82
|
+
say "#{target} (#{config}) #{f_to_show.win} ...."
|
83
|
+
# paths can contains spaces so we need use quotes
|
84
|
+
if supports_msbuild?(idever)
|
85
|
+
i.puts %Q["#{self['RootDir'] + 'bin\rsvars.bat'}"]
|
86
|
+
i.puts %Q[msbuild /nologo /t:#{target} /p:Config=#{config} "#{f.win}"]
|
87
|
+
else
|
88
|
+
i.puts %Q[bds -b "#{f.win}"]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.winshell(options = {})
|
95
|
+
acmd = options[:cmd] || 'cmd /k'
|
96
|
+
out_filter = options[:out_filter] || ->(line){true}
|
97
|
+
err_filter = options[:err_filter] || ->(line){true}
|
98
|
+
|
99
|
+
Open3.popen3(acmd) do |i,o,e,t|
|
100
|
+
err_t = Thread.new(e) do |stm|
|
101
|
+
while (line = stm.gets)
|
102
|
+
say "STDERR: #{line}" if err_filter.call(line)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
out_t = Thread.new(o) do |stm|
|
107
|
+
while (line = stm.gets)
|
108
|
+
say "#{line}" if out_filter.call(line)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
begin
|
113
|
+
yield i if block_given?
|
114
|
+
i.close
|
115
|
+
err_t.join
|
116
|
+
out_t.join
|
117
|
+
o.close
|
118
|
+
e.close
|
119
|
+
rescue Exception => excep
|
120
|
+
say excep
|
121
|
+
end
|
122
|
+
t.value
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def self.say(msg)
|
129
|
+
puts msg
|
130
|
+
end
|
131
|
+
|
132
|
+
def say(msg)
|
133
|
+
self.class.say(msg)
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.ide_paths(idetag=nil)
|
137
|
+
result = []
|
138
|
+
@reg = Win32::Registry::HKEY_CURRENT_USER
|
139
|
+
IDEInfos.each { |key, data|
|
140
|
+
@reg.open(data[:regkey]) {|r| result << 'RootDir' } if idetag.nil? || idetag.to_s == key
|
141
|
+
}
|
142
|
+
result
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.winpath=(path)
|
146
|
+
Win32::Registry::HKEY_CURRENT_USER.open('Environment', Win32::Registry::KEY_WRITE) do |r|
|
147
|
+
r['PATH'] = path
|
148
|
+
end
|
149
|
+
SendMessageTimeout.call(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 'Environment', SMTO_ABORTIFHUNG, 5000, 0)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
data/lib/delphivm.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
require 'thor'
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
Delphivm = Thor
|
8
|
+
|
9
|
+
class Delphivm
|
10
|
+
ROOT = ::Pathname.getwd
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'zip/zip'
|
14
|
+
|
15
|
+
require 'open3'
|
16
|
+
require 'nokogiri'
|
17
|
+
|
18
|
+
require 'win32/registry.rb'
|
19
|
+
require 'Win32API'
|
20
|
+
|
21
|
+
require 'version_info'
|
22
|
+
require 'open-uri'
|
23
|
+
require 'net/http'
|
24
|
+
require 'progressbar'
|
25
|
+
|
26
|
+
require 'extensions'
|
27
|
+
require 'delphivm/version'
|
28
|
+
require 'delphivm/ide_services'
|
29
|
+
require 'delphivm/dsl'
|
30
|
+
|
31
|
+
require 'thor/runner'
|
32
|
+
|
33
|
+
if Delphivm::ROOT == Pathname(__FILE__).dirname.parent
|
34
|
+
TARGET = Object.const_get('Delphivm')
|
35
|
+
else
|
36
|
+
VersionInfo.file_format = :text
|
37
|
+
target = Module.new
|
38
|
+
target.module_exec do
|
39
|
+
include VersionInfo
|
40
|
+
self.VERSION.file_name = Delphivm::ROOT + 'VERSION'
|
41
|
+
end
|
42
|
+
Object.const_set(Delphivm::ROOT.basename.to_s.snake_case.camelize, target)
|
43
|
+
target.freeze
|
44
|
+
VersionInfo.install_tasks(:target => target)
|
45
|
+
|
46
|
+
TARGET = Object.const_get(target.name)
|
47
|
+
end
|
48
|
+
|
49
|
+
module Thor::Util #:nodoc:
|
50
|
+
SEARCH_ROOT = File.dirname(__FILE__)
|
51
|
+
# redefine to search tasks only for this app
|
52
|
+
def self.globs_for(path)
|
53
|
+
["#{SEARCH_ROOT}/tasks/*.thor", "#{Delphivm::ROOT}/dvm/*.thor"]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
class BuildTarget < Thor
|
59
|
+
attr_accessor :idetag
|
60
|
+
attr_accessor :config
|
61
|
+
|
62
|
+
INCL_BUILD = /(_|\/|\A)build(_|\/|\Z)/ # REX for recognize a build subpath
|
63
|
+
|
64
|
+
include Thor::Actions
|
65
|
+
|
66
|
+
def self.inherited(klass)
|
67
|
+
klass.source_root(ROOT)
|
68
|
+
klass.publish
|
69
|
+
end
|
70
|
+
|
71
|
+
def method_missing(name, *args, &block)
|
72
|
+
if name.to_s.match(/(\w+)_path$/)
|
73
|
+
convert_to_path $1
|
74
|
+
else
|
75
|
+
super
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
def self.depends(*task_names)
|
81
|
+
@depends ||=[]
|
82
|
+
@depends.push *task_names
|
83
|
+
@depends
|
84
|
+
end
|
85
|
+
|
86
|
+
def clear_products
|
87
|
+
@products = []
|
88
|
+
end
|
89
|
+
|
90
|
+
def catch_products
|
91
|
+
@catch_products = true
|
92
|
+
yield
|
93
|
+
ensure
|
94
|
+
@catch_products = false
|
95
|
+
end
|
96
|
+
|
97
|
+
def catch_product(*prods)
|
98
|
+
@products.push *prods
|
99
|
+
yield *prods unless @catch_products
|
100
|
+
end
|
101
|
+
|
102
|
+
def do_clean(idetag, cfg)
|
103
|
+
catch_products do
|
104
|
+
do_make(idetag, cfg)
|
105
|
+
end
|
106
|
+
@products.each do |p|
|
107
|
+
remove_file(p)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def do_make(idetag, cfg)
|
112
|
+
end
|
113
|
+
|
114
|
+
def do_build(idetag, cfg)
|
115
|
+
invoke :clean
|
116
|
+
invoke :make
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.publish
|
120
|
+
[:clean, :make, :build].each do |mth|
|
121
|
+
desc "#{mth}", "#{mth} #{self.namespace} products"
|
122
|
+
method_option :config, type: :array, aliases: '-c', default: 'Debug', desc: "use IDE config(s): Debug, Release, etc"
|
123
|
+
define_method mth do
|
124
|
+
IDEServices.ideused.each do |idetag|
|
125
|
+
configs = [options[:config]].flatten
|
126
|
+
configs.each do |cfg|
|
127
|
+
self.idetag = idetag
|
128
|
+
self.config = cfg
|
129
|
+
self.clear_products
|
130
|
+
self.class.depends.each { |task| self.invoke "#{task}:#{mth}" }
|
131
|
+
send("do_#{mth}", idetag, cfg)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def convert_to_path(under_scored='')
|
139
|
+
buildpath_as_str = (Pathname('out') + self.idetag + self.config).to_s
|
140
|
+
ROOT + under_scored.to_s.split('_').join('/').gsub(INCL_BUILD, '\1' + buildpath_as_str + '\2')
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
class Delphivm
|
146
|
+
EXE_NAME = File.basename($0, '.rb')
|
147
|
+
|
148
|
+
PATH_TO_VENDOR = ROOT + 'vendor'
|
149
|
+
PATH_TO_VENDOR_CACHE = PATH_TO_VENDOR + 'cache'
|
150
|
+
PATH_TO_VENDOR_IMPORTS = PATH_TO_VENDOR + 'imports'
|
151
|
+
DVM_IMPORTS_FILE = PATH_TO_VENDOR + 'imports.dvm'
|
152
|
+
|
153
|
+
class Runner
|
154
|
+
# remove some tasks not needed
|
155
|
+
remove_task :install, :installed, :uninstall, :update
|
156
|
+
|
157
|
+
# default version and banner outputs THOR, so redefine it
|
158
|
+
def self.banner(task, all = false, subcommand = false)
|
159
|
+
"#{Delphivm::EXE_NAME} " + task.formatted_usage(self, all, subcommand)
|
160
|
+
end
|
161
|
+
|
162
|
+
desc "version", "Show #{Delphivm::EXE_NAME} version"
|
163
|
+
def version
|
164
|
+
say "#{Delphivm::VERSION}"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
data/lib/extensions.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
class ::Pathname
|
3
|
+
def glob(*args, &block)
|
4
|
+
args[0] = (self + args[0]).to_s
|
5
|
+
Pathname.glob(*args, &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def win
|
9
|
+
self.to_s.gsub('/','\\')
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_str
|
13
|
+
win
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class String
|
18
|
+
def snake_case
|
19
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
20
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
21
|
+
tr("-", "_").
|
22
|
+
downcase
|
23
|
+
end
|
24
|
+
|
25
|
+
def camelize
|
26
|
+
self.split('_').map(&:capitalize).join
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module Kernel
|
31
|
+
def silence_warnings
|
32
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
33
|
+
yield
|
34
|
+
ensure
|
35
|
+
$VERBOSE = old_verbose
|
36
|
+
end
|
37
|
+
end
|
data/lib/tasks/ide.thor
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
class Ide < Thor
|
4
|
+
|
5
|
+
desc "list", "show instaled IDE versions"
|
6
|
+
def list
|
7
|
+
report_ides IDEServices.idelist
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "use IDE-TAG", "use IDE with IDE-TAG"
|
11
|
+
def use(ide_tag)
|
12
|
+
puts "Active path: " + IDEServices.use(ide_tag)
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "used", "list used IDEs in project"
|
16
|
+
def used
|
17
|
+
report_ides IDEServices.ideused
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "start IDE-TAG ", "start IDE with IDE-TAG"
|
21
|
+
def start(idever=nil)
|
22
|
+
idever ||= IDEServices.idelist.first
|
23
|
+
ide = IDEServices.new(idever, ROOT)
|
24
|
+
ide.start
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def report_ides(ides)
|
30
|
+
if ides.empty?
|
31
|
+
say "NO IDE(s) found\n"
|
32
|
+
else
|
33
|
+
say "found IDEs:\n"
|
34
|
+
say ides.join("\n")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
|
4
|
+
class Project < BuildTarget
|
5
|
+
|
6
|
+
SHIP_FILE = "#{TARGET}-#{TARGET.VERSION.tag}"
|
7
|
+
|
8
|
+
desc "clean", "clean #{SHIP_FILE} products", :for => :clean
|
9
|
+
|
10
|
+
desc "make", "make #{SHIP_FILE} products", :for => :make
|
11
|
+
desc "build", "build #{SHIP_FILE} products", :for => :build
|
12
|
+
|
13
|
+
desc "ship", "create ship file #{SHIP_FILE}.zip file"
|
14
|
+
method_option :config, type: :array, aliases: '-c', default: '', desc: "use IDE config(s): Debug, Release, etc"
|
15
|
+
def ship
|
16
|
+
get_idevers.each do |idever|
|
17
|
+
#ide = IDEServices.new(idever, ROOT)
|
18
|
+
configs = [options[:config]].flatten
|
19
|
+
configs.each do |cfg|
|
20
|
+
build_ship(idever, cfg)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def do_clean(idetag, cfg)
|
28
|
+
ide = IDEServices.new(idetag, ROOT)
|
29
|
+
ide.msbuild(cfg, 'Clean')
|
30
|
+
end
|
31
|
+
|
32
|
+
def do_make(idetag, cfg)
|
33
|
+
ide = IDEServices.new(idetag, ROOT)
|
34
|
+
ide.msbuild(cfg, 'Make')
|
35
|
+
end
|
36
|
+
|
37
|
+
def do_build(idetag, cfg)
|
38
|
+
ide = IDEServices.new(idetag, ROOT)
|
39
|
+
ide.msbuild(cfg, 'Build')
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def get_idevers
|
45
|
+
IDEServices.ideused
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_ship(idever, config)
|
49
|
+
cfg_segment = config.strip
|
50
|
+
cfg_segment = "-#{cfg_segment}" unless cfg_segment.empty?
|
51
|
+
|
52
|
+
zip_fname = ROOT + 'ship' + "#{SHIP_FILE}-#{idever}#{cfg_segment}.zip"
|
53
|
+
zip_fname.dirname.mkpath
|
54
|
+
zip_fname.delete if zip_fname.exist?
|
55
|
+
|
56
|
+
groups = [
|
57
|
+
["output", ROOT + 'out' + idever + config, Pathname('.')],
|
58
|
+
["source", ROOT + 'src', Pathname('src') + SHIP_FILE],
|
59
|
+
["sample", ROOT + 'samples', Pathname('samples') + SHIP_FILE],
|
60
|
+
["documentation", ROOT + 'doc', Pathname('doc') + SHIP_FILE]
|
61
|
+
]
|
62
|
+
puts "Ship file " + zip_fname.to_s
|
63
|
+
Zip::ZipFile.open(zip_fname, Zip::ZipFile::CREATE) do |zipfile|
|
64
|
+
groups.each do |group|
|
65
|
+
puts "Add #{group[0]} files"
|
66
|
+
Pathname.glob((group[1] + '**' + '*.*').to_s).each do |source_file|
|
67
|
+
zip_entry = group[2] + source_file.relative_path_from(group[1])
|
68
|
+
zipfile.get_output_stream(zip_entry) { |f| f.puts source_file.read(:mode => "rb") }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
class Vendor < Thor
|
3
|
+
include Thor::Actions
|
4
|
+
|
5
|
+
desc "init", "create and initialize vendor directory"
|
6
|
+
def init
|
7
|
+
vendor_path = PATH_TO_VENDOR
|
8
|
+
empty_directory vendor_path
|
9
|
+
empty_directory vendor_path + 'cache'
|
10
|
+
empty_directory vendor_path + 'imports'
|
11
|
+
create_file(DVM_IMPORTS_FILE, :skip => true) do <<-EOS
|
12
|
+
# sample imports file for delphivm
|
13
|
+
|
14
|
+
# first set source url
|
15
|
+
source "http://home.jcangas.info/ship"
|
16
|
+
|
17
|
+
# for each IDE version yo need
|
18
|
+
idever "D150" do
|
19
|
+
# define some imports:
|
20
|
+
import "SummerFW4D", "0.4.6"
|
21
|
+
end
|
22
|
+
|
23
|
+
# you can repeat it for other IDEs & sources
|
24
|
+
|
25
|
+
# source "#{PATH_TO_VENDOR}/local"
|
26
|
+
# etc..
|
27
|
+
|
28
|
+
EOS
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "import", "download and install vendor imports"
|
33
|
+
method_option :clean, type: :boolean, aliases: '-c', default: false, desc: "clean cache first"
|
34
|
+
method_option :deploy, type: :boolean, aliases: '-d', default: false, desc: "deploy after the import"
|
35
|
+
def import
|
36
|
+
clean_vendor(options) if options.clean?
|
37
|
+
prepare
|
38
|
+
silence_warnings{DSL.uses(DVM_IMPORTS_FILE)}
|
39
|
+
deploy_vendor if options.deploy?
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "clean", "Clean imports. Use -c (--cache) to also clean downloads cache"
|
43
|
+
method_option :cache, type: :boolean, aliases: '-c', default: false, desc: "also clean cache"
|
44
|
+
def clean
|
45
|
+
clean_vendor(options)
|
46
|
+
prepare
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "deploy", "deploy vendor bin files to project out dir"
|
50
|
+
def deploy
|
51
|
+
deploy_vendor
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def deploy_vendor
|
57
|
+
self.class.source_root PATH_TO_VENDOR_IMPORTS
|
58
|
+
PATH_TO_VENDOR_IMPORTS.glob('**/bin/*.*') do |f|
|
59
|
+
fname = f.relative_path_from(PATH_TO_VENDOR_IMPORTS)
|
60
|
+
copy_file(fname, ROOT + 'out' + fname)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def clean_vendor(opts)
|
65
|
+
remove_dir(PATH_TO_VENDOR_IMPORTS)
|
66
|
+
remove_dir PATH_TO_VENDOR_CACHE if opts.cache?
|
67
|
+
end
|
68
|
+
|
69
|
+
def prepare
|
70
|
+
empty_directory PATH_TO_VENDOR_CACHE
|
71
|
+
empty_directory PATH_TO_VENDOR_IMPORTS
|
72
|
+
end
|
73
|
+
end
|