easycompile 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +216 -0
  3. data/bin/easycompile +7 -0
  4. data/doc/DESIGN_DECISIONS.md +34 -0
  5. data/doc/README.gen +189 -0
  6. data/doc/todo/todo_for_the_easycompile_project.md +0 -0
  7. data/easycompile.gemspec +66 -0
  8. data/lib/easycompile/base/change_directory.rb +28 -0
  9. data/lib/easycompile/base/cmake.rb +53 -0
  10. data/lib/easycompile/base/colours.rb +88 -0
  11. data/lib/easycompile/base/commandline_arguments.rb +37 -0
  12. data/lib/easycompile/base/constants.rb +24 -0
  13. data/lib/easycompile/base/easycompile.rb +22 -0
  14. data/lib/easycompile/base/esystem.rb +59 -0
  15. data/lib/easycompile/base/gem.rb +35 -0
  16. data/lib/easycompile/base/help.rb +38 -0
  17. data/lib/easycompile/base/initialize.rb +33 -0
  18. data/lib/easycompile/base/menu.rb +140 -0
  19. data/lib/easycompile/base/meson_and_ninja.rb +36 -0
  20. data/lib/easycompile/base/misc.rb +1157 -0
  21. data/lib/easycompile/base/opn.rb +27 -0
  22. data/lib/easycompile/base/process_the_input.rb +107 -0
  23. data/lib/easycompile/base/remove.rb +77 -0
  24. data/lib/easycompile/base/reset.rb +140 -0
  25. data/lib/easycompile/base/run.rb +26 -0
  26. data/lib/easycompile/compile_as_appdir/compile_as_appdir.rb +45 -0
  27. data/lib/easycompile/constants/array_possible_archives.rb +45 -0
  28. data/lib/easycompile/constants/constants.rb +21 -0
  29. data/lib/easycompile/constants/file_and_directory_constants.rb +137 -0
  30. data/lib/easycompile/constants/misc.rb +23 -0
  31. data/lib/easycompile/constants/namespace.rb +16 -0
  32. data/lib/easycompile/constants/programs_directory.rb +46 -0
  33. data/lib/easycompile/easycompile/easycompile.rb +89 -0
  34. data/lib/easycompile/images/logo/EASYCOMPILE_LOGO.png +0 -0
  35. data/lib/easycompile/project/project.rb +29 -0
  36. data/lib/easycompile/requires/require_the_easycompile_project.rb +13 -0
  37. data/lib/easycompile/requires/require_the_toplevel_methods.rb +11 -0
  38. data/lib/easycompile/toplevel_methods/copy_file.rb +23 -0
  39. data/lib/easycompile/toplevel_methods/misc.rb +54 -0
  40. data/lib/easycompile/toplevel_methods/rinstall2.rb +29 -0
  41. data/lib/easycompile/version/version.rb +26 -0
  42. data/lib/easycompile/yaml/name_of_the_build_directory.yml +1 -0
  43. data/lib/easycompile.rb +5 -0
  44. data/test/testing_easycompile.rb +29 -0
  45. metadata +147 -0
@@ -0,0 +1,1157 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # require 'easycompile/base/misc.rb'
6
+ # =========================================================================== #
7
+ require 'easycompile/constants/array_possible_archives.rb'
8
+ require 'easycompile/base/change_directory.rb'
9
+ require 'easycompile/base/colours.rb'
10
+ require 'easycompile/base/cmake.rb'
11
+ require 'easycompile/base/commandline_arguments.rb'
12
+ require 'easycompile/base/help.rb'
13
+ require 'easycompile/base/opn.rb'
14
+ require 'easycompile/base/process_the_input.rb'
15
+ require 'easycompile/base/remove.rb'
16
+
17
+ module Easycompile
18
+
19
+ class Base
20
+
21
+ begin
22
+ require 'program_information'
23
+ rescue LoadError; end
24
+
25
+ # ========================================================================= #
26
+ # === return_pwd
27
+ # ========================================================================= #
28
+ def return_pwd
29
+ ("#{Dir.pwd}/").squeeze '/'
30
+ end
31
+
32
+ # ========================================================================= #
33
+ # === set_find_this_program
34
+ #
35
+ # This will store e. g. "php", so that we can designate to work on
36
+ # a particular program, and pass this information to external
37
+ # programs if necessary.
38
+ # ========================================================================= #
39
+ def set_find_this_program(i)
40
+ @find_this_program = i
41
+ end
42
+
43
+ # ========================================================================= #
44
+ # === rds
45
+ # ========================================================================= #
46
+ def rds(i)
47
+ i.squeeze('/')
48
+ end
49
+
50
+ # ========================================================================= #
51
+ # === find_this_program?
52
+ # ========================================================================= #
53
+ def find_this_program?
54
+ @find_this_program
55
+ end; alias find_which_program? find_this_program? # === find_which_program?
56
+
57
+ # ========================================================================= #
58
+ # === run_rinstall2
59
+ # ========================================================================= #
60
+ def run_rinstall2
61
+ copy_setup_rb
62
+ internal_system 'ruby setup.rb config'
63
+ internal_system 'ruby setup.rb setup'
64
+ internal_system 'ruby setup.rb install'
65
+ internal_system 'rm setup.rb'
66
+ internal_system 'rm InstalledFiles'
67
+ internal_system 'rm .config'
68
+ end
69
+
70
+ # ========================================================================= #
71
+ # === prefix?
72
+ # ========================================================================= #
73
+ def prefix?
74
+ @prefix
75
+ end
76
+
77
+ # ========================================================================= #
78
+ # === set_this_build_dir
79
+ # ========================================================================= #
80
+ def set_this_build_dir(i = :pwd)
81
+ case i
82
+ when :pwd
83
+ i = return_pwd
84
+ end
85
+ i = i.to_s
86
+ unless i.include? '/'
87
+ i = File.absolute_path(i)
88
+ end
89
+ unless i.end_with? '/'
90
+ i = i.dup if i.frozen?
91
+ i << '/'
92
+ end
93
+ @build_directory_is_stored_here = i
94
+ end; alias set_build_directory set_this_build_dir # === set_build_directory
95
+
96
+ # ========================================================================= #
97
+ # === run_perl_installation
98
+ # ========================================================================= #
99
+ def run_perl_installation
100
+ _ 'perl Makefile.PL'
101
+ end
102
+
103
+ # ========================================================================= #
104
+ # === copy_setup_rb
105
+ # ========================================================================= #
106
+ def copy_setup_rb
107
+ FileUtils.cp(LOCATION_OF_SETUP_RB, return_pwd)
108
+ end
109
+
110
+ # ========================================================================= #
111
+ # === temp_dir?
112
+ # ========================================================================= #
113
+ def temp_dir?
114
+ ::Easycompile.temp_dir?
115
+ end
116
+
117
+ # ========================================================================= #
118
+ # === filename
119
+ # ========================================================================= #
120
+ def filename
121
+ return File.basename(__FILE__)+':'
122
+ end; alias filename? filename # === filename?
123
+
124
+ # ========================================================================= #
125
+ # === find_partial_match_for
126
+ # ========================================================================= #
127
+ def find_partial_match_for(i)
128
+ possible_matches = Dir["#{i}*"]
129
+ return_value = false
130
+ return_value = true unless possible_matches.empty?
131
+ return [return_value, possible_matches] # Returns an Array.
132
+ end
133
+
134
+ # ========================================================================= #
135
+ # === Easycompile::Base.version?
136
+ # ========================================================================= #
137
+ def self.version?
138
+ Easycompile.version?
139
+ end
140
+
141
+ # ========================================================================= #
142
+ # === temp_directory?
143
+ # ========================================================================= #
144
+ def temp_directory?
145
+ @temp_directory
146
+ end
147
+
148
+ # ========================================================================== #
149
+ # === open_this_file
150
+ # ========================================================================== #
151
+ def open_this_file(this_file = self.class::THIS_FILE)
152
+ esystem "bluefish #{this_file}"
153
+ end
154
+
155
+ # ========================================================================= #
156
+ # === do_not_create_a_build_directory
157
+ #
158
+ # Use this method if you do not wish to create a build directory.
159
+ # ========================================================================= #
160
+ def do_not_create_a_build_directory
161
+ @shall_we_create_a_build_directory = false
162
+ end
163
+
164
+ # ========================================================================= #
165
+ # === skip_make_install?
166
+ # ========================================================================= #
167
+ def skip_make_install?
168
+ @skip_make_install
169
+ end
170
+
171
+ # ========================================================================= #
172
+ # === set_start_dir
173
+ # ========================================================================= #
174
+ def set_start_dir(i = return_pwd)
175
+ i.squeeze! '/'
176
+ @start_dir = i # This is not @base_dir.
177
+ end
178
+
179
+ # ========================================================================= #
180
+ # === start_dir?
181
+ # ========================================================================= #
182
+ def start_dir?
183
+ @start_dir
184
+ end
185
+
186
+ # ========================================================================= #
187
+ # === empty_dir?
188
+ # ========================================================================= #
189
+ def empty_dir?(i)
190
+ Dir["#{i}/*"].empty?
191
+ end
192
+
193
+ # ========================================================================= #
194
+ # === set_extract_to_this_directory
195
+ # ========================================================================= #
196
+ def set_extract_to_this_directory(i = :default)
197
+ case i
198
+ # ======================================================================= #
199
+ # === :default
200
+ # ======================================================================= #
201
+ when :default,
202
+ nil
203
+ i = temp_dir?
204
+ end
205
+ i = i.to_s.dup
206
+ unless i.end_with? '/'
207
+ i = i.dup if i.frozen?
208
+ i << '/'
209
+ end
210
+ # ======================================================================= #
211
+ # === Handle blocks given to this method next:
212
+ # ======================================================================= #
213
+ if block_given?
214
+ yielded = yield
215
+ case yielded
216
+ # ===================================================================== #
217
+ # === :be_verbose
218
+ # ===================================================================== #
219
+ when :be_verbose
220
+ e "#{rev}Using the directory #{sdir(i)} as temp-directory next."
221
+ e '(The archive at hand will be extracted to this directory.)'
222
+ end
223
+ end
224
+ @extract_to_this_directory = i
225
+ end; alias set_extract_to set_extract_to_this_directory # === set_extract_to
226
+
227
+ # ========================================================================= #
228
+ # === extract_to_this_directory?
229
+ # ========================================================================= #
230
+ def extract_to_this_directory?
231
+ @extract_to_this_directory
232
+ end; alias extract_to? extract_to_this_directory? # === extract_to?
233
+
234
+ # ========================================================================= #
235
+ # === shall_we_create_a_build_directory?
236
+ # ========================================================================= #
237
+ def shall_we_create_a_build_directory?
238
+ @shall_we_create_a_build_directory
239
+ end
240
+
241
+ # ========================================================================= #
242
+ # === set_name_of_build_directory
243
+ # ========================================================================= #
244
+ def set_name_of_build_directory(
245
+ i = :default
246
+ )
247
+ case i
248
+ # ======================================================================= #
249
+ # === :load_the_yaml_file
250
+ # ======================================================================= #
251
+ when :load_the_yaml_file,
252
+ :default
253
+ i = YAML.load_file(FILE_NAME_OF_THE_BUILD_DIRECTORY)
254
+ end
255
+ i = i.dup if i.frozen?
256
+ i << '/' unless i.end_with? '/'
257
+ @name_of_build_directory = i
258
+ end
259
+
260
+ # ========================================================================= #
261
+ # === name_of_build_directory?
262
+ #
263
+ # This method will return the name of the BUILD/ directory. For now
264
+ # this is static but perhaps one day we may wish to change this,
265
+ # in order to make it more dynamic.
266
+ # ========================================================================= #
267
+ def name_of_build_directory?
268
+ @name_of_build_directory
269
+ end; alias name_for_build_dir? name_of_build_directory? # === name_for_build_dir?
270
+ alias name_of_the_build_directory? name_of_build_directory? # === name_of_the_build_directory?
271
+
272
+ # ========================================================================= #
273
+ # === continue_past_configure_stage?
274
+ # ========================================================================= #
275
+ def continue_past_configure_stage?
276
+ @continue_past_configure_stage
277
+ end
278
+
279
+ # ========================================================================= #
280
+ # === do_make_use_of_a_build_directory
281
+ # ========================================================================= #
282
+ def do_make_use_of_a_build_directory
283
+ @shall_we_create_a_build_directory = true
284
+ end
285
+
286
+ # ========================================================================= #
287
+ # === are_we_on_gobolinux?
288
+ # ========================================================================= #
289
+ def are_we_on_gobolinux?
290
+ ENV['IS_ON_GOBOLINUX'].to_s == '1'
291
+ end
292
+
293
+ # ========================================================================= #
294
+ # === set_original_input
295
+ #
296
+ # This method will keep track of the "original" input.
297
+ # ========================================================================= #
298
+ def set_original_input(i)
299
+ @original_input = i
300
+ end
301
+
302
+ # ========================================================================= #
303
+ # === original_input?
304
+ # ========================================================================= #
305
+ def original_input?
306
+ @original_input
307
+ end
308
+
309
+ # ========================================================================= #
310
+ # === mkdir (mkdir tag)
311
+ # ========================================================================= #
312
+ def mkdir(i)
313
+ FileUtils.mkdir_p(i)
314
+ end
315
+
316
+ # ========================================================================= #
317
+ # === can_not_continue
318
+ #
319
+ # Set @continue_past_configure_stage to false, so tha we won't continue.
320
+ # ========================================================================= #
321
+ def can_not_continue
322
+ @continue_past_configure_stage = false
323
+ end
324
+
325
+ # ========================================================================= #
326
+ # === continue_after_extracting?
327
+ # ========================================================================= #
328
+ def continue_after_extracting?
329
+ @continue_after_extracting
330
+ end
331
+
332
+ # ========================================================================= #
333
+ # === do_compile_with_dependencies
334
+ # ========================================================================= #
335
+ def do_compile_with_dependencies
336
+ opn_namespace; e 'We will compile the dependencies first.'
337
+ @compile_with_dependencies = true
338
+ end
339
+
340
+ # ========================================================================= #
341
+ # === enable_skip_make_install
342
+ # ========================================================================= #
343
+ def enable_skip_make_install
344
+ show_namespace; e 'We will skip running the "make install" step.'
345
+ @skip_make_install = true
346
+ end
347
+
348
+ # ========================================================================= #
349
+ # === skip_extracting?
350
+ # ========================================================================= #
351
+ def skip_extracting?
352
+ @skip_extracting
353
+ end
354
+
355
+ # ========================================================================= #
356
+ # === skip_extracting
357
+ # ========================================================================= #
358
+ def skip_extracting
359
+ show_namespace; e 'We will not extract.'
360
+ @skip_extracting = true
361
+ end
362
+
363
+ # ========================================================================= #
364
+ # === do_not_continue
365
+ #
366
+ # This method does not output anything to the user, on purpose.
367
+ # ========================================================================= #
368
+ def do_not_continue
369
+ @continue_after_extracting = false
370
+ end
371
+
372
+ # ========================================================================= #
373
+ # === do_not_compile
374
+ # ========================================================================= #
375
+ def do_not_compile
376
+ show_namespace; e 'We will not compile after extracting the source archive.'
377
+ do_not_continue
378
+ end
379
+
380
+ # ========================================================================= #
381
+ # === is_archive?
382
+ #
383
+ # Return true if the given input is an archive.
384
+ # ========================================================================= #
385
+ def is_archive?(i)
386
+ ::Easycompile.is_archive?(i)
387
+ end; alias is_an_archive? is_archive? # === is_an_archive?
388
+
389
+ # ========================================================================= #
390
+ # === consider_symlinking_appdir
391
+ #
392
+ # Use this method to consider symlinking into the AppDir hierarchy.
393
+ #
394
+ # We use class SymlinkProgram for this, from the RBT project. However
395
+ # had, when we are on GoboLinux, we will instead use the GoboLinux
396
+ # program called SymlinkProgram.
397
+ # ========================================================================= #
398
+ def consider_symlinking_appdir
399
+ _ = rds(prefix?+'/')
400
+ opn :namespace => NAMESPACE
401
+ e 'Next attempting to symlink at '+sdir(_)
402
+ if are_we_on_gobolinux?
403
+ cmd = 'SymlinkProgram '+_
404
+ esystem cmd
405
+ else
406
+ begin
407
+ require 'rbt/requires/require_symlink_this_program.rb'
408
+ rescue LoadError; end
409
+ if Object.const_defined?('RBT') and
410
+ RBT.const_defined?(SymlinkFromToCurrent)
411
+ RBT::SymlinkFromToCurrent.new(_)
412
+ end
413
+ end
414
+ end
415
+
416
+ # ========================================================================= #
417
+ # === enter_extracted_directory
418
+ #
419
+ # We use this method to enter the extracted directory.
420
+ # ========================================================================= #
421
+ def enter_extracted_directory(i = @original_input)
422
+ i = remove_extension_from(i)
423
+ if File.directory? i
424
+ _ = i
425
+ else
426
+ _ = "#{@temp_directory}#{get_program_name(i)}"
427
+ end
428
+ i = i.dup
429
+ _ << '/' unless _.end_with? '/'
430
+ if Dir.exist? _ # Only inform the user that we cd if that directory exists.
431
+ show_namespace; e "Now entering the directory `#{sdir(_)}`."
432
+ cd _
433
+ end
434
+ end
435
+
436
+ # ========================================================================= #
437
+ # === set_program_version
438
+ # ========================================================================= #
439
+ def set_program_version(i)
440
+ @program_version = i
441
+ end
442
+
443
+ # ========================================================================= #
444
+ # === set_base_dir
445
+ # ========================================================================= #
446
+ def set_base_dir(i = return_pwd)
447
+ i = i.squeeze('/')
448
+ @base_dir = i
449
+ end
450
+
451
+ # ========================================================================= #
452
+ # === base_dir`
453
+ # ========================================================================= #
454
+ def base_dir?
455
+ @base_dir
456
+ end
457
+
458
+ # ========================================================================= #
459
+ # === program_version?
460
+ # ========================================================================= #
461
+ def program_version?
462
+ @program_version
463
+ end; alias version? program_version? # === version?
464
+
465
+ # ========================================================================= #
466
+ # === attempt_to_find_a_valid_file
467
+ #
468
+ # This method will attempt to sanitize incomplete entries such as
469
+ # "nettle-2.7" towards "nettle-2.7.tar.xz".
470
+ #
471
+ # When we pass something such as "htop.yml" and this file does not
472
+ # exist in the current directory, then we will attempt to find it
473
+ # in another directory.
474
+ # ========================================================================= #
475
+ def attempt_to_find_a_valid_file(i)
476
+ if i.is_a? Array
477
+ i.map! {|entry|
478
+ unless File.exist? entry
479
+ entry = File.basename(entry)
480
+ if entry.include?('.yml') or entry.end_with?('.')
481
+ entry = INDIVIDUAL_COOKBOOKS+entry
482
+ yaml_dataset = get_dataset_from(entry)
483
+ entry = yaml_dataset['program_path']
484
+ set_program_version(yaml_dataset['program_version'])
485
+ else
486
+ # Then we try a glob.
487
+ _ = Dir["#{entry}*"]
488
+ entry = _.first unless _.empty?
489
+ end
490
+ end
491
+ entry
492
+ }
493
+ end
494
+ return i
495
+ end
496
+
497
+ # ========================================================================= #
498
+ # === set_hash
499
+ # ========================================================================= #
500
+ def set_hash(i = {})
501
+ if i.is_a? Hash
502
+ if i.has_key? :extract_to
503
+ set_extract_to(i[:extract_to])
504
+ end
505
+ if i.has_key? :program_version
506
+ set_version(i[:program_version])
507
+ end
508
+ if i.has_key? :prefix
509
+ set_prefix(i[:prefix])
510
+ end
511
+ if i.has_key? :appdir_layout
512
+ set_prefix(i[:appdir_layout])
513
+ elsif i.has_key? :usr_prefix
514
+ set_prefix(i[:usr_prefix])
515
+ end
516
+ end
517
+ @hash = i
518
+ end
519
+
520
+ # ========================================================================= #
521
+ # === program_name?
522
+ # ========================================================================= #
523
+ def program_name?
524
+ @program_name
525
+ end
526
+
527
+ # ========================================================================= #
528
+ # === consider_creating_a_build_directory
529
+ #
530
+ # Here we will consider whether we will create a build directory or
531
+ # whether we will not do so.
532
+ #
533
+ # If such a directory already exists then we do not need to create a
534
+ # new directory.
535
+ # ========================================================================= #
536
+ def consider_creating_a_build_directory(
537
+ where = return_pwd
538
+ )
539
+ if shall_we_create_a_build_directory?
540
+ _ = name_of_build_directory?
541
+ if File.exist? _
542
+ show_namespace
543
+ e "We will use the already existing build directory "\
544
+ "called `#{sdir(_)}`."
545
+ set_build_directory(_)
546
+ else
547
+ @base_dir = rds(where)
548
+ set_this_build_dir(File.absolute_path(_))
549
+ show_namespace
550
+ e 'We will create a build directory next called `'+sdir(_)+'` '\
551
+ '(Full target will be: '+@build_directory_is_stored_here+').'
552
+ # =================================================================== #
553
+ # Keep track of where the build directory is.
554
+ # =================================================================== #
555
+ mkdir @build_directory_is_stored_here # Creating the build directory finally.
556
+ end
557
+ # ===================================================================== #
558
+ # Next, we will enter that BUILD directory.
559
+ # ===================================================================== #
560
+ cd @build_directory_is_stored_here
561
+ show_namespace
562
+ # ===================================================================== #
563
+ # Notify the user that we have cd-ed already.
564
+ # ===================================================================== #
565
+ e 'Now entering the directory '+
566
+ sdir(@build_directory_is_stored_here)+'.'
567
+ end
568
+ end
569
+
570
+ # ========================================================================= #
571
+ # === compile_these_programs?
572
+ #
573
+ # This method will return on which input-files we will be working
574
+ # on, that is our target-programs.
575
+ # ========================================================================= #
576
+ def compile_these_programs?
577
+ @compile_these_programs
578
+ end; alias files? compile_these_programs? # === files?
579
+ alias file? compile_these_programs? # === file?
580
+
581
+ # ========================================================================= #
582
+ # === add_this_archive (add tag)
583
+ # ========================================================================= #
584
+ def add_this_archive(i)
585
+ if i
586
+ @compile_these_programs << i
587
+ @compile_these_programs.flatten!
588
+ @compile_these_programs.compact!
589
+ end
590
+ end; alias add_to_commandline_arguments add_this_archive # === add_to_commandline_arguments
591
+ alias set_files add_this_archive # === set_files
592
+ alias add_these_files add_this_archive # === add_these_files
593
+ alias add add_this_archive # === add
594
+
595
+ # ========================================================================= #
596
+ # === check_for_dependencies
597
+ # ========================================================================= #
598
+ def check_for_dependencies
599
+ # ======================================================================= #
600
+ # Next, add dependencies. To try this, do:
601
+ #
602
+ # ecompile metacity.yml wdeps
603
+ #
604
+ # ======================================================================= #
605
+ if @compile_with_dependencies
606
+ dependencies = get_dataset_from(@original_input)['required_deps_on']
607
+ dependencies.map! {|entry|
608
+ entry = entry.dup if entry.frozen?
609
+ entry << '.yml'
610
+ }
611
+ add(dependencies)
612
+ end
613
+ end
614
+
615
+ require 'extracter'
616
+ # ========================================================================= #
617
+ # === try_to_extract
618
+ #
619
+ # Use this method here to extract a given archive.
620
+ # ========================================================================= #
621
+ def try_to_extract(
622
+ this_archive, extract_to = extract_to?
623
+ )
624
+ if this_archive.is_a? Array # Obtain only the first element in this case.
625
+ this_archive = this_archive.first
626
+ end
627
+ cd start_dir?
628
+ if File.exist? this_archive.to_s
629
+ # ===================================================================== #
630
+ # In this case, we will assume that an valid archive was given to us.
631
+ # ===================================================================== #
632
+ unless skip_extracting?
633
+ show_namespace; e "Now trying to extract `#{sfancy(this_archive)}`."
634
+ @extracter = Extracter.what_to(this_archive, extract_to)
635
+ return remove_archive_at_the_end(
636
+ extract_to+
637
+ File.basename(this_archive)
638
+ )
639
+ else
640
+ nil
641
+ end
642
+ elsif File.exist? base_dir?+this_archive
643
+ unless skip_extracting?
644
+ @extracter = Extracter.what_to(base_dir?+this_archive, extract_to)
645
+ end
646
+ else
647
+ # ===================================================================== #
648
+ # The file does not exist here at this point. Thus, we will
649
+ # do some further checks.
650
+ # ===================================================================== #
651
+ if this_archive =~ /^\d+$/ # Ok, user inputted a number alone, check first.
652
+ this_archive = Dir['*'].sort[ this_archive.to_i - 1 ]
653
+ if File.exist? this_archive
654
+ @extracter = Extracter.what_to(this_archive, extract_to)
655
+ end
656
+ elsif find_partial_match_for(this_archive).first # Ok, user could input a partial number and a string, like: "baobab-3.9"
657
+ matched = find_partial_match_for(i)[1]
658
+ consider_extracting_this_archive(matched)
659
+ else # Ok, it indeed does not exist.
660
+ show_namespace; e 'File `'+sfile(this_archive)+'` does '+
661
+ 'not exist. We thus can not continue.'
662
+ show_namespace; e 'We will not continue as a consequence.'
663
+ do_not_continue
664
+ return nil
665
+ end
666
+ end
667
+ end; alias extract_archive try_to_extract # === extract_archive
668
+ alias extract try_to_extract # === extract
669
+ alias consider_extracting_this_archive try_to_extract # === consider_extracting_this_archive
670
+
671
+ # ========================================================================= #
672
+ # === set_compile_these_programs
673
+ #
674
+ # This method specifies which programs this class will compile.
675
+ # ========================================================================= #
676
+ def set_compile_these_programs(i)
677
+ i = [i].flatten.compact
678
+ i.map! {|entry|
679
+ # ======================================================================= #
680
+ # The file in question may not exist, for instance if it is a remote URL
681
+ # link. In that case we enter here.
682
+ # ======================================================================= #
683
+ unless File.exist? entry
684
+ case entry # case tag
685
+ when 'ALL','A' # simply get all.
686
+ entry = Dir['*'].reject {|inner_entry| File.directory? inner_entry }
687
+ when /LAST/,/LAT/ # Special instruction.
688
+ entry = File.readlines(LAST_DOWNLOADED_FILE).first
689
+ else # Try a (silent) glob here if the file does not exist.
690
+ if entry.include?('http') # Assume this to be a remote file.
691
+ esystem "wget #{entry}"
692
+ entry = File.basename(entry)
693
+ else
694
+ glob = Dir["#{entry}*"]
695
+ entry = glob.first unless glob.empty?
696
+ end
697
+ end
698
+ end
699
+ entry
700
+ }
701
+ @compile_these_programs = i
702
+ end
703
+
704
+ # ========================================================================= #
705
+ # === consider_removing_the_archive
706
+ # ========================================================================= #
707
+ def consider_removing_the_archive(
708
+ i = @build_directory_is_stored_here
709
+ )
710
+ if remove_all_after_compile?
711
+ if i.responds_to? :each
712
+ i.each {|entry|
713
+ remove_directory(entry)
714
+ }
715
+ else
716
+ i = i.to_s
717
+ if shall_we_create_a_build_directory?
718
+ if File.exist?(i) and empty_dir?(i)
719
+ # =============================================================== #
720
+ # Ok, we found an empty build-directory. Since it is empty,
721
+ # we can safely remove it.
722
+ # =============================================================== #
723
+ remove_directory(i)
724
+ end
725
+ end
726
+ end
727
+ end
728
+ end; alias consider_removing_this_archive consider_removing_the_archive # === consider_removing_this_archive
729
+ alias consider_purging_empty_build_directory consider_removing_the_archive # === consider_purging_empty_build_directory
730
+
731
+ # ========================================================================= #
732
+ # === run_configure (configure tag)
733
+ #
734
+ # This method runs the classical configure command with a specific
735
+ # prefix. It is equivalent to just run "./configure".
736
+ # ========================================================================= #
737
+ def run_configure
738
+ if shall_we_create_a_build_directory?
739
+ @prefix_to_base_directory << '../'
740
+ end
741
+ # ======================================================================= #
742
+ # === Check for Rakefile
743
+ # ======================================================================= #
744
+ if File.exist?(@prefix_to_base_directory+'Rakefile')
745
+ run_rinstall2
746
+ # ======================================================================= #
747
+ # === Check for cmake-file
748
+ #
749
+ # Here we will run cmake.
750
+ # ======================================================================= #
751
+ elsif File.exist?("#{@prefix_to_base_directory}#{cmake_file?}")
752
+ run_cmake_command
753
+ # ======================================================================= #
754
+ # === Check for setup.py file
755
+ #
756
+ # Note that a file called setup.py may exist, but the program itself
757
+ # may still require a "configure" invocation. This is the case with
758
+ # the official source archive for Python.
759
+ # ======================================================================= #
760
+ elsif File.exist?(@prefix_to_base_directory+'setup.py')
761
+ run_python_installation
762
+ # ======================================================================= #
763
+ # === Check for Makefile.PL
764
+ # ======================================================================= #
765
+ elsif File.exist?(@prefix_to_base_directory+'Makefile.PL')
766
+ run_perl_installation
767
+ # ======================================================================= #
768
+ # === Check for build.sh file
769
+ #
770
+ # This was disabled on 20.06.2020 as it was not working for the
771
+ # program called "make". At a later time this may have to be
772
+ # re-enabled again, but for now it has to stay disabled.
773
+ # ======================================================================= #
774
+ # elsif File.exist? @prefix_to_base_directory+'build.sh'
775
+ # run_build_sh
776
+ # ======================================================================= #
777
+ # === Run the configure command next
778
+ # ======================================================================= #
779
+ elsif File.exist? @prefix_to_base_directory+'configure'
780
+ simply_run_the_configure_command
781
+ # ======================================================================= #
782
+ # === Check for ruby .gem files next
783
+ # ======================================================================= #
784
+ elsif (@original_input =~ /\.gem$/)
785
+ install_this_gem(@original_input)
786
+ exit
787
+ # ======================================================================= #
788
+ # === Check whether 'meson.build' exists
789
+ # ======================================================================= #
790
+ elsif does_a_meson_build_file_exist?
791
+ compile_as_meson_based_project
792
+ exit
793
+ else # The default, that is - we will run ./configure here.
794
+ show_namespace; e 'We could not find a configure script, no cmake'
795
+ show_namespace; e 'file and we also could not find various other '
796
+ show_namespace; e 'files. We will now assume that configure may'
797
+ show_namespace; e 'still work, and thus run, but be aware that'
798
+ show_namespace; e 'this may fail.'
799
+ simply_run_the_configure_command
800
+ end
801
+ end; alias run_configure_command run_configure # === run_configure_command
802
+ alias run_configure_command_or_another_command run_configure # === run_configure_command_or_another_command
803
+ alias run_configure_or_cmake run_configure # === run_configure_command_or_another_command
804
+
805
+ # ========================================================================= #
806
+ # === simply_run_the_configure_command
807
+ # ========================================================================= #
808
+ def simply_run_the_configure_command
809
+ _ = ''.dup # ← Buildup the command.
810
+ _ << '.' if shall_we_create_a_build_directory?
811
+ _ << "./configure --prefix=#{prefix?}"
812
+ # ======================================================================= #
813
+ # === Check for etended configure options next
814
+ # ======================================================================= #
815
+ if @try_to_use_extended_configure_options
816
+ begin
817
+ require 'rbt/requires/require_show_configuration_options.rb'
818
+ rescue LoadError; end
819
+ if RBT.respond_to? :return_configuration_options_for?
820
+ _ << " #{RBT.return_configuration_options_for?(find_which_program?)}"
821
+ end
822
+ end
823
+ begin
824
+ # This part invokes the actual "./configure" run.
825
+ esystem(_) # Also show the ./configure command we will use.
826
+ rescue Errno::ENOENT
827
+ show_namespace
828
+ e 'An error happened - the configure-file could not be found. '\
829
+ 'The faulty line was:'
830
+ show_namespace
831
+ e " #{simp(_)}"
832
+ show_namespace
833
+ e "It was issued from the directory: #{sdir(return_pwd)}"
834
+ if return_pwd.include? name_for_build_dir?
835
+ set_this_build_dir(:pwd)
836
+ end
837
+ can_not_continue # We can not continue past the configure-step.
838
+ # ======================================================================= #
839
+ # Do "make distclean" here.
840
+ # ======================================================================= #
841
+ if _.include?('configure: error: source directory already configured') or
842
+ _.include?('source directory already configured; run "make distclean"')
843
+ @base_dir = return_pwd
844
+ cd '..'
845
+ make_distclean
846
+ cd @base_dir
847
+ run_configure_command
848
+ end if _
849
+ end
850
+ end
851
+
852
+ # ========================================================================= #
853
+ # === try_to_compile_or_install_this_program
854
+ # ========================================================================= #
855
+ def try_to_compile_or_install_this_program(this_archive)
856
+ if is_a_gem?(this_archive)
857
+ e "#{rev}Now installing the gem at #{sfile(this_archive)}."
858
+ install_this_gem(this_archive)
859
+ else
860
+ extracted_to = try_to_extract(this_archive)
861
+ if continue_after_extracting?
862
+ if File.directory? extracted_to
863
+ enter_extracted_directory(extracted_to)
864
+ consider_creating_a_build_directory
865
+ run_configure_make_and_make_install
866
+ end
867
+ end
868
+ end
869
+ end
870
+
871
+ # ========================================================================= #
872
+ # === return_to_start_directory_again
873
+ # ========================================================================= #
874
+ def return_to_start_directory_again
875
+ cd start_dir?
876
+ end
877
+
878
+ # ========================================================================= #
879
+ # === is_the_cookbook_class_available?
880
+ # ========================================================================= #
881
+ def is_the_cookbook_class_available?
882
+ Object.const_defined?(:RBT) and
883
+ RBT.const_defined?(:Cookbooks) and
884
+ RBT::Cookbooks.const_defined?(:Cookbook)
885
+ end
886
+
887
+ # ========================================================================= #
888
+ # === get_dataset_from
889
+ # ========================================================================= #
890
+ def get_dataset_from(i)
891
+ if !Object.const_defined?(:RBT) and !RBT.const_defined?(:Cookbooks)
892
+ begin
893
+ require 'rbt/requires/require_the_cookbook_class.rb'
894
+ rescue LoadError; end
895
+ end
896
+ i.chop! if i.end_with? '.'
897
+ if is_the_cookbook_class_available?
898
+ i = RBT::Cookbooks::SanitizeCookbook.new(i).dataset?
899
+ end
900
+ return i
901
+ end
902
+
903
+ # ========================================================================= #
904
+ # === run_make_command_or_equivalent (make tag)
905
+ #
906
+ # This method will either run "make", or another command.
907
+ #
908
+ # For now we assume the alternative is via cmake. Please note that
909
+ # the command "make install" usually follows the "make" command.
910
+ # ========================================================================= #
911
+ def run_make_command_or_equivalent
912
+ show_namespace; e 'Running "make" in '+sdir(return_pwd)+' next.'
913
+ if File.exist? 'Makefile'
914
+ esystem 'make' if continue_past_configure_stage?
915
+ else # Else assume cmake.
916
+ esystem 'make' if continue_past_configure_stage?
917
+ end
918
+ end; alias run_make_command run_make_command_or_equivalent # === run_make_command
919
+ alias run_make run_make_command_or_equivalent # === run_make
920
+
921
+ # ========================================================================= #
922
+ # === is_an_appdir?
923
+ #
924
+ # Return true if this is an appdir-based program.
925
+ # ========================================================================= #
926
+ def is_an_appdir?
927
+ @hash.has_key?(:prefix) and @hash[:prefix] == :appdir
928
+ end
929
+
930
+ # ========================================================================= #
931
+ # === determine_which_programs_to_compile
932
+ # ========================================================================= #
933
+ def determine_which_programs_to_compile
934
+ if @commandline_arguments.empty?
935
+ # ===================================================================== #
936
+ # If we did not input anything then use all archives from the
937
+ # current working directory.
938
+ # ===================================================================== #
939
+ _ = Dir['*'].select {|entry| is_an_archive?(entry) }
940
+ else
941
+ if @commandline_arguments.any? {|entry| entry.end_with? '.yml' }
942
+ # =================================================================== #
943
+ # Handle .yml files here.
944
+ # =================================================================== #
945
+ @commandline_arguments = replace_all_yaml_files(@commandline_arguments)
946
+ end
947
+ _ = @commandline_arguments.select {|entry| File.exist?(entry) }
948
+ end
949
+ set_compile_these_programs(_)
950
+ end
951
+
952
+ # ========================================================================= #
953
+ # === replace_all_yaml_files
954
+ # ========================================================================= #
955
+ def replace_all_yaml_files(i = @commandline_arguments)
956
+ i.map {|entry|
957
+ if entry.end_with?('.yml')
958
+ begin
959
+ require 'rbt/requires/require_the_cookbook_class.rb'
960
+ entry = return_yaml_file(entry)
961
+ rescue LoadError; end
962
+ end
963
+ entry
964
+ }
965
+ end
966
+
967
+ # ========================================================================= #
968
+ # === return_yaml_file
969
+ # ========================================================================= #
970
+ def return_yaml_file(i)
971
+ begin
972
+ require 'rbt/requires/require_the_cookbook_class.rb'
973
+ i = RBT::Cookbooks::SanitizeCookbook.new(i).program_path?
974
+ rescue LoadError; end
975
+ return i
976
+ end
977
+
978
+ # ========================================================================= #
979
+ # === get_program_name
980
+ #
981
+ # Obtain the program name here.
982
+ # ========================================================================= #
983
+ def get_program_name(i = @original_input)
984
+ if i.include? ' '
985
+ i = i.split(' ').first
986
+ end
987
+ program_name = remove_file_suffix(File.basename(i))
988
+ return program_name
989
+ end
990
+
991
+ # ========================================================================= #
992
+ # === set_program_name
993
+ #
994
+ # Note that this method can make use of ProgramInformation.
995
+ # ========================================================================= #
996
+ def set_program_name(i = nil)
997
+ i = i.first if i.is_a? Array
998
+ if i
999
+ i = get_program_name(i)
1000
+ # ===================================================================== #
1001
+ # Next, we need to obtain the real program name, without the
1002
+ # version. We used the following line for this in the past:
1003
+ # _ = _.split('-').first if _.include? '-'
1004
+ # However had, as of 08.08.2015, we will instead use ProgramInformation.
1005
+ # ===================================================================== #
1006
+ i = ProgramInformation.return_name(i) # .first() will return the right name.
1007
+ end
1008
+ @program_name = i
1009
+ end
1010
+
1011
+ # ========================================================================= #
1012
+ # === use_the_home_directory_as_prefix
1013
+ # ========================================================================= #
1014
+ def use_the_home_directory_as_prefix
1015
+ set_prefix(:home_directory)
1016
+ end
1017
+
1018
+ # ========================================================================= #
1019
+ # === run_build_sh
1020
+ #
1021
+ # Run sh build.sh
1022
+ # ========================================================================= #
1023
+ def run_build_sh
1024
+ _ = "#{@prefix_to_base_directory}sh build.sh"
1025
+ esystem _
1026
+ end
1027
+
1028
+ # ========================================================================= #
1029
+ # === make_distclean
1030
+ # ========================================================================= #
1031
+ def make_distclean
1032
+ esystem 'make distclean'
1033
+ end
1034
+
1035
+ # ========================================================================= #
1036
+ # === run_make_install_command
1037
+ #
1038
+ # This will run "make install".
1039
+ # ========================================================================= #
1040
+ def run_make_install_command
1041
+ esystem 'make install' unless skip_make_install?
1042
+ end
1043
+
1044
+ # ========================================================================= #
1045
+ # === run_configure_make_and_make_install
1046
+ # ========================================================================= #
1047
+ def run_configure_make_and_make_install
1048
+ run_configure_command_or_another_command
1049
+ if continue_past_configure_stage?
1050
+ run_make_command_or_equivalent
1051
+ run_make_install_command
1052
+ end
1053
+ end; alias run_configure_then_make_then_make_install run_configure_make_and_make_install # === run_configure_then_make_then_make_install
1054
+
1055
+ # ========================================================================= #
1056
+ # === run_make_then_make_install
1057
+ # ========================================================================= #
1058
+ def run_make_then_make_install
1059
+ run_make_command_or_equivalent
1060
+ run_make_install_command
1061
+ end
1062
+
1063
+ # ========================================================================= #
1064
+ # === run_python_installation (python tag)
1065
+ #
1066
+ # This method will additionally check for a file called 'configure'.
1067
+ # ========================================================================= #
1068
+ def run_python_installation
1069
+ if File.exist?("#{@prefix_to_base_directory}configure")
1070
+ simply_run_the_configure_command
1071
+ run_make_then_make_install
1072
+ else
1073
+ _ 'python setup.py configure'
1074
+ _ 'python setup.py build'
1075
+ _ 'python setup.py install'
1076
+ end
1077
+ end
1078
+
1079
+ # ========================================================================= #
1080
+ # === set_prefix
1081
+ #
1082
+ # Set the prefix here. By default the prefix will be /usr, but some
1083
+ # programs, in particular app-dir like programs, will default to
1084
+ # a prefix such as /Programs/Gimp/2.5.2.
1085
+ # ========================================================================= #
1086
+ def set_prefix(
1087
+ i = '/usr'
1088
+ )
1089
+ if i.is_a? Symbol # This may be triggered via :appdir, for instance.
1090
+ case i
1091
+ # ===================================================================== #
1092
+ # === :home_directory
1093
+ # ===================================================================== #
1094
+ when :home_directory,
1095
+ :home_dir,
1096
+ :home
1097
+ i = ENV['HOME'].to_s
1098
+ end
1099
+ i = i.to_s # Work on a String here.
1100
+ i = remove_file_suffix(i)
1101
+ # ===================================================================== #
1102
+ # Simply assemble the prefix now, based on the capitalized variant
1103
+ # of the program name, and then the version.
1104
+ # For this to work, program_name? and program_version? must have
1105
+ # been already defined.
1106
+ # ===================================================================== #
1107
+ # if program_name?.nil? and program_version?.nil?
1108
+ # # In this case, we must first define these two entries.
1109
+ # # This has not yet happened - stub.
1110
+ # end
1111
+ case i
1112
+ when /usr(_|-)?prefix/
1113
+ i = '/usr/'
1114
+ # ===================================================================== #
1115
+ # === appdir
1116
+ # ===================================================================== #
1117
+ when 'appdir',
1118
+ 'app'
1119
+ # =================================================================== #
1120
+ # We will first check on the original input. If that original
1121
+ # input was an existing file, in form of an archive, then
1122
+ # we may make use of ProgramInformation to change the
1123
+ # version of the program at hand.
1124
+ # =================================================================== #
1125
+ if @original_input and
1126
+ File.exist?(@original_input) and
1127
+ File.file?(@original_input) and
1128
+ is_archive?(@original_input)
1129
+ # ================================================================= #
1130
+ # Ok, in this case, we will make use of ProgramInformation.
1131
+ # ================================================================= #
1132
+ _ = remove_archive_at_the_end(
1133
+ File.basename(
1134
+ @original_input
1135
+ )
1136
+ )
1137
+ set_program_name(_)
1138
+ set_program_version(
1139
+ ProgramInformation.return_version(@original_input)
1140
+ )
1141
+ end
1142
+ # =================================================================== #
1143
+ # Build up the full appdir-prefix next:
1144
+ # =================================================================== #
1145
+ i = "#{::Easycompile.programs_directory?}"\
1146
+ "#{program_name?.to_s.capitalize.delete('-')}"\
1147
+ "/#{program_version?}"
1148
+ end
1149
+ end
1150
+ if i.is_a? String # We can do this because the next step is rds().
1151
+ i = i.dup if i.frozen?
1152
+ i = rds("#{i}/")
1153
+ end
1154
+ @prefix = i
1155
+ end; alias set_prefix_for_this_program set_prefix # === set_prefix_for_this_program
1156
+
1157
+ end; end