Mxx_ru 1.6.7.1 → 1.6.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b65c551e624ecad29a513d7af93989985acb4455
4
- data.tar.gz: ce616be948582f09e650fa28feeb76dc54035914
3
+ metadata.gz: 73efa525294417a45416e080580599b7ddc46c74
4
+ data.tar.gz: e76fb9f6de5eeff271e0a6596fa8059cfcf45ac0
5
5
  SHA512:
6
- metadata.gz: c454658a0f9b740e0da247913482674c2cc83f50b9179afc10274fc403c959b7b02192d7c9659be94dfb6f9251fd5654e72e4f4216c11b0e759c10fd819f04b8
7
- data.tar.gz: fbedcdc011c11cfd9f244807ca3b7c7c76edd012c16146475a7a4febdc4a55a5a4e001160f37381d457b1d9139bba549611c74a120298fd40b6ac16d83bb59cb
6
+ metadata.gz: fd8d76c2e95b1feabb5905c9fea9b022c0260426d01c603a98bedd662831dbbc91ad64930361196378b63729e8d754f55b638ae098afd108a094bf3e96248a44
7
+ data.tar.gz: 443864dbe6a9927c2fda510dcd5aac15e67354f226ad1add2cf42cf290a02ac1739aebd8ef7c4f7a8dc52b24d289c6bab269d279acfecfba62f9b241b8901b55
data/Rakefile CHANGED
@@ -10,11 +10,14 @@ require 'lib/mxx_ru/version'
10
10
  spec = Gem::Specification.new do |s|
11
11
  s.name = "Mxx_ru"
12
12
  s.version = MXX_RU_VERSION
13
+ s.licenses = ['NewBSD']
13
14
  s.author = "The Mxx_ru Project"
14
15
  s.email = "eao197@yahoo.com"
15
16
  s.homepage = "http://sourceforge.net/projects/mxxru"
16
17
  s.platform = Gem::Platform::RUBY
17
18
  s.summary = "Mxx_ru (Make++ on Ruby) is a cross-platform build tool"
19
+ s.description = "Mxx_ru is a cross-platform build tool primarily focused " +
20
+ "to C/C++ projects"
18
21
  s.files = FileList[ "{bin,tests,lib,docs,examples}/**/*" ].
19
22
  exclude( "rdoc" ).to_a + [ "THANKS" ]
20
23
  s.executables = 'mxxrugen'
@@ -1,10 +1,166 @@
1
1
  require 'rake'
2
2
  require 'rake/tasklib'
3
3
 
4
+ require 'uri'
5
+ require 'singleton'
6
+
7
+ require 'digest'
8
+
4
9
  module MxxRu
5
10
 
6
11
  module Externals
7
12
 
13
+ module Impl
14
+
15
+ module Utils
16
+ # Return nil if tool not found.
17
+ # Return version if tool is found.
18
+ def Utils.external_tool_version_probe(cmd_line, version_re)
19
+ ver = nil
20
+ IO.popen(cmd_line, :err => [:child, :out]).grep(version_re) do |s|
21
+ ver = version_re.match(s)[1]
22
+ end
23
+ ver
24
+ rescue
25
+ nil
26
+ end
27
+ end # module Utils
28
+
29
+ module OptionsHolder
30
+ def option(*values)
31
+ make_options.push(*values)
32
+ end
33
+
34
+ protected
35
+
36
+ def push_options_to(receiver)
37
+ receiver.push(*@options)
38
+ end
39
+
40
+ private
41
+
42
+ def make_options
43
+ @options = [] unless @options
44
+ @options
45
+ end
46
+ end # module OptionsHolder
47
+
48
+ class CurlDownloder
49
+ include OptionsHolder
50
+
51
+ def CurlDownloder.check_presence
52
+ Utils.external_tool_version_probe('curl --version', /^curl\s(\S+)\s/)
53
+ end
54
+
55
+ def CurlDownloder.downloader_id
56
+ :curl
57
+ end
58
+
59
+ def initialize(options)
60
+ @options = options
61
+ end
62
+
63
+ def make_download_sh_args(uri, result_name)
64
+ push_options_to(['curl', '-L']).push('-o', result_name, uri)
65
+ end
66
+ end
67
+
68
+ class WgetDownloder
69
+ include OptionsHolder
70
+
71
+ def WgetDownloder.check_presence
72
+ Utils.external_tool_version_probe('wget --version', /^GNU Wget\s(\S+)\s/)
73
+ end
74
+
75
+ def WgetDownloder.downloader_id
76
+ :wget
77
+ end
78
+
79
+ def initialize(options)
80
+ @options = options
81
+ end
82
+
83
+ def make_download_sh_args(uri, result_name)
84
+ push_options_to(['wget']).push('-O', result_name, uri)
85
+ end
86
+ end
87
+
88
+ module WebDownloaderOptions
89
+ def downloader_option(downloader_id, *values)
90
+ downloader_option_storage()[downloader_id].push(*values)
91
+ end
92
+
93
+ def downloader_options_for(downloader_id)
94
+ downloader_option_storage()[downloader_id]
95
+ end
96
+
97
+ def all_downloader_options
98
+ downloader_option_storage
99
+ end
100
+
101
+ private
102
+ def downloader_option_storage
103
+ @downloader_options = Hash.new{|h,k| h[k] = []} unless @downloader_options
104
+ @downloader_options
105
+ end
106
+ end
107
+
108
+ class WebDownloader
109
+ include Singleton
110
+ SUPPORTED_DOWNLOADERS = [WgetDownloder, CurlDownloder]
111
+
112
+ @@preffered_downloaders = []
113
+ @@downloader_options = Hash.new{|h,k| h[k] = []}
114
+
115
+ def initialize
116
+ @downloader_type, @downloader_version = *detect_downloader_type
117
+
118
+ if Rake.verbose
119
+ puts "#{@downloader_type.downloader_id} v.#{@downloader_version} found"
120
+ end
121
+ end
122
+
123
+ def make_downloader(options_holder)
124
+ id = @downloader_type.downloader_id
125
+ @downloader_type.new(
126
+ merge_options(
127
+ options_holder.downloader_options_for(id),
128
+ @@downloader_options[id]))
129
+ end
130
+
131
+ def WebDownloader.preffered_downloader(downloader_id)
132
+ found = SUPPORTED_DOWNLOADERS.find do |klass|
133
+ downloader_id == klass.downloader_id ? klass : nil
134
+ end
135
+ raise "Unsupported downloader: #{downloader_id}" unless found
136
+
137
+ @@preffered_downloaders.push(found)
138
+ end
139
+
140
+ def WebDownloader.downloader_option(downloader_id, *values)
141
+ @@downloader_options[downloader_id].push(*values)
142
+ end
143
+
144
+ private
145
+ def detect_downloader_type
146
+ r = search_downloader_in(@@preffered_downloaders)
147
+ r = search_downloader_in(SUPPORTED_DOWNLOADERS) unless r
148
+ raise "No web downloader found (curl, wget)" unless r
149
+ r
150
+ end
151
+
152
+ def search_downloader_in(sequence)
153
+ version = nil
154
+ downloader = sequence.find {|klass| version = klass.check_presence}
155
+ downloader ? [downloader, version] : nil
156
+ end
157
+
158
+ def merge_options(head, tail)
159
+ r = head.dup
160
+ r.push(*tail)
161
+ end
162
+ end # class WebDownloader
163
+
8
164
  module ExternalBasics
9
165
  EXTERNALS_STORAGE_DIR = '.externals'
10
166
 
@@ -29,15 +185,11 @@ module ExternalBasics
29
185
  alias :map :map_dir
30
186
 
31
187
  def map_file(value)
32
- raise "map() value must be a Hash" unless value.is_a?(Hash)
188
+ raise "map_file() value must be a Hash" unless value.is_a?(Hash)
33
189
 
34
190
  @files.merge!(value)
35
191
  end
36
192
 
37
- def option(*values)
38
- @options.push(*values)
39
- end
40
-
41
193
  private
42
194
 
43
195
  def defaults(name)
@@ -46,7 +198,6 @@ private
46
198
  @reget_task_name = "#{@name}:reget"
47
199
  @paths = {}
48
200
  @files = {}
49
- @options = []
50
201
  @verbose = Rake.verbose
51
202
  end
52
203
 
@@ -87,20 +238,17 @@ private
87
238
  "#{prefixes.join('.')}.#{Process.pid}.#{Thread.current.object_id}"
88
239
  end
89
240
 
90
- def add_options(receiver)
91
- receiver.push(*@options)
92
- end
93
-
94
- def define(src_type, &exporter)
241
+ def define(&exporter)
95
242
  ensure_basics_correctness(@name)
96
243
 
97
- ext_prj_sources_dir, dir_subtargets, file_subtargets = define_basic_task(src_type, &exporter)
244
+ ext_prj_sources_dir, dir_subtargets, file_subtargets =
245
+ define_basic_task(&exporter)
98
246
 
99
247
  define_remove_task(ext_prj_sources_dir, dir_subtargets, file_subtargets)
100
248
  define_reget_task(ext_prj_sources_dir, dir_subtargets, file_subtargets)
101
249
  end
102
250
 
103
- def define_basic_task(src_type, &exporter)
251
+ def define_basic_task(&exporter)
104
252
  ext_prj_sources_dir = subdir_name(@name.to_s)
105
253
 
106
254
  directory EXTERNALS_STORAGE_DIR
@@ -135,7 +283,7 @@ private
135
283
  rm_directories(dir_subtargets)
136
284
  rm_files(file_subtargets)
137
285
 
138
- ext_prj_sources_tmp_dir = subdir_name(make_tmp_name src_type, @name)
286
+ ext_prj_sources_tmp_dir = subdir_name(make_tmp_name(@name))
139
287
  exporter.call(ext_prj_sources_tmp_dir)
140
288
  mv(ext_prj_sources_tmp_dir, ext_prj_sources_dir, fileop_options)
141
289
  end
@@ -167,8 +315,11 @@ private
167
315
  end
168
316
  end
169
317
 
318
+ end # module Impl
319
+
170
320
  class Svn < Rake::TaskLib
171
- include ExternalBasics
321
+ include Impl::ExternalBasics
322
+ include Impl::OptionsHolder
172
323
 
173
324
  def initialize(name)
174
325
  defaults(name)
@@ -176,12 +327,12 @@ class Svn < Rake::TaskLib
176
327
 
177
328
  yield self if block_given?
178
329
 
179
- define 'svn' do |tmp_dir|
330
+ define do |tmp_dir|
180
331
  sh_args = [ 'svn', 'export' ]
181
332
 
182
333
  sh_args << '-r' << @rev.to_s if @rev
183
334
  sh_args << '--ignore-externals' unless @with_externals
184
- add_options(sh_args)
335
+ push_options_to(sh_args)
185
336
 
186
337
  sh_args << @url << tmp_dir
187
338
 
@@ -199,7 +350,8 @@ class Svn < Rake::TaskLib
199
350
  end
200
351
 
201
352
  class Git < Rake::TaskLib
202
- include ExternalBasics
353
+ include Impl::ExternalBasics
354
+ include Impl::OptionsHolder
203
355
 
204
356
  def initialize(name)
205
357
  defaults(name)
@@ -208,17 +360,34 @@ class Git < Rake::TaskLib
208
360
 
209
361
  yield self if block_given?
210
362
 
211
- define 'git' do |tmp_dir|
212
- sh_args = ['git', 'clone']
213
-
214
- sh_args << '--branch' << @tag.to_s if @tag
215
- sh_args << '--depth' << '1' unless @unlimited_depth
216
- sh_args << '--recursive' if @recursive
217
- add_options(sh_args)
218
-
219
- sh_args << @url << tmp_dir
220
-
221
- sh *sh_args
363
+ raise "#{name}: tag and commit cannot be specified together" if @tag and @commit
364
+
365
+ define do |tmp_dir|
366
+ if @commit.nil?
367
+ # No specific commit.
368
+ # Simple clone (probably with --depth 1) is enough.
369
+ sh_args = ['git', 'clone']
370
+
371
+ sh_args << '--branch' << @tag.to_s if @tag
372
+ sh_args << '--depth' << '1' unless @unlimited_depth
373
+ sh_args << '--recursive' if @recursive
374
+ push_options_to(sh_args)
375
+
376
+ sh_args << @url << tmp_dir
377
+
378
+ sh *sh_args
379
+ else
380
+ # To extract specific commit is necessary to do
381
+ # at least two commands: clone (without limitiation of depth) and
382
+ # checkout for specific commit.
383
+
384
+ # Do `clone repo tmp_dir`
385
+ sh *(push_options_to(['git', 'clone']).push(@url).push(tmp_dir))
386
+ # Do `checkout commit` inside tmp_dir
387
+ cd tmp_dir do
388
+ sh 'git', 'checkout', @commit
389
+ end
390
+ end
222
391
  end
223
392
  end
224
393
 
@@ -233,21 +402,26 @@ class Git < Rake::TaskLib
233
402
  def recursive
234
403
  @recursive = true
235
404
  end
405
+
406
+ attr_reader :commit
407
+ def commit(v); @commit = v; end
408
+ alias :commit= :commit
236
409
  end
237
410
 
238
411
  class Hg < Rake::TaskLib
239
- include ExternalBasics
412
+ include Impl::ExternalBasics
413
+ include Impl::OptionsHolder
240
414
 
241
415
  def initialize(name)
242
416
  defaults(name)
243
417
 
244
418
  yield self if block_given?
245
419
 
246
- define 'hg' do |tmp_dir|
420
+ define do |tmp_dir|
247
421
  sh_args = ['hg', 'clone']
248
422
 
249
423
  sh_args << '--updaterev' << @tag.to_s if @tag
250
- add_options(sh_args)
424
+ push_options_to(sh_args)
251
425
 
252
426
  sh_args << @url << tmp_dir
253
427
 
@@ -258,6 +432,185 @@ class Hg < Rake::TaskLib
258
432
  attr_reader :tag
259
433
  def tag(v); @tag = v; end
260
434
  alias :tag= :tag
435
+ end # class Hg
436
+
437
+ # Implementation of externals represented as downloadable
438
+ # archive (like tar.gz, zip, rar or 7z).
439
+ #
440
+ class ArchiveAsExternals < Rake::TaskLib
441
+ include Impl::ExternalBasics
442
+ include Impl::WebDownloaderOptions
443
+
444
+ @@archive_handlers = {
445
+ :tar => proc {
446
+ ['tar', 'x'].push(*@unpaker_options).push('-f').push(archive_name)
447
+ },
448
+ :zip => proc {
449
+ ['unzip'].push(*@unpaker_options).push(archive_name)
450
+ },
451
+ :sevenzip => proc {
452
+ ['7z', 'x'].push(*@unpaker_options).push(archive_name)
453
+ }
454
+ }
455
+
456
+ @@archive_extensions = {
457
+ '.tar' => :tar,
458
+ '.tar.gz' => :tar,
459
+ '.tgz' => :tar,
460
+ '.taz' => :tar,
461
+ '.tar.Z' => :tar,
462
+ '.taZ' => :tar,
463
+ '.tar.bz2' => :tar,
464
+ '.tz2' => :tar,
465
+ '.tbz2' => :tar,
466
+ '.tar.lz' => :tar,
467
+ '.tar.lzma' => :tar,
468
+ '.tlz' => :tar,
469
+ '.tar.lzo' => :tar,
470
+ '.tar.xz' => :tar,
471
+ '.zip' => :zip,
472
+ '.7z' => :sevenzip
473
+ }
474
+
475
+ def initialize(name)
476
+ defaults(name)
477
+ @unpaker_options = []
478
+
479
+ yield self if block_given?
480
+
481
+ parse_uri
482
+ detect_archive_type
483
+
484
+ define do |tmp_dir|
485
+ # Temporary directory must be removed in a case of any error.
486
+ successful = false
487
+ begin
488
+ mkdir(tmp_dir, fileop_options) if !Dir.exists?(tmp_dir)
489
+
490
+ cd tmp_dir do
491
+ download_archive
492
+ unpack_archive
493
+ end
494
+
495
+ successful = true
496
+ ensure
497
+ rm_dir_if_exists(tmp_dir) unless successful
498
+ end
499
+ end
500
+ end
501
+
502
+ def md5(v)
503
+ @md5 = v
504
+ end
505
+
506
+ def sha1(v)
507
+ @sha1 = v
508
+ end
509
+
510
+ def sha256(v)
511
+ @sha256 = v
512
+ end
513
+
514
+ def sha512(v)
515
+ @sha512 = v
516
+ end
517
+
518
+ def unpacker_option(v)
519
+ @unpaker_options.push(v)
520
+ end
521
+
522
+ private
523
+ def parse_uri
524
+ @parsed_uri = URI::split(@url)
525
+ @archive_name = File.split(uri_path).last
526
+ end
527
+
528
+ def uri_scheme
529
+ @parsed_uri[0]
530
+ end
531
+
532
+ def uri_path
533
+ @parsed_uri[5] # See doc for URI::split for description
534
+ # of items in result vector.
535
+ end
536
+
537
+ attr_reader :archive_name
538
+
539
+ def detect_archive_type
540
+ ext = @@archive_extensions.keys.find {|k| @archive_name.end_with?(k)}
541
+ raise "#{name} unable to detect archive type for " +
542
+ "#{@archive_name}" unless ext
543
+
544
+ @archive_type = @@archive_extensions[ext]
545
+ end
546
+
547
+ def download_archive
548
+ if 'file' == uri_scheme
549
+ download_archive_via_cp
550
+ else
551
+ download_archive_from_web
552
+ end
553
+ check_digest_if_necessary(:MD5, @md5)
554
+ check_digest_if_necessary(:SHA1, @sha1)
555
+ check_digest_if_necessary(:SHA256, @sha256)
556
+ check_digest_if_necessary(:SHA512, @sha512)
557
+ end
558
+
559
+ def download_archive_from_web
560
+ web_downloader = Impl::WebDownloader.instance.make_downloader(self)
561
+ sh *(web_downloader.make_download_sh_args(@url, archive_name))
562
+ end
563
+
564
+ def download_archive_via_cp
565
+ # On Windows path can look like '/d:/...'.
566
+ # The leading slash must be removed.
567
+ path = uri_path.gsub(/^(\/)(\w:)(.+)$/, '\2\3')
568
+ cp(path, archive_name, fileop_options)
569
+ end
570
+
571
+ def unpack_archive
572
+ sh(*make_unpacker_args)
573
+ rm(archive_name, fileop_options)
574
+ names = Dir['*']
575
+ if 1 == names.size and Dir.exists?(names.first)
576
+ # This is the only folder in the distributive.
577
+ # Move all its contents one level up.
578
+ cd names.first do
579
+ # Files like '.gitignore' won't be found without FNM_DOTMATCH.
580
+ # But in that case '.' and '..' will be found too.
581
+ Dir.glob('*', File::FNM_DOTMATCH).each do |n|
582
+ mv(n, '..', fileop_options) if n != '.' && n != '..'
583
+ end
584
+ end
585
+ # This single directory no more needed.
586
+ rm_r(names.first, fileop_options)
587
+ end
588
+ end
589
+
590
+ def check_digest_if_necessary(digest_id, expected)
591
+ return unless expected
592
+
593
+ digest_klass = Digest(digest_id)
594
+ puts "#{archive_name} checking #{digest_id} checksum..." if @verbose
595
+ chsum = digest_klass.file(archive_name).hexdigest
596
+ if chsum != expected
597
+ raise "#{archive_name}: #{digest_id} checksum missmatch. " +
598
+ "actual: #{chsum}, expected: #{expected}"
599
+ end
600
+ end
601
+
602
+ def make_unpacker_args
603
+ handler = @@archive_handlers[@archive_type]
604
+ self.instance_eval &handler
605
+ end
606
+ end # class ArchiveAsExternals
607
+
608
+ def Externals::preffered_downloader(downloader_id)
609
+ Impl::WebDownloader.preffered_downloader(downloader_id)
610
+ end
611
+
612
+ def Externals::downloader_option(downloader_id, *values)
613
+ Impl::WebDownloader.downloader_option(downloader_id, *values)
261
614
  end
262
615
 
263
616
  end # module Externals
@@ -274,16 +627,25 @@ def MxxRu.hg_externals(name, &block)
274
627
  Externals::Hg.new(name, &block)
275
628
  end
276
629
 
630
+ def MxxRu.arch_externals(name, &block)
631
+ Externals::ArchiveAsExternals.new(name, &block)
632
+ end
633
+
277
634
  end # module MxxRu
278
635
 
279
636
  desc "Remove all external projects"
280
637
  task :remove do
281
- d = MxxRu::Externals::ExternalBasics::EXTERNALS_STORAGE_DIR
638
+ d = MxxRu::Externals::Impl::ExternalBasics::EXTERNALS_STORAGE_DIR
282
639
  rm_r(d, :verbose => Rake.verbose) if Dir.exists?(d)
283
640
  end
284
641
 
285
642
  desc "Remove and get again all external projects"
286
643
  task :reget
287
644
 
645
+ local_rc_file = File.join(Dir.getwd, '.externalsrc')
646
+ if File.exists?(local_rc_file)
647
+ load local_rc_file
648
+ end
649
+
288
650
  # vim:ts=2:sts=2:sw=2:expandtab
289
651
 
@@ -34,4 +34,4 @@
34
34
  #
35
35
  # puts 'Mxx_ru version is: ' + MXX_RU_VERSION
36
36
  #
37
- MXX_RU_VERSION = '1.6.7.1'
37
+ MXX_RU_VERSION = '1.6.8'
@@ -0,0 +1,13 @@
1
+ require 'mxx_ru/externals'
2
+
3
+ MxxRu::arch_externals :asio_tgz do |e|
4
+ e.url 'https://github.com/chriskohlhoff/asio/archive/asio-1-11-0.tar.gz'
5
+ e.sha1 '1be2489015a1e1c7b8666a5a803d984cdec4a12b'
6
+
7
+ e.map 'asio/src' => 'dev/asio_tgz'
8
+
9
+ e.downloader_option :wget, '--no-use-server-timestamps'
10
+ e.downloader_option :wget, '-T', '36'
11
+
12
+ e.downloader_option :curl, '--max-time', '3600'
13
+ end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Mxx_ru
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.7.1
4
+ version: 1.6.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Mxx_ru Project
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-04 00:00:00.000000000 Z
11
+ date: 2016-03-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description:
13
+ description: Mxx_ru is a cross-platform build tool primarily focused to C/C++ projects
14
14
  email: eao197@yahoo.com
15
15
  executables:
16
16
  - mxxrugen
@@ -217,6 +217,7 @@ files:
217
217
  - tests/externals/check_git.rb
218
218
  - tests/externals/check_hg.rb
219
219
  - tests/externals/check_svn.rb
220
+ - tests/externals/check_tar.rb
220
221
  - tests/mxx_ru/binary_library/tc_binary_library.rb
221
222
  - tests/mxx_ru/binary_library/tc_binary_target_lib_methods.rb
222
223
  - tests/mxx_ru/change_default_value/ignoring_by_build_root/build.rb
@@ -348,7 +349,8 @@ files:
348
349
  - tests/unix/lib_order/main.rb
349
350
  - tests/unix/lib_order/tc_normal_build.rb
350
351
  homepage: http://sourceforge.net/projects/mxxru
351
- licenses: []
352
+ licenses:
353
+ - NewBSD
352
354
  metadata: {}
353
355
  post_install_message:
354
356
  rdoc_options: