rake-delphi 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile.rb +12 -0
  6. data/lib/rake/common/chdirtask.rb +21 -0
  7. data/lib/rake/common/classes.rb +15 -0
  8. data/lib/rake/common/dsl.rb +10 -0
  9. data/lib/rake/common/echotask.rb +34 -0
  10. data/lib/rake/common/exectask.rb +20 -0
  11. data/lib/rake/common/git.rb +102 -0
  12. data/lib/rake/common/hashtask.rb +43 -0
  13. data/lib/rake/common/initask.rb +31 -0
  14. data/lib/rake/common/libstask.rb +35 -0
  15. data/lib/rake/common/sendmailtask.rb +45 -0
  16. data/lib/rake/common/ziptask.rb +98 -0
  17. data/lib/rake/delphi/dcc32.rb +260 -0
  18. data/lib/rake/delphi/envvariables.rb +41 -0
  19. data/lib/rake/delphi/liblist.rb +29 -0
  20. data/lib/rake/delphi/project.rb +68 -0
  21. data/lib/rake/delphi/projectinfo.rb +76 -0
  22. data/lib/rake/delphi/rc.rb +25 -0
  23. data/lib/rake/delphi/resources.rb +126 -0
  24. data/lib/rake/delphi/tool.rb +140 -0
  25. data/lib/rake/delphi/version.rb +7 -0
  26. data/lib/rake/delphi.rb +4 -0
  27. data/lib/rake/helpers/digest.rb +28 -0
  28. data/lib/rake/helpers/file.rb +35 -0
  29. data/lib/rake/helpers/filelist.rb +12 -0
  30. data/lib/rake/helpers/gemversion.rb +42 -0
  31. data/lib/rake/helpers/logger.rb +15 -0
  32. data/lib/rake/helpers/rake.rb +29 -0
  33. data/lib/rake/helpers/raketask.rb +39 -0
  34. data/lib/rake/helpers/string.rb +10 -0
  35. data/lib/rake/helpers/unittest.rb +17 -0
  36. data/lib/rake/templates/project.erb +60 -0
  37. data/rake-delphi.gemspec +23 -0
  38. data/test/helpers/consts.rb +4 -0
  39. data/test/resources/FakeDelphi/dcc32.exe +0 -0
  40. data/test/resources/FakeDelphi/rc.exe +0 -0
  41. data/test/resources/echo/file.in +1 -0
  42. data/test/resources/echo/file.out +1 -0
  43. data/test/resources/hashes/hash.2.file +1 -0
  44. data/test/resources/hashes/hash.file +1 -0
  45. data/test/resources/ini/file.ini +7 -0
  46. data/test/resources/libstask/lib/level-1/level-2-1/level-3-1/.gitkeep +0 -0
  47. data/test/resources/libstask/lib/level-1/level-2-1/level-3-2/.gitkeep +0 -0
  48. data/test/resources/libstask/lib/level-1/level-2-2/.gitkeep +0 -0
  49. data/test/resources/testproject/.gitignore +8 -0
  50. data/test/resources/testproject/ExplicitLib/ExplicitLibUnit.pas +17 -0
  51. data/test/resources/testproject/Rakefile.rb +54 -0
  52. data/test/resources/testproject/lib/AnyLib/LibUnit.pas +17 -0
  53. data/test/resources/testproject/local.resources.txt +1 -0
  54. data/test/resources/testproject/release.dcc.cfg +1 -0
  55. data/test/resources/testproject/resources.rc +1 -0
  56. data/test/resources/testproject/testproject.bdsproj +175 -0
  57. data/test/resources/testproject/testproject.cfg +39 -0
  58. data/test/resources/testproject/testproject.dpr +78 -0
  59. data/test/resources/testproject/testproject.dproj +77 -0
  60. data/test/resources/testproject/testproject.ico +0 -0
  61. data/test/test-delphi.rb +166 -0
  62. data/test/test-echo.rb +33 -0
  63. data/test/test-gemversion.rb +61 -0
  64. data/test/test-git.rb +144 -0
  65. data/test/test-hashes.rb +57 -0
  66. data/test/test-ini.rb +18 -0
  67. data/test/test-libstask.rb +54 -0
  68. data/test/test-projectinfo.rb +66 -0
  69. data/test/test-zip.rb +43 -0
  70. metadata +179 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rake-delphi.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Alexey Shumkin
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Rake::Delphi
2
+
3
+ This gem adds an ability to compile automatically Delphi projects
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rake-delphi'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rake-delphi
18
+
19
+ ## Usage
20
+
21
+
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile.rb ADDED
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ task :default => :test
7
+
8
+ Rake::TestTask.new('test') do |t|
9
+ t.ruby_opts << '-d' if Rake.application.options.trace
10
+ t.libs << 'test'
11
+ t.verbose = true
12
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rake/common/classes'
4
+
5
+ module Rake
6
+ module Delphi
7
+ class ChDir < BasicTask
8
+ def initialize(task, dir)
9
+ super(task)
10
+ return unless block_given?
11
+ od = Dir.pwd
12
+ begin
13
+ Dir.chdir(dir)
14
+ yield dir
15
+ ensure
16
+ Dir.chdir(od)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module Rake
4
+ module Delphi
5
+ class BasicTask
6
+ def initialize(task)
7
+ @task = task
8
+ end
9
+
10
+ def trace?
11
+ @task.application.options.trace || $DEBUG || false
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ # include this file
4
+ # to avoid errors like 'uninitialized constant Rake::DSL'
5
+ # on rake > v0.8.7
6
+ if RAKEVERSION !~ /^0\.8/
7
+ require 'rake/dsl_definition'
8
+ include Rake::DSL
9
+ Rake::TaskManager.record_task_metadata = true if Rake::TaskManager.respond_to?('record_task_metadata')
10
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ require 'fileutils'
4
+ require 'rake/common/classes'
5
+ require 'rake/helpers/raketask'
6
+
7
+ module Rake
8
+ module Delphi
9
+ class EchoToFile < BasicTask
10
+ def initialize(task, ifile, ofile, vars)
11
+ super(task)
12
+ @task.out "#{ifile} -> #{ofile}"
13
+ FileUtils.mkdir_p(File.dirname(ofile))
14
+ File.open(ifile, 'r') do |f|
15
+ File.open(ofile, 'w') do |w|
16
+ while (line = f.gets)
17
+ # replace ${var1.var2.var3} with its value from xml
18
+ line.gsub!(/\$\{(.+?)\}/) do |match|
19
+ val = nil
20
+ $1.split(".").each do |part|
21
+ val = val.nil? ? vars[part] : val[part]
22
+ end
23
+ match = val.nil? ? match : val
24
+ end if vars
25
+ w.puts line
26
+ end
27
+ w.close
28
+ end
29
+ f.close
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rake/common/classes'
4
+
5
+ module Rake
6
+ module Delphi
7
+
8
+ class CustomExec < BasicTask
9
+ public
10
+ def execute
11
+ end
12
+
13
+ def to_system_path(path, base = '')
14
+ r = super(path, base)
15
+ # quote path if it contains SPACE
16
+ r = '"%s"' % r.strip if r[" "]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rake/common/classes'
4
+ require 'rake/helpers/rake'
5
+
6
+ module Rake
7
+ module Delphi
8
+ class Git
9
+ def self.version
10
+ null = Rake.cygwin? ? '/dev/null' : 'nul'
11
+ r = `git rev-parse 1>#{null} 2>&1 && git describe --abbrev=1 2>#{null}`
12
+ # trim
13
+ r.chomp!
14
+ unless r.to_s.empty?
15
+ # add ".0" for exact version (like v3.0.43)
16
+ # example: v3.0.43-5-g3952dc
17
+ # take text before '-g'
18
+ r << '.0'
19
+ r = r.split('-g')[0]
20
+ # remove any non-digits in the beginning
21
+ # remove any alpha-characters
22
+ r.gsub!(/^\D+|[a-zA-Z]+/, '')
23
+ # replace any non-digits with dots
24
+ r.gsub!(/\D/, '.')
25
+ end
26
+ end
27
+ end
28
+
29
+ class GitChangelog < BasicTask
30
+
31
+ attr_reader :opts, :changelog, :processed
32
+
33
+ def initialize(task, opts)
34
+ super(task)
35
+ @opts = {:filter => '.'}
36
+ @opts.merge!(opts) if opts.kind_of?(Hash)
37
+ @changelog = @processed = []
38
+ get_changelog
39
+ yield self if block_given?
40
+ end
41
+
42
+ def processed_string
43
+ @processed.join("\n")
44
+ end
45
+
46
+ def changelog_string
47
+ @changelog.join("\n")
48
+ end
49
+
50
+ private
51
+ def get_changelog
52
+ cmd = ['git']
53
+ cmd << "-c i18n.logOutputEncoding=#{opts[:logoutputencoding]}" if opts[:logoutputencoding]
54
+ cmd << 'log' << '--format=%B' << "#{opts[:since]}..HEAD"
55
+ p cmd if trace?
56
+ @changelog=%x[#{cmd.join(' ')}].lines.to_a
57
+ @changelog.map! do |line|
58
+ line.chomp!
59
+ if line.respond_to?(:force_encoding) \
60
+ && opts[:logoutputencoding]
61
+ line.force_encoding(opts[:logoutputencoding])
62
+ end
63
+ line
64
+ end
65
+
66
+ # delete empty lines
67
+ @changelog.delete_if { |line| line.chomp.empty? }
68
+ # unique lines only
69
+ @changelog.uniq!
70
+ do_filter
71
+ do_process
72
+ puts @changelog if trace?
73
+ end
74
+
75
+ def charset
76
+ opts[:logoutputencoding]
77
+ end
78
+
79
+ def do_filter
80
+ @filter = Regexp.new(@opts[:filter])
81
+ @changelog.delete_if { |line| ! @filter.match(line) }
82
+ end
83
+
84
+ def do_process
85
+ @processed = []
86
+ return unless @opts[:process] && @opts[:process].size > 0
87
+ @processed = @changelog.map do |line|
88
+ line = line.dup
89
+ process = @opts[:process]
90
+ process = [process] unless process.kind_of?(Array)
91
+ process.each do |filters|
92
+ raise "`%s` must be a Hash" % [filters] unless filters.kind_of?(Hash)
93
+ filters.each do |filter, subst|
94
+ line.gsub!(filter, subst)
95
+ end
96
+ end
97
+ line
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rake/common/classes'
4
+ require 'rake/helpers/digest'
5
+
6
+ module Rake
7
+ module Delphi
8
+ class HashTask < BasicTask
9
+ def initialize(file, alg)
10
+ @file = file
11
+ @alg = alg
12
+ end
13
+
14
+ def digest
15
+ if ['md5', 'sha1'].include?(@alg)
16
+ require 'digest/' + @alg
17
+ return eval("Digest::#{@alg.upcase}.file(@file).hexdigest.upcase")
18
+ else
19
+ return "%02X" % Digest::CRC32.file(@file).digest.to_i
20
+ end
21
+ end
22
+ end
23
+
24
+ class HashesTask < BasicTask
25
+ def initialize(task, files, alg)
26
+ super(task)
27
+ @hashes = {}
28
+ calc_hashes(files, alg)
29
+ end
30
+
31
+ def calc_hashes(files, alg)
32
+ files = [files] unless files.kind_of?(Array)
33
+ files.each do |f|
34
+ @hashes[f] = { alg.upcase => HashTask.new(f, alg).digest }
35
+ end
36
+ end
37
+
38
+ def to_hash
39
+ @hashes
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require 'inifile'
4
+ require 'rake/common/classes'
5
+
6
+ module Rake
7
+ module Delphi
8
+ class IniProperty < BasicTask
9
+ private
10
+ def self.parse(string)
11
+ dir = File.dirname(string)
12
+ file, section, valuename = string.gsub(dir, '').split(":")
13
+ file = dir + '/' + File.basename(file)
14
+ return file, section, valuename
15
+ end
16
+ public
17
+ def self.get(string)
18
+ file, section, valuename = parse(string)
19
+ ini = IniFile.load(file)
20
+ return ini[section][valuename]
21
+ end
22
+
23
+ def self.set(string, value)
24
+ file, section, valuename = parse(string)
25
+ ini = IniFile.load(file)
26
+ ini[section][valuename] = value
27
+ ini.write
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rake/common/classes'
4
+ require 'rake/delphi/liblist'
5
+
6
+ module Rake
7
+ module Delphi
8
+ class LibsTask < Rake::Task
9
+ attr_reader :libs
10
+
11
+ def initialize(name, app)
12
+ super
13
+ @original_dir = ENV['RAKE_DIR'] || Rake.original_dir
14
+ end
15
+
16
+ def self.define(name, app)
17
+ app.tasks.each do |t|
18
+ # if there is a task with a name like a searched one
19
+ return t if t.name.index(name)
20
+ end
21
+ # else - define a new task
22
+ app.define_task(LibsTask, name)
23
+ end
24
+
25
+ def libs_relative(level)
26
+ @libs.map { |d| d.gsub(@original_dir, '.' + '/..' * level)}
27
+ end
28
+
29
+ def execute(args = nil)
30
+ mask = @original_dir + '/lib/**/**'
31
+ @libs = LibList.new(mask)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rake/common/classes'
4
+ require 'rake/helpers/rake'
5
+
6
+ module Rake
7
+ module Delphi
8
+ class Sendmail < BasicTask
9
+
10
+ def initialize(task, opts)
11
+ super(task)
12
+ cmd = ''
13
+ predefined = { :from => '-f', :"from.full" => '-F', :extra => nil, :to => nil }
14
+ predefined.keys.sort{|a, b| a.to_s <=> b.to_s}.each do |k|
15
+ cmd += "#{predefined[k]} #{opts[k]} " if opts[k]
16
+ end
17
+ cmd = "#{sendmail} -i #{cmd}"
18
+ pp cmd if trace?
19
+ if @task.application.windows? && Rake.ruby18?
20
+ require 'win32/open3'
21
+ else
22
+ require 'open3'
23
+ end
24
+ Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
25
+ stdin.puts(opts[:text])
26
+ stdin.close
27
+ while s = stdout.gets
28
+ puts s
29
+ end
30
+ while s = stderr.gets
31
+ puts s
32
+ end
33
+ end
34
+ end
35
+
36
+ def sendmail
37
+ if @task.application.unix?
38
+ "sendmail"
39
+ else
40
+ ENV['SENDMAIL']
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,98 @@
1
+ # encoding: utf-8
2
+
3
+ require 'zlib'
4
+ require 'rake/common/classes'
5
+ require 'rake/helpers/raketask'
6
+
7
+ module Rake
8
+ module Delphi
9
+ class GZip < BasicTask
10
+ def initialize(task, params)
11
+ super(task)
12
+ if params.kind_of?(String)
13
+ gzip_file(params)
14
+ elsif params.kind_of?(Array)
15
+ params.each do |file|
16
+ gzip_file(file)
17
+ end
18
+ end
19
+ end
20
+
21
+ private
22
+ def gzip_file(file)
23
+ @task.out "GZip #{file} -> #{file}.gz"
24
+ sfile = File.open(file + '.gz', "w+b")
25
+ gzfile = Zlib::GzipWriter.wrap(sfile) do |gz|
26
+ File.open(file, "rb") do |f|
27
+ gz.mtime = File.mtime(file)
28
+ gz.orig_name = File.basename(file)
29
+ gz.write(f.read)
30
+ gz.close
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ class ZipTask < BasicTask
37
+ def initialize(task, zipfile, files, options = nil)
38
+ super(task)
39
+ pp [zipfile, files] if trace?
40
+ raise "zipfile name is not defined!" if zipfile.nil? || zipfile.empty?
41
+ @norubyzip = nil
42
+ @options = options || {}
43
+ begin
44
+ require 'zipruby'
45
+ rescue LoadError
46
+ begin
47
+ require 'zip/zip'
48
+ rescue LoadError
49
+ @norubyzip = true
50
+ end
51
+ end
52
+ raise "no ZIP library (nor zipruby nor rubyzip) found!" if @norubyzip
53
+ if defined? Zip::Archive
54
+ # zipruby used
55
+ $stderr.puts '`zipruby` gem is used' if trace?
56
+ Zip::Archive.open(zipfile, Zip::CREATE | Zip::TRUNC) do |z|
57
+ files.each do |f|
58
+ zip_addfile(z, f)
59
+ end
60
+ end
61
+ else
62
+ # work with rubyzip
63
+ $stderr.puts '`rubyzip` gem is used' if trace?
64
+ File.unlink(zipfile) if File.exists?(zipfile)
65
+ Zip.options[:continue_on_exists_proc] = true
66
+ Zip::ZipFile.open(zipfile, Zip::ZipFile::CREATE) do |z|
67
+ files.each do |f|
68
+ zip_addfile(z, f)
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ private
75
+ def zip_addfile(zipfile, file)
76
+ return if ! File.exists?(file)
77
+ filename = File.basename(file)
78
+ @task.out "Zipping #{file}..."
79
+ if defined? Zip::Archive
80
+ if @options[:preserve_paths]
81
+ if ! zipfile.locate_name(File.dirname(file))
82
+ zipfile.add_dir(File.dirname(file))
83
+ end
84
+ filename = file
85
+ end
86
+ zipfile.add_file(filename, file)
87
+ else
88
+ if @options[:preserve_paths]
89
+ dir = File.dirname(file)
90
+ # avoid "./<filename>" entries (instead of "<filename>")
91
+ filename = File.join(dir, filename) if dir != '.'
92
+ end
93
+ zipfile.add(filename, file)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end