Class: Squared::Workspace::Project::Base

Inherits:
Object
  • Object
show all
Includes:
Format, Rake::DSL, Shell, Common, System, Task, Utils
Defined in:
lib/squared/workspace/project/base.rb

Direct Known Subclasses

Git

Constant Summary collapse

SEM_VER =
/(\d+)(?:(\.)(\d+))?(?:(\.)(\d+)(\S+)?)?/.freeze
0
@@tasks =
{}

Constants included from Common

Common::KEY

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, path, workspace, group: nil, verbose: nil, pass: nil, exclude: nil, common: , pipe: , **kwargs) ⇒ Base

Returns a new instance of Base.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/squared/workspace/project/base.rb', line 55

def initialize(name, path, workspace, *,
               group: nil, verbose: nil, pass: nil, exclude: nil,
               common: Common::KEY[:COMMON], pipe: Common::KEY[:PIPE], **kwargs)
  @name = name.to_s
  @path = path
  @project = @path.basename.to_s
  @workspace = workspace
  @group = group&.to_s
  @depend = kwargs[:depend]
  @doc = kwargs[:doc]
  @test = kwargs[:test]
  @copy = kwargs[:copy]
  @clean = kwargs[:clean]
  @exception = workspace.exception
  @pipe = env_pipe(pipe, workspace.pipe)
  @verbose = verbose.nil? ? workspace.verbose : verbose
  @theme = if !@verbose
             {}
           elsif common
             workspace.theme
           else
             __get__(:theme)[:project][to_sym] ||= {}
           end
  @output = []
  @ref = []
  @children = []
  @pass = (pass ? as_a(pass, :to_sym) : []).freeze
  @exclude = (exclude ? as_a(exclude, :to_sym) : []).freeze
  @envname = @name.gsub(/[^\w]+/, '_').upcase
  @desc = @name.split(':').join(' => ')
  @global = false
  run_set kwargs[:run], kwargs[:env]
  initialize_ref(Base.ref)
end

Instance Attribute Details

#exceptionObject

Returns the value of attribute exception.



53
54
55
# File 'lib/squared/workspace/project/base.rb', line 53

def exception
  @exception
end

#groupObject (readonly)

Returns the value of attribute group.



52
53
54
# File 'lib/squared/workspace/project/base.rb', line 52

def group
  @group
end

#nameObject (readonly)

Returns the value of attribute name.



52
53
54
# File 'lib/squared/workspace/project/base.rb', line 52

def name
  @name
end

#parentObject (readonly)

Returns the value of attribute parent.



52
53
54
# File 'lib/squared/workspace/project/base.rb', line 52

def parent
  @parent
end

#pathObject (readonly)

Returns the value of attribute path.



52
53
54
# File 'lib/squared/workspace/project/base.rb', line 52

def path
  @path
end

#pipeObject

Returns the value of attribute pipe.



53
54
55
# File 'lib/squared/workspace/project/base.rb', line 53

def pipe
  @pipe
end

#projectObject (readonly)

Returns the value of attribute project.



52
53
54
# File 'lib/squared/workspace/project/base.rb', line 52

def project
  @project
end

#themeObject (readonly)

Returns the value of attribute theme.



52
53
54
# File 'lib/squared/workspace/project/base.rb', line 52

def theme
  @theme
end

#verboseObject

Returns the value of attribute verbose.



53
54
55
# File 'lib/squared/workspace/project/base.rb', line 53

def verbose
  @verbose
end

#workspaceObject (readonly)

Returns the value of attribute workspace.



52
53
54
# File 'lib/squared/workspace/project/base.rb', line 52

def workspace
  @workspace
end

Class Method Details

.as_path(val) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/squared/workspace/project/base.rb', line 31

def as_path(val)
  case val
  when ::Pathname
    val
  when ::String
    Pathname.new(val)
  end
end

.populateObject



25
# File 'lib/squared/workspace/project/base.rb', line 25

def populate(*); end

.refObject



40
41
42
# File 'lib/squared/workspace/project/base.rb', line 40

def ref
  @ref ||= to_s.downcase.to_sym
end

.tasksObject



27
28
29
# File 'lib/squared/workspace/project/base.rb', line 27

def tasks
  [].freeze
end

.to_sObject



44
45
46
# File 'lib/squared/workspace/project/base.rb', line 44

def to_s
  super.to_s.match(/[^:]+$/)[0]
end

Instance Method Details

#add(path, name = nil, **kwargs, &blk) ⇒ Object



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/squared/workspace/project/base.rb', line 223

def add(path, name = nil, **kwargs, &blk)
  return self unless source_path?(path = base_path(path))

  kwargs[:group] = group unless kwargs.key?(:group)
  kwargs[:ref] = ref unless kwargs.key?(:ref)
  parent = self
  proj = nil
  workspace.add(path, name || path.basename.to_s, **kwargs) do
    variable_set :parent, parent
    proj = self
  end
  @children << proj
  proj.instance_eval(&blk) if block_given?
  self
end

#base_path(*args) ⇒ Object



321
322
323
# File 'lib/squared/workspace/project/base.rb', line 321

def base_path(*args)
  path.join(*args)
end

#build(*args, sync: true) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/squared/workspace/project/base.rb', line 239

def build(*args, sync: true)
  if args.empty?
    cmd, opts, var = @output
    opts &&= shell_split(opts, join: true)
  else
    cmd = args.shift
    opts = args.map { |val| shell_quote(val, force: false) }.join(' ')
  end
  if cmd
    if opts
      cmd = "#{cmd} #{opts}"
    elsif cmd.is_a?(::Array)
      cmd = cmd.join(' && ')
    end
    banner = verbose != false
  else
    return unless respond_to?(:compose)

    cmd = compose(opts)
    banner = verbose == 1
  end
  run(cmd, var, banner: banner, sync: sync)
end

#build?Boolean

Returns:

  • (Boolean)


379
380
381
# File 'lib/squared/workspace/project/base.rb', line 379

def build?
  !!@output[0] || script?
end

#cleanObject



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/squared/workspace/project/base.rb', line 286

def clean
  case @clean
  when ::String
    run_s(@clean, sync: invoked_sync?('clean'))
  when ::Enumerable
    as_a(@clean).each do |val|
      if (val = val.to_s) =~ %r{[\\/]$}
        dir = Pathname.new(val)
        dir = base_path(dir) unless dir.absolute?
        next unless dir.directory?

        log.warn "rm -rf #{dir}"
        dir.rmtree(verbose: true)
      else
        files = val.include?('*') ? Dir[base_path(val)] : [base_path(val)]
        files.each do |file|
          begin
            File.delete(file) if File.file?(file)
          rescue StandardError => e
            log.error e
          end
        end
      end
    end
  end
end

#clean?Boolean

Returns:

  • (Boolean)


407
408
409
# File 'lib/squared/workspace/project/base.rb', line 407

def clean?
  runnable?(@clean) || workspace.task_defined?("#{name}:clean")
end

#color(val) ⇒ Object



325
326
327
328
# File 'lib/squared/workspace/project/base.rb', line 325

def color(val)
  ret = theme[val]
  ret && !ret.empty? ? ret : [val]
end

#copyObject



274
275
276
# File 'lib/squared/workspace/project/base.rb', line 274

def copy(*)
  run_s(@copy, sync: invoked_sync?('copy')) if @copy
end

#copy?Boolean

Returns:

  • (Boolean)


403
404
405
# File 'lib/squared/workspace/project/base.rb', line 403

def copy?
  runnable?(@copy) || workspace.task_defined?("#{name}:copy")
end

#dependObject



270
271
272
# File 'lib/squared/workspace/project/base.rb', line 270

def depend(*)
  run(@depend, sync: invoked_sync?('depend')) if @depend
end

#depend?Boolean

Returns:

  • (Boolean)


391
392
393
# File 'lib/squared/workspace/project/base.rb', line 391

def depend?
  @depend != false && (!@depend.nil? || has?('outdated'))
end

#dev?Boolean

Returns:

  • (Boolean)


411
412
413
# File 'lib/squared/workspace/project/base.rb', line 411

def dev?
  @dev != false && workspace.dev?(pat: @dev, **scriptargs)
end

#docObject



278
279
280
# File 'lib/squared/workspace/project/base.rb', line 278

def doc
  build(@doc, sync: invoked_sync?('doc')) if @doc
end

#doc?Boolean

Returns:

  • (Boolean)


395
396
397
# File 'lib/squared/workspace/project/base.rb', line 395

def doc?
  !!@doc
end

#enabled?(ref = nil) ⇒ Boolean

Returns:

  • (Boolean)


363
364
365
366
367
# File 'lib/squared/workspace/project/base.rb', line 363

def enabled?(ref = nil)
  return false if ref && !ref?(ref)

  path.directory? && !path.empty?
end

#has?(meth, ref = nil) ⇒ Boolean

Returns:

  • (Boolean)


369
370
371
372
373
# File 'lib/squared/workspace/project/base.rb', line 369

def has?(meth, ref = nil)
  return false if ref && !ref?(ref)

  respond_to?(meth = :"#{meth}?") && __send__(meth)
end

#initialize_build(ref, **kwargs) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/squared/workspace/project/base.rb', line 94

def initialize_build(ref, **kwargs)
  initialize_ref(ref)
  if (@script = @workspace.script(group: @group, ref: ref))
    if @script[:log] && !kwargs.key?(:log)
      kwargs[:log] = @script[:log]
      @log = nil
    end
    @depend = @script[:depend] if @depend.nil?
    @doc = @script[:doc] if @doc.nil?
    @test = @script[:test] if @test.nil?
    @clean = @script[:clean] if @clean.nil?
    @exclude = @script[:exclude] if @exclude.empty? && @script.key?(:exclude)
  end
  initialize_logger(**kwargs)
  return if @output[0] == false

  data = @workspace.script(*@ref, @group)
  if @output[0].nil?
    if (scr = data[:script])
      @global = true
      script_set(scr, prod: kwargs[:prod])
    elsif (run = data[:run])
      @global = true
      run_set run
    end
    unless data[:env]
      if (scr = kwargs[:script])
        @global = false
        script_set scr
      elsif @script && !data[:global]
        if (scr = @script[:script])
          @global = false
          script_set scr
        elsif (run = @script[:run])
          @global = false
          run_set run
        end
      end
    end
  elsif data[:env] && data[:run]
    @global = true
    run_set data[:run]
  end
end

#initialize_env(dev: nil, prod: nil) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/squared/workspace/project/base.rb', line 173

def initialize_env(dev: nil, prod: nil, **)
  prefix = "BUILD_#{@envname}"
  @dev = env_match("#{prefix}_DEV", dev)
  @prod = env_match("#{prefix}_PROD", prod)
  if (val = env('BUILD', suffix: 'ENV'))
    begin
      data = JSON.parse(val)
      raise_error('invalid JSON object', val, hint: "#{prefix}_ENV") unless data.is_a?(::Hash)
      @output[2] = data
    rescue StandardError => e
      log.warn e
    end
  end
  return unless (val = env('BUILD', strict: true))

  @global = false
  if script?
    script_set val
  else
    run_set(val, opts: false)
  end
end

#initialize_logger(log: nil) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/squared/workspace/project/base.rb', line 139

def initialize_logger(log: nil, **)
  return if @log

  log = log.is_a?(::Hash) ? log.dup : { file: log }
  if (file = env('LOG_FILE')).nil? && (auto = env('LOG_AUTO'))
    file = case auto
           when 'y', 'year'
             "#{@name}-#{Date.today.year}.log"
           when 'm', 'month'
             "#{@name}-#{Date.today.strftime('%Y-%m')}.log"
           when 'd', 'day', '1'
             "#{@name}-#{Date.today}.log"
           end
  end
  if file ||= log[:file]
    file = Date.today.strftime(file)
    file = (dir = env('LOG_DIR')) ? Pathname.new(dir).join(file) : Pathname.new(file)
    begin
      file = file.realdirpath
    rescue StandardError => e
      raise if @exception

      file = nil
      warn log_message(::Logger::WARN, e) if warning?
    end
  end
  log[:progname] ||= @name
  if (val = env('LOG_LEVEL', ignore: nil))
    log[:level] = val
  end
  log.delete(:file)
  @log = [file, log]
end

#initialize_ref(ref) ⇒ Object



90
91
92
# File 'lib/squared/workspace/project/base.rb', line 90

def initialize_ref(ref)
  @ref << ref unless @exclude.include?(ref)
end

#inspectObject



351
352
353
# File 'lib/squared/workspace/project/base.rb', line 351

def inspect
  "#<#{self.class}: #{name} => #{self}>"
end

#logObject



313
314
315
316
317
318
319
# File 'lib/squared/workspace/project/base.rb', line 313

def log
  if @log.is_a?(::Array)
    @log = Logger.new(enabled? ? @log[0] : nil, **@log[1])
  else
    @log
  end
end

#populateObject



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/squared/workspace/project/base.rb', line 200

def populate(*)
  check = lambda do |proj, key|
    workspace.series.include?(key) ? proj.has?(key, Base.ref) : workspace.task_extend?(proj, key)
  end

  namespace name do
    workspace.series.each_key do |key|
      next unless check.(self, key)

      unless workspace.task_defined?("#{name}:#{key}")
        desc message(@desc, key)
        task key do
          __send__(key)
        end
      end
      next if (items = @children.select { |item| check.(item, key) }).empty?

      desc message(@desc, key, 'workspace')
      task "#{key}:workspace" => items.map { |item| "#{item.name}:#{key}" }
    end
  end
end

#prod?Boolean

Returns:

  • (Boolean)


415
416
417
# File 'lib/squared/workspace/project/base.rb', line 415

def prod?
  @prod != false && workspace.prod?(pat: @prod, **scriptargs)
end

#refObject



196
197
198
# File 'lib/squared/workspace/project/base.rb', line 196

def ref
  Base.ref
end

#ref?(val) ⇒ Boolean

Returns:

  • (Boolean)


375
376
377
# File 'lib/squared/workspace/project/base.rb', line 375

def ref?(val)
  @ref.include?(val)
end

#refreshObject



263
264
265
266
267
268
# File 'lib/squared/workspace/project/base.rb', line 263

def refresh(*)
  build(sync: invoked_sync?('refresh') || invoked_sync?('build'))
  return if run_task "#{name}:copy"

  copy if copy?
end

#refresh?Boolean

Returns:

  • (Boolean)


387
388
389
# File 'lib/squared/workspace/project/base.rb', line 387

def refresh?
  build? && copy?
end

#script?Boolean

Returns:

  • (Boolean)


383
384
385
# File 'lib/squared/workspace/project/base.rb', line 383

def script?
  @output[0].nil? && !!@output[1] && respond_to?(:compose)
end

#testObject



282
283
284
# File 'lib/squared/workspace/project/base.rb', line 282

def test
  build(@test, sync: invoked_sync?('test')) if @test
end

#test?Boolean

Returns:

  • (Boolean)


399
400
401
# File 'lib/squared/workspace/project/base.rb', line 399

def test?
  !!@test
end

#to_sObject



355
356
357
# File 'lib/squared/workspace/project/base.rb', line 355

def to_s
  path.to_s
end

#to_symObject



359
360
361
# File 'lib/squared/workspace/project/base.rb', line 359

def to_sym
  name.to_sym
end

#variable_allObject



347
348
349
# File 'lib/squared/workspace/project/base.rb', line 347

def variable_all
  VAR_SET
end

#variable_set(key, *val, **kwargs) ⇒ Object



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/squared/workspace/project/base.rb', line 330

def variable_set(key, *val, **kwargs)
  if variable_all.include?(key)
    case key
    when :run
      run_set(*val, opts: false, **kwargs)
    when :script
      script_set(*val, **kwargs)
    when :env
      run_set(output[0], *val, opts: false, **kwargs)
    else
      instance_variable_set :"@#{key}", val.first
    end
  else
    log.warn "variable_set: @#{key} (not defined)"
  end
end