build-tool 0.5.7 → 0.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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