delphivm 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|