build-tool 0.5.7 → 0.6.0.rc1

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.
Files changed (133) hide show
  1. data/.gitignore +1 -0
  2. data/.rvmrc +1 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile.lock +56 -0
  6. data/History.txt +64 -0
  7. data/README.txt +0 -7
  8. data/Rakefile +8 -56
  9. data/bin/build-tool +4 -1
  10. data/build-tool.gemspec +62 -0
  11. data/db/migrations/20110703074000_add_command_logs.rb +17 -0
  12. data/db/migrations/20110703075000_add_module_logs.rb +20 -0
  13. data/db/migrations/20110815170000_add_features.rb +17 -0
  14. data/db/migrations/20120103204700_add_modules.rb +17 -0
  15. data/db/migrations/20120106181200_add_settings.rb +18 -0
  16. data/lib/build-tool.rb +3 -4
  17. data/lib/build-tool/application.rb +127 -37
  18. data/lib/build-tool/build-system/autoconf.rb +2 -8
  19. data/lib/build-tool/build-system/base.rb +12 -4
  20. data/lib/build-tool/build-system/cmake.rb +2 -0
  21. data/lib/build-tool/build-system/custom.rb +2 -0
  22. data/lib/build-tool/build-system/kdel10n.rb +2 -0
  23. data/lib/build-tool/build-system/make.rb +2 -0
  24. data/lib/build-tool/build-system/none.rb +2 -0
  25. data/lib/build-tool/build-system/qmake.rb +2 -0
  26. data/lib/build-tool/build-system/qt.rb +4 -0
  27. data/lib/build-tool/cfg/lexer.rex +40 -8
  28. data/lib/build-tool/cfg/lexer_base.rb +3 -1
  29. data/lib/build-tool/cfg/node.rb +17 -1
  30. data/lib/build-tool/cfg/parser.y +92 -10
  31. data/lib/build-tool/cfg/visitor.rb +202 -78
  32. data/lib/build-tool/command_actions.rb +26 -10
  33. data/lib/build-tool/commands.rb +289 -197
  34. data/lib/build-tool/commands/build.rb +13 -9
  35. data/lib/build-tool/commands/configuration.rb +25 -0
  36. data/lib/build-tool/commands/configuration/edit.rb +42 -0
  37. data/lib/build-tool/commands/configuration/list.rb +48 -0
  38. data/lib/build-tool/commands/configure.rb +9 -5
  39. data/lib/build-tool/commands/ctags.rb +8 -3
  40. data/lib/build-tool/commands/environments.rb +2 -4
  41. data/lib/build-tool/commands/environments/list.rb +13 -10
  42. data/lib/build-tool/commands/environments/set.rb +5 -1
  43. data/lib/build-tool/commands/features.rb +24 -0
  44. data/lib/build-tool/commands/features/disable.rb +70 -0
  45. data/lib/build-tool/commands/features/enable.rb +66 -0
  46. data/lib/build-tool/commands/features/list.rb +92 -0
  47. data/lib/build-tool/commands/fetch.rb +9 -3
  48. data/lib/build-tool/commands/files.rb +9 -5
  49. data/lib/build-tool/commands/gc.rb +48 -15
  50. data/lib/build-tool/commands/history.rb +21 -16
  51. data/lib/build-tool/commands/info.rb +16 -13
  52. data/lib/build-tool/commands/install.rb +8 -4
  53. data/lib/build-tool/commands/modules.rb +2 -4
  54. data/lib/build-tool/commands/modules/cleanup.rb +52 -0
  55. data/lib/build-tool/commands/modules/disable.rb +95 -0
  56. data/lib/build-tool/commands/modules/enable.rb +52 -0
  57. data/lib/build-tool/commands/modules/info.rb +44 -35
  58. data/lib/build-tool/commands/modules/list.rb +67 -15
  59. data/lib/build-tool/commands/modules/shell.rb +8 -2
  60. data/lib/build-tool/commands/rebase.rb +15 -7
  61. data/lib/build-tool/commands/recipes.rb +2 -4
  62. data/lib/build-tool/commands/recipes/add.rb +16 -2
  63. data/lib/build-tool/commands/recipes/edit.rb +72 -0
  64. data/lib/build-tool/commands/recipes/incoming.rb +11 -7
  65. data/lib/build-tool/commands/recipes/info.rb +12 -8
  66. data/lib/build-tool/commands/recipes/install.rb +37 -42
  67. data/lib/build-tool/commands/recipes/list.rb +6 -2
  68. data/lib/build-tool/configuration.rb +88 -3
  69. data/lib/build-tool/environment.rb +2 -0
  70. data/lib/build-tool/errors.rb +5 -0
  71. data/lib/build-tool/history.rb +3 -181
  72. data/lib/build-tool/model/command_log.rb +93 -0
  73. data/lib/build-tool/model/feature.rb +80 -0
  74. data/lib/build-tool/{module.rb → model/module.rb} +110 -29
  75. data/lib/build-tool/model/module_log.rb +64 -0
  76. data/lib/build-tool/model/setting.rb +84 -0
  77. data/lib/build-tool/recipe.rb +40 -18
  78. data/lib/build-tool/repository.rb +39 -33
  79. data/lib/build-tool/server.rb +27 -3
  80. data/lib/build-tool/singleton.rb +2 -0
  81. data/lib/build-tool/sshkey.rb +2 -0
  82. data/lib/build-tool/state_helper.rb +64 -0
  83. data/lib/build-tool/vcs/archive.rb +3 -1
  84. data/lib/build-tool/vcs/base.rb +13 -0
  85. data/lib/build-tool/vcs/git-svn.rb +36 -14
  86. data/lib/build-tool/vcs/git.rb +180 -44
  87. data/lib/build-tool/vcs/mercurial.rb +25 -13
  88. data/lib/build-tool/vcs/svn.rb +20 -15
  89. data/lib/build-tool/version.rb +30 -0
  90. data/lib/mj/error.rb +2 -0
  91. data/lib/mj/logging.rb +2 -0
  92. data/lib/mj/mixins/inherited_attributes.rb +73 -0
  93. data/lib/mj/tools/editor.rb +34 -0
  94. data/lib/mj/tools/ssh.rb +2 -0
  95. data/lib/mj/tools/subprocess.rb +2 -1
  96. data/lib/mj/vcs/git.rb +14 -2
  97. data/lib/mj/visitor.rb +22 -0
  98. data/tasks/db.rake +36 -0
  99. data/tasks/racc.rake +14 -0
  100. data/tasks/rdoc.rake +8 -0
  101. data/tasks/rexical.rake +14 -0
  102. data/tasks/test.rake +21 -0
  103. data/test/integration/history_test.rb +88 -0
  104. data/test/integration/parser_configuration.rb +36 -0
  105. data/test/integration/parser_environment_parser.rb +156 -0
  106. data/test/integration/parser_feature_test.rb +75 -0
  107. data/test/integration/parser_git-svn_test.rb +92 -0
  108. data/test/integration/parser_git_test.rb +97 -0
  109. data/test/integration/parser_mercurial_test.rb +77 -0
  110. data/test/integration/parser_module_test.rb +103 -0
  111. data/test/integration/parser_svn_test.rb +92 -0
  112. data/test/integration/parser_test.rb +73 -0
  113. data/test/test_helper.rb +61 -0
  114. data/test/unit/configuration_test.rb +36 -0
  115. data/test/unit/git_configuration_test.rb +163 -0
  116. data/test/unit/git_svn_configuration_test.rb +240 -0
  117. data/test/unit/mercurial_configuration_test.rb +64 -0
  118. data/test/unit/model/command_log_test.rb +103 -0
  119. data/test/unit/model/feature_test.rb +29 -0
  120. data/test/unit/model/module_log_test.rb +70 -0
  121. data/test/unit/model/module_test.rb +32 -0
  122. data/test/unit/repository_test.rb +110 -0
  123. data/test/unit/server_test.rb +66 -0
  124. data/test/unit/svn_configuration_test.rb +90 -0
  125. metadata +134 -93
  126. data/Manifest.txt +0 -80
  127. data/db/migrations/001_command_histories.rb +0 -20
  128. data/db/migrations/002_module_events.rb +0 -24
  129. data/db/migrations/003_command_histories_add_logfile.rb +0 -19
  130. data/lib/build-tool/GUI.rb +0 -360
  131. data/lib/build-tool/commands/help.rb +0 -22
  132. data/lib/build-tool/commands/lsfeatures.rb +0 -76
  133. data/lib/build-tool/feature.rb +0 -47
@@ -0,0 +1,80 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ require 'active_record'
4
+
5
+ module BuildTool
6
+
7
+ # A feature bundles modules and makes it possible to enable/disable them together.
8
+ class Feature < ActiveRecord::Base
9
+
10
+ validates_uniqueness_of :name, :scope => :parent_id
11
+
12
+ # A short description for the feature
13
+ attr_accessor :description
14
+
15
+ # A long description for the feature
16
+ attr_accessor :long_description
17
+
18
+ # The default state of the feature
19
+ attr_accessor :default_active
20
+
21
+ # The modules associated with this feature
22
+ attr_reader :modules
23
+
24
+ # The environments associated with this feature
25
+ attr_reader :environments
26
+
27
+ # Custom initialization
28
+ after_initialize :my_initialize
29
+ def my_initialize
30
+ @description = nil
31
+ @long_description = nil
32
+ @modules = []
33
+ @environments = []
34
+ @default_active = true
35
+ end
36
+
37
+ # Is the feature active?
38
+ def active?
39
+ state = active.nil? ? default_active : active
40
+ if parent_id.nil?
41
+ state
42
+ else
43
+ parent.active? && state
44
+ end
45
+ end
46
+
47
+ # Return a character showing the features active state.
48
+ def active_char
49
+ if active?
50
+ ANSI::Code.green { "A" }
51
+ else
52
+ "I"
53
+ end
54
+ end
55
+
56
+ # Is the feature active by default?
57
+ def default_active?
58
+ default_active
59
+ end
60
+
61
+ # Return a unique name for the feature.
62
+ #
63
+ # The name is scoped with the parents name.
64
+ def path
65
+ if parent.nil?
66
+ name
67
+ else
68
+ "%s/%s" % [ parent.name, name ]
69
+ end
70
+ end
71
+
72
+ def to_s
73
+ "Feature #{name} ( #{self.active} / #{self.default_active} )"
74
+ end
75
+
76
+ belongs_to :parent, :class_name => 'BuildTool::Feature'
77
+
78
+ end
79
+
80
+ end
@@ -1,5 +1,8 @@
1
+ # -*- coding: UTF-8 -*-
2
+
1
3
  require 'mj/tools/ssh'
2
4
 
5
+ require 'active_record'
3
6
  require 'fileutils'
4
7
 
5
8
  module BuildTool
@@ -7,17 +10,27 @@ module BuildTool
7
10
  #
8
11
  # Represents the information associated with a buildable module.
9
12
  #
10
- class Module
13
+ class Module < ActiveRecord::Base
14
+
15
+ # The name of the module
16
+ validates_uniqueness_of :name
17
+
18
+ # Modules are sorted by name
19
+ def <=>( other )
20
+ self.name <=> other.name
21
+ end
11
22
 
12
- # Create a module
13
- def initialize( name, parent = nil )
23
+ # A command can have many module events
24
+ has_many :module_logs, :class_name => "BuildTool::History::ModuleLog", :order => :id, :foreign_key => :module, :primary_key => :name, :dependent => :destroy
25
+
26
+ # Custom initialization
27
+ after_initialize :my_initialize
28
+ def my_initialize()
14
29
  if name.nil?
15
30
  raise StandardError, "Module name is required!"
16
31
  end
17
32
  @active = nil
18
33
  @patches = Array.new
19
- @name = name
20
- @parent = parent
21
34
  @local_path = nil
22
35
  @build_prefix = nil
23
36
  @remote_path = nil
@@ -27,6 +40,9 @@ def initialize( name, parent = nil )
27
40
  @is_template = false
28
41
  @vcs_configuration = nil
29
42
  @feature = nil
43
+ @default_active = true
44
+ @found_in_recipe = false
45
+ @parent = nil
30
46
 
31
47
  @long_description = nil
32
48
  @description = nil
@@ -35,21 +51,41 @@ def initialize( name, parent = nil )
35
51
  #
36
52
  ### ATTRIBUTES
37
53
  #
54
+
38
55
  attr_writer :feature
39
- attr_writer :active
40
56
  attr_reader :patches
41
- attr_reader :parent
42
57
 
58
+ # The previous version of this module.
59
+ attr_accessor :parent
60
+
61
+ # Signals wether the module was found in the recipe or only in the database.
62
+ attr_accessor :found_in_recipe
63
+
64
+ # The default state of the feature
65
+ attr_accessor :default_active
66
+
67
+ # Is the module active by default?
68
+ def default_active?
69
+ @default_active
70
+ end
71
+
72
+ # Is the module active?
43
73
  def active?
44
- # If the module is activated that wins
45
- if @active.nil?
46
- if @feature.nil?
47
- return true
74
+ # If the module is explicitely de/activated that wins
75
+ if active.nil?
76
+ # if the module is active by default let the feature decide if present.
77
+ if default_active?
78
+ if @feature.nil?
79
+ return true
80
+ else
81
+ return @feature.active?
82
+ end
48
83
  else
49
- return @feature.active?
84
+ # The feature is not active by default.
85
+ return false
50
86
  end
51
87
  else
52
- return @active
88
+ return active
53
89
  end
54
90
  end
55
91
 
@@ -74,7 +110,7 @@ def build_prefix
74
110
  # Return our own buildsystem if there is one
75
111
  return @build_prefix if @build_prefix
76
112
  # Return our parents buildsystem if there is one
77
- return @parent.build_prefix if @parent && @parent.build_prefix
113
+ return parent.build_prefix if parent && parent.build_prefix
78
114
  # Nothing
79
115
  nil
80
116
  end
@@ -92,8 +128,8 @@ def build_system
92
128
  # Return our own buildsystem if there is one
93
129
  return @build_system if @build_system
94
130
  # Return our parents buildsystem if there is one
95
- if @parent && @parent.build_system
96
- @build_system = @parent.build_system.dup
131
+ if parent && parent.build_system
132
+ @build_system = parent.build_system.dup
97
133
  @build_system.module = self
98
134
  return @build_system
99
135
  end
@@ -112,6 +148,18 @@ def build_system_required
112
148
  raise ConfigurationError, "No build system configured for #{name}!"
113
149
  end
114
150
 
151
+ # Return true if the last build failed for whatever reason
152
+ def broken?
153
+ lastlog = BuildTool::History::CommandLog.last_by_module( name )
154
+ return true if lastlog.empty?
155
+ lastlog[0].module_logs.where( :module => name ).each do |e|
156
+ if e.state != History::ModuleLog::FINISHED_SUCCESSFUL
157
+ return true
158
+ end
159
+ end
160
+ return false
161
+ end
162
+
115
163
  def checkedout?
116
164
  vcs_required.checkedout?
117
165
  end
@@ -136,7 +184,7 @@ def environment
136
184
  # Return our own buildsystem if there is one
137
185
  return @environment if @environment
138
186
  # Return our parents buildsystem if there is one
139
- return @parent.environment if @parent && @parent.environment
187
+ return parent.environment if parent && parent.environment
140
188
  # Nothing
141
189
  nil
142
190
  end
@@ -169,7 +217,7 @@ def install_prefix
169
217
  # Return our own buildsystem if there is one
170
218
  return @install_prefix if @install_prefix
171
219
  # Return our parents buildsystem if there is one
172
- return @parent.install_prefix if @parent && @parent.install_prefix
220
+ return parent.install_prefix if parent && parent.install_prefix
173
221
  # Nothing
174
222
  nil
175
223
  end
@@ -191,7 +239,7 @@ def local_path=( local_path )
191
239
  end
192
240
 
193
241
  def local_path
194
- @local_path || @name
242
+ @local_path || name
195
243
  end
196
244
 
197
245
  attr_writer :long_description
@@ -199,9 +247,6 @@ def long_description
199
247
  @long_description
200
248
  end
201
249
 
202
- # The module name
203
- attr_reader :name
204
-
205
250
  # Remote path
206
251
  def remote_path=( remote_path )
207
252
  raise ConfigurationError, "Attempt to set remote_path for module template #{name}" if is_template?
@@ -209,7 +254,7 @@ def remote_path=( remote_path )
209
254
  end
210
255
 
211
256
  def remote_path
212
- @remote_path || @name
257
+ @remote_path || name
213
258
  end
214
259
 
215
260
  def source_directory
@@ -217,6 +262,38 @@ def source_directory
217
262
  end
218
263
  alias source_directory_required source_directory
219
264
 
265
+ # Returns a current state in string format
266
+ def state
267
+ lastlog = BuildTool::History::CommandLog.last_by_module( name )
268
+ return 'UNKNOWN' if lastlog.empty?
269
+ lastlog[0].module_logs.where( :module => name ).each do |e|
270
+ if e.state != History::ModuleLog::FINISHED_SUCCESSFUL
271
+ return "#{e.state_str} (#{e.event})"
272
+ end
273
+ end
274
+ return History::ModuleLog::state_str( History::ModuleLog::FINISHED_SUCCESSFUL )
275
+ end
276
+
277
+ # Return the current state as one char.
278
+ def state_char
279
+ lastlog = BuildTool::History::CommandLog.last_by_module( name )
280
+ return '?' if lastlog.empty?
281
+ lastlog[0].module_logs.where( :module => name ).each do |e|
282
+ if e.state != History::ModuleLog::FINISHED_SUCCESSFUL
283
+ return "#{e.state_char}"
284
+ end
285
+ end
286
+ return History::ModuleLog::state_char( History::ModuleLog::FINISHED_SUCCESSFUL )
287
+ end
288
+
289
+ def active_char
290
+ if active?
291
+ ANSI::Code.green { "A" }
292
+ else
293
+ "I"
294
+ end
295
+ end
296
+
220
297
  def vcs
221
298
  return vcs_configuration.vcs( self ) if vcs_configuration
222
299
  nil
@@ -225,10 +302,10 @@ def vcs
225
302
  attr_writer :vcs_configuration
226
303
  def vcs_configuration
227
304
  return @vcs_configuration if @vcs_configuration
228
- if @parent && @parent.vcs_configuration
229
- # puts "copying vcs for #{name} from #{@parent.name}"
230
- vc = @parent.vcs_configuration.class.new
231
- vc.copy_configuration( @parent.vcs_configuration )
305
+ if parent && parent.vcs_configuration
306
+ # puts "copying vcs for #{name} from #{parent.name}"
307
+ vc = parent.vcs_configuration.class.new
308
+ vc.copy_configuration( parent.vcs_configuration )
232
309
  @vcs_configuration = vc
233
310
  return vc
234
311
  end
@@ -261,6 +338,10 @@ def remove_build_directory
261
338
  build_system_required.remove_build_directory
262
339
  end
263
340
 
341
+ def remove_source_directory
342
+ build_system_required.remove_source_directory
343
+ end
344
+
264
345
  # Clone the repository.
265
346
  def clone
266
347
  vcs_required.clone
@@ -280,8 +361,8 @@ def fetch
280
361
 
281
362
  # Update the local changes with remote changes. Do not fetch changes
282
363
  # from the remote repository.
283
- def rebase
284
- vcs_required.rebase
364
+ def rebase( verbose )
365
+ vcs_required.rebase( verbose )
285
366
  if !patches.empty?
286
367
  if !vcs.patches_supported?
287
368
  raise NotImplementedError, "Patch support not implemented for vcs #{vcs.name}"
@@ -0,0 +1,64 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ require 'active_record'
4
+ require 'build-tool/state_helper'
5
+
6
+ module BuildTool
7
+
8
+ #
9
+ # Provide method to add and retrieve entries from the history
10
+ #
11
+ module History
12
+
13
+ # Represents a module event.
14
+ #
15
+ # A module event is updating, compiling etc. a module.
16
+ class ModuleLog < ActiveRecord::Base
17
+
18
+ include StateHelper
19
+
20
+ # A module event belongs to a command
21
+ belongs_to :command_log
22
+
23
+ # A module event belongs to a module
24
+ belongs_to :module, :foreign_key => :module, :primary_key => :name
25
+
26
+ def duration
27
+ if self.finished_at
28
+ dur = self.finished_at - self.started_at
29
+ "%02d:%02d" % [ dur.to_i / 60, (dur% 60 ).to_i ]
30
+ else
31
+ "-----"
32
+ end
33
+ end
34
+
35
+ # Call this if the command is finished. [:finished] will be set to Time.now,
36
+ # [:state] to the given value and the object is saved.
37
+ def finished( state )
38
+ self.finished_at = Time.now
39
+ self.state = state
40
+ save
41
+ end
42
+
43
+ # Call this when the command is started. [:started] will be set to Time.now and
44
+ # the object is saved.
45
+ def started
46
+ self.started_at = Time.now
47
+ save!
48
+ end
49
+
50
+ # Make sure a finished command has one of the accepted finished states.
51
+ def before_update
52
+ super
53
+ if !self.finished_at.nil?
54
+ raise StandardError, "Wrong state for finished Command" if ! [ FINISHED_SUCCESSFUL, FINISHED_WITH_ERRORS, CANCELED_BY_USER ].include? self.state
55
+ end
56
+ end
57
+
58
+ class << self
59
+
60
+ end # class self
61
+
62
+ end
63
+ end
64
+ end # module BuildTool::History
@@ -0,0 +1,84 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ require 'active_record'
4
+
5
+ module BuildTool
6
+
7
+ class Setting < ActiveRecord::Base
8
+
9
+ # Custom initialization
10
+ after_initialize :my_initialize
11
+ def my_initialize()
12
+ @description = nil
13
+ @default = ""
14
+ @seen = false
15
+ end
16
+
17
+ # The description for this setting
18
+ attr_accessor :description
19
+
20
+ # The default value for this setting
21
+ attr_accessor :default
22
+
23
+ # If the setting has been seen
24
+ attr_accessor :seen
25
+
26
+ def value()
27
+ rv = read_attribute( :value )
28
+ return @default if rv.nil?
29
+ rv
30
+ end
31
+
32
+ def to_hash()
33
+ return {
34
+ :name => name,
35
+ :value => value,
36
+ :description => description }
37
+ end
38
+
39
+ class<<self
40
+
41
+ def export( settings, only = [] )
42
+ only = settings.keys if only.empty?
43
+ values = []
44
+ only.sort.each do |name|
45
+ # Skip internal settings.
46
+ next if name.start_with?( 'BUILD_TOOL.' )
47
+ # Check for unknown settings.
48
+ if not settings.has_key?( name )
49
+ logger.warn( 'Unknown setting %s skipped' % name )
50
+ next
51
+ end
52
+ s = settings[name]
53
+ values << s.to_hash()
54
+ end
55
+ return values
56
+ end
57
+
58
+ def import( settings, new )
59
+ new.each do |v|
60
+ if not settings.has_key?( v[:name] )
61
+ logger.warn( 'Unknown setting %s skipped' % name )
62
+ next
63
+ end
64
+ s = settings[v[:name]]
65
+ if s.value != v[:value]
66
+ s.value = v[:value]
67
+ logger.info( 'Setting %s to "%s"' % [ s.name, s.value ] )
68
+ s.save!
69
+ end
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+ # #name is in the database.
76
+ validates_uniqueness_of :name
77
+
78
+ def to_s()
79
+ self.value.to_s
80
+ end
81
+
82
+ end # class Setting
83
+
84
+ end