delphivm 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Thorfile.thor +2 -2
- data/delphivm.gemspec +1 -1
- data/delphivm.sublime-project +8 -0
- data/delphivm.sublime-workspace +453 -0
- data/lib/build_target.rb +84 -0
- data/lib/delphivm.rb +77 -137
- data/lib/delphivm/generator.rb +123 -0
- data/lib/delphivm/ide_services.rb +8 -3
- data/lib/delphivm/runner.rb +5 -8
- data/lib/delphivm/version.rb +3 -4
- data/lib/dvm/gen/app.thor +84 -0
- data/lib/dvm/ide.thor +3 -2
- data/lib/dvm/project.thor +1 -1
- data/lib/extensions.rb +1 -1
- data/templates/delphi/app.tt/.gitignore.tt +18 -0
- data/templates/delphi/app.tt/BDS.bat.tt +9 -0
- data/templates/delphi/app.tt/BUILD.bat.tt +19 -0
- data/templates/delphi/app.tt/README.md.tt +16 -0
- data/templates/delphi/app.tt/VERSION +1 -0
- data/templates/delphi/app.tt/license.txt +61 -0
- data/templates/delphi/app.tt/src/@D170/%{app_name}App.groupproj +45 -0
- data/templates/delphi/app.tt/src/source.optset +18 -0
- data/templates/delphi/dproj/sample.tt/samples/@D170/%{name}.dpr +12 -0
- data/templates/delphi/dproj/sample.tt/samples/@D170/%{name}.dproj +146 -0
- data/templates/delphi/dproj/src.tt/src/@D170/%{app_name}.dpr +12 -0
- data/templates/delphi/dproj/src.tt/src/@D170/%{app_name}.dproj +174 -0
- data/templates/delphi/dproj/test.tt/tests/@D170/%{name}.dpr +24 -0
- data/templates/delphi/dproj/test.tt/tests/@D170/%{name}.dproj +146 -0
- data/templates/delphi/samples.tt/samples/@D170/%{app_name}Samples.groupproj +44 -0
- data/templates/delphi/samples.tt/samples/samples.optset +19 -0
- data/templates/delphi/tests.tt/tests/@D170/%{app_name}Tests.groupproj +44 -0
- data/templates/delphi/tests.tt/tests/tests.optset +35 -0
- metadata +26 -2
data/lib/build_target.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
class BuildTarget < Thor
|
2
|
+
attr_accessor :idetag
|
3
|
+
attr_accessor :config
|
4
|
+
|
5
|
+
INCL_BUILD = /(_|\/|\A)build(_|\/|\Z)/ # REX for recognize a build subpath
|
6
|
+
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
def self.inherited(klass)
|
10
|
+
klass.source_root(ROOT)
|
11
|
+
klass.publish
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(name, *args, &block)
|
15
|
+
if name.to_s.match(/(\w+)_path$/)
|
16
|
+
convert_to_path $1
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
def self.depends(*task_names)
|
24
|
+
@depends ||=[]
|
25
|
+
@depends.push(*task_names)
|
26
|
+
@depends
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear_products
|
30
|
+
@products = []
|
31
|
+
end
|
32
|
+
|
33
|
+
def catch_products
|
34
|
+
@catch_products = true
|
35
|
+
yield
|
36
|
+
ensure
|
37
|
+
@catch_products = false
|
38
|
+
end
|
39
|
+
|
40
|
+
def catch_product(*prods)
|
41
|
+
@products.push(*prods)
|
42
|
+
yield *prods unless @catch_products
|
43
|
+
end
|
44
|
+
|
45
|
+
def do_clean(idetag, cfg)
|
46
|
+
catch_products do
|
47
|
+
do_make(idetag, cfg)
|
48
|
+
end
|
49
|
+
@products.each do |p|
|
50
|
+
remove_file(p)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def do_make(idetag, cfg)
|
55
|
+
end
|
56
|
+
|
57
|
+
def do_build(idetag, cfg)
|
58
|
+
invoke :clean
|
59
|
+
invoke :make
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.publish
|
63
|
+
[:clean, :make, :build].each do |mth|
|
64
|
+
desc "#{mth}", "#{mth} #{self.namespace} products"
|
65
|
+
method_option :params, type: :hash, aliases: '-p', default: {:Config => 'Debug'}, desc: "more MSBuild params. See MSBuild help"
|
66
|
+
define_method mth do
|
67
|
+
msbuild_params = options[:params]
|
68
|
+
IDEServices.ideused.each do |idetag|
|
69
|
+
self.idetag = idetag
|
70
|
+
self.config = msbuild_params
|
71
|
+
self.clear_products
|
72
|
+
self.class.depends.each { |task| self.invoke "#{task}:#{mth}" }
|
73
|
+
send("do_#{mth}", idetag, msbuild_params)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def convert_to_path(under_scored='')
|
80
|
+
buildpath_as_str = (Pathname('out') + self.idetag + self.config[:Config]).to_s
|
81
|
+
ROOT + under_scored.to_s.split('_').join('/').gsub(INCL_BUILD, '\1' + buildpath_as_str + '\2')
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
data/lib/delphivm.rb
CHANGED
@@ -1,137 +1,77 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'thor'
|
4
|
-
require 'pathname'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
require '
|
12
|
-
|
13
|
-
require '
|
14
|
-
require '
|
15
|
-
|
16
|
-
require '
|
17
|
-
|
18
|
-
require '
|
19
|
-
|
20
|
-
require '
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
def self.
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
@depends.push(*task_names)
|
79
|
-
@depends
|
80
|
-
end
|
81
|
-
|
82
|
-
def clear_products
|
83
|
-
@products = []
|
84
|
-
end
|
85
|
-
|
86
|
-
def catch_products
|
87
|
-
@catch_products = true
|
88
|
-
yield
|
89
|
-
ensure
|
90
|
-
@catch_products = false
|
91
|
-
end
|
92
|
-
|
93
|
-
def catch_product(*prods)
|
94
|
-
@products.push(*prods)
|
95
|
-
yield *prods unless @catch_products
|
96
|
-
end
|
97
|
-
|
98
|
-
def do_clean(idetag, cfg)
|
99
|
-
catch_products do
|
100
|
-
do_make(idetag, cfg)
|
101
|
-
end
|
102
|
-
@products.each do |p|
|
103
|
-
remove_file(p)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def do_make(idetag, cfg)
|
108
|
-
end
|
109
|
-
|
110
|
-
def do_build(idetag, cfg)
|
111
|
-
invoke :clean
|
112
|
-
invoke :make
|
113
|
-
end
|
114
|
-
|
115
|
-
def self.publish
|
116
|
-
[:clean, :make, :build].each do |mth|
|
117
|
-
desc "#{mth}", "#{mth} #{self.namespace} products"
|
118
|
-
method_option :params, type: :hash, aliases: '-p', default: {:Config => 'Debug'}, desc: "more MSBuild params. See MSBuild help"
|
119
|
-
define_method mth do
|
120
|
-
msbuild_params = options[:params]
|
121
|
-
IDEServices.ideused.each do |idetag|
|
122
|
-
self.idetag = idetag
|
123
|
-
self.config = msbuild_params
|
124
|
-
self.clear_products
|
125
|
-
self.class.depends.each { |task| self.invoke "#{task}:#{mth}" }
|
126
|
-
send("do_#{mth}", idetag, msbuild_params)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def convert_to_path(under_scored='')
|
133
|
-
buildpath_as_str = (Pathname('out') + self.idetag + self.config[:Config]).to_s
|
134
|
-
ROOT + under_scored.to_s.split('_').join('/').gsub(INCL_BUILD, '\1' + buildpath_as_str + '\2')
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
require 'zip/zip'
|
7
|
+
|
8
|
+
require 'open3'
|
9
|
+
require 'nokogiri'
|
10
|
+
|
11
|
+
require 'win32/registry.rb'
|
12
|
+
|
13
|
+
require 'version_info'
|
14
|
+
require 'open-uri'
|
15
|
+
require 'net/http'
|
16
|
+
require 'ruby-progressbar'
|
17
|
+
|
18
|
+
require 'extensions'
|
19
|
+
|
20
|
+
require 'build_target'
|
21
|
+
|
22
|
+
Delphivm = Thor # sure, we are hacking Thor !
|
23
|
+
|
24
|
+
class Delphivm
|
25
|
+
include(VersionInfo)
|
26
|
+
|
27
|
+
ROOT = ::Pathname.getwd
|
28
|
+
GEM_ROOT = Pathname(__FILE__).dirname.parent
|
29
|
+
EXE_NAME = File.basename($0, '.rb')
|
30
|
+
|
31
|
+
PATH_TO_VENDOR = ROOT + 'vendor'
|
32
|
+
PATH_TO_VENDOR_CACHE = PATH_TO_VENDOR + 'cache'
|
33
|
+
PATH_TO_VENDOR_IMPORTS = PATH_TO_VENDOR + 'imports'
|
34
|
+
DVM_IMPORTS_FILE = PATH_TO_VENDOR + 'imports.dvm'
|
35
|
+
|
36
|
+
module Util #:nodoc:
|
37
|
+
# redefine Thor to search tasks only for this app
|
38
|
+
def self.globs_for(path)
|
39
|
+
["#{GEM_ROOT}/lib/dvm/**/*.thor", "#{Delphivm::ROOT}/dvm/**/*.thor"]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Gen < Thor
|
44
|
+
namespace :gen
|
45
|
+
# used only as thor namesapce for generators
|
46
|
+
# defined here because we need ensure class Gen exist when generator tasks are loaded
|
47
|
+
desc "echo", "prueba de echo"
|
48
|
+
def echo
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def self.create_app_module
|
54
|
+
@app_module = ::Module.new do
|
55
|
+
include VersionInfo
|
56
|
+
self.VERSION.file_name = ROOT + 'VERSION'
|
57
|
+
end
|
58
|
+
Object.const_set(ROOT.basename.to_s.snake_case.camelize, @app_module)
|
59
|
+
@app_module.freeze # force to fix then module name
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.app_module
|
63
|
+
return @app_module if @app_module
|
64
|
+
if ROOT.basename.to_s.casecmp(EXE_NAME) == 0
|
65
|
+
@app_module = Delphivm
|
66
|
+
else
|
67
|
+
create_app_module
|
68
|
+
end
|
69
|
+
VersionInfo.install_tasks(:target => @app_module)
|
70
|
+
@app_module
|
71
|
+
end
|
72
|
+
public
|
73
|
+
APPMODULE = self.app_module
|
74
|
+
end
|
75
|
+
|
76
|
+
# Runner must be loaded after Delphivm setup, i.e., after Thor is hacked
|
77
|
+
require 'delphivm/runner'
|
@@ -0,0 +1,123 @@
|
|
1
|
+
class Delphivm
|
2
|
+
|
3
|
+
module Generator
|
4
|
+
TEMPLATE_ROOT = GEM_ROOT + Pathname('templates/delphi')
|
5
|
+
|
6
|
+
def self.included(base) #:nodoc:
|
7
|
+
base.send :include, Thor::Actions
|
8
|
+
base.add_runtime_options!
|
9
|
+
base.extend ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def subtemplate
|
14
|
+
@subtemplate
|
15
|
+
end
|
16
|
+
|
17
|
+
def subtemplate=(value)
|
18
|
+
@subtemplate = value
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_app_name
|
22
|
+
@app_name = output_folder.basename.to_s.camelize
|
23
|
+
end
|
24
|
+
|
25
|
+
def desc(*msg)
|
26
|
+
if msg.size==1
|
27
|
+
command = name.split(':')[-1].downcase
|
28
|
+
args = self.arguments.map {|arg| arg.usage }.join(' ')
|
29
|
+
# # hide from thor standard list
|
30
|
+
group(' ')
|
31
|
+
Gen.register(self, command, command + ' ' + args, *msg)
|
32
|
+
end
|
33
|
+
super *msg
|
34
|
+
end
|
35
|
+
|
36
|
+
def template_subfolder
|
37
|
+
subpath = (subtemplate.to_s.empty? ? '' : '/' + subtemplate.to_s)
|
38
|
+
@template_subfolder = self.name.split('::')[-1].snake_case + subpath + '.tt'
|
39
|
+
end
|
40
|
+
|
41
|
+
def output_folder
|
42
|
+
@output_folder ||= ROOT
|
43
|
+
end
|
44
|
+
|
45
|
+
def output_folder=(value)
|
46
|
+
@output_folder = Pathname(value.to_s)
|
47
|
+
end
|
48
|
+
|
49
|
+
def source_root
|
50
|
+
TEMPLATE_ROOT + self.template_subfolder
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def method_missing(name, *args, &block)
|
55
|
+
binding_params.has_key?(name) ? binding_params[name] : super
|
56
|
+
end
|
57
|
+
|
58
|
+
def do_folder_template(folder)
|
59
|
+
empty_directory folder
|
60
|
+
end
|
61
|
+
|
62
|
+
def do_file_template(source, target)
|
63
|
+
template(source, target.dirname + target.basename('.tt'))
|
64
|
+
rescue Exception => e
|
65
|
+
say "task #{self.class.namespace} proccessing template #{source}", :red
|
66
|
+
say "ERROR: #{e.message}", :red
|
67
|
+
say "avaiable params:\n", :red
|
68
|
+
print_table(binding_params.inject({}){|r,p| r[":#{p[0]} => "] = p[1];r}.to_a)
|
69
|
+
raise ""
|
70
|
+
end
|
71
|
+
|
72
|
+
def skip_template_item?(item, directory)
|
73
|
+
if directory && item.to_s =~ /@(.+)/
|
74
|
+
($1 != binding_params[:idever])
|
75
|
+
else
|
76
|
+
false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def do_execute
|
81
|
+
self.class.source_root.glob('**/*') do |f|
|
82
|
+
source = f.relative_path_from(self.class.source_root)
|
83
|
+
target = self.class.output_folder + source
|
84
|
+
|
85
|
+
next if skip_template_item?(source, f.directory?)
|
86
|
+
|
87
|
+
target = Pathname(target.to_s.gsub('@','') % binding_params)
|
88
|
+
if f.directory?
|
89
|
+
do_folder_template target
|
90
|
+
else
|
91
|
+
do_file_template(source, target)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def binding_params
|
97
|
+
return @binding_params if @binding_params
|
98
|
+
@binding_params = {app_name: self.class.get_app_name}
|
99
|
+
options.each do |k, v|
|
100
|
+
@binding_params[k.to_sym] = v
|
101
|
+
end
|
102
|
+
self.class.arguments.each do |arg|
|
103
|
+
@binding_params[arg.name.to_sym] = self.send(arg.name)
|
104
|
+
end
|
105
|
+
@binding_params
|
106
|
+
end
|
107
|
+
|
108
|
+
def do_invoke(*names, &block)
|
109
|
+
propagate_thor_runtime_options(*names)
|
110
|
+
klass = names[0]
|
111
|
+
klass.output_folder = self.class.output_folder
|
112
|
+
invoke(*names, &block)
|
113
|
+
end
|
114
|
+
|
115
|
+
def propagate_thor_runtime_options(*names)
|
116
|
+
names[2] ||= {} # ensure we have options hash
|
117
|
+
%w(force pretend quiet skip).each do |rt_opt|
|
118
|
+
names[2][rt_opt] = options[rt_opt] if options.has_key?(rt_opt)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
@@ -21,7 +21,8 @@ class Delphivm
|
|
21
21
|
'D100' => {regkey: 'Software\Borland\BDS\4.0', name: '2006', desc: 'Borland Developer Stuido 4.0'},
|
22
22
|
'D150' => {regkey: 'Software\Embarcadero\BDS\8.0', name: 'XE', desc: 'Embarcadero RAD Stuido XE'},
|
23
23
|
'D160' => {regkey: 'Software\Embarcadero\BDS\9.0', name: 'XE2', desc: 'Embarcadero RAD Stuido XE2'},
|
24
|
-
|
24
|
+
'D170' => {regkey: 'Software\Embarcadero\BDS\10.0', name: 'XE3', desc: 'Embarcadero RAD Stuido XE3'},
|
25
|
+
'D180' => {regkey: 'Software\Embarcadero\BDS\11.0', name: 'XE4', desc: 'Embarcadero RAD Stuido XE4'}
|
25
26
|
}
|
26
27
|
|
27
28
|
def self.idelist
|
@@ -30,6 +31,10 @@ class Delphivm
|
|
30
31
|
result.sort.reverse
|
31
32
|
end
|
32
33
|
|
34
|
+
def self.default_ide
|
35
|
+
self.idelist.first
|
36
|
+
end
|
37
|
+
|
33
38
|
def self.ideused
|
34
39
|
#TODO ensure we return only ides listed at IDEInfos
|
35
40
|
ROOT.glob("{src,samples}/**/*.{#{GROUP_FILE_EXT.join(',')}}").map {|f| f.dirname.basename.to_s.split('-')[0]}.uniq.sort
|
@@ -44,7 +49,7 @@ class Delphivm
|
|
44
49
|
new_path = ide_paths(ide_tag.upcase).map{ |p| p + 'bin' }.first
|
45
50
|
path.unshift new_path
|
46
51
|
path = path.join(';')
|
47
|
-
self.winpath= path
|
52
|
+
self.winpath = path
|
48
53
|
return new_path
|
49
54
|
end
|
50
55
|
|
@@ -59,7 +64,7 @@ class Delphivm
|
|
59
64
|
end
|
60
65
|
|
61
66
|
def set_env
|
62
|
-
ENV["PATH"] =
|
67
|
+
ENV["PATH"] = '$(BDSCOMMONDIR)\bpl;' + ENV["PATH"]
|
63
68
|
ENV["PATH"] = self['RootDir'] + 'bin;' + ENV["PATH"]
|
64
69
|
ENV["BDSPROJECTGROUPDIR"] = workdir.win
|
65
70
|
ENV["IDEVERSION"] = idever
|