squared 0.0.10 → 0.0.12

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.
@@ -1,16 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rexml/document'
4
+
3
5
  module Squared
4
6
  module Workspace
5
7
  module Repo
6
- include Common
7
- include Format
8
- include System
9
- include Utils
8
+ include Common::Format
10
9
 
11
10
  class << self
12
11
  def read_manifest(path)
13
- require 'rexml/document'
14
12
  return unless (file = path.join('.repo/manifest.xml')).exist?
15
13
 
16
14
  doc = REXML::Document.new(file.read)
@@ -22,6 +20,8 @@ module Squared
22
20
  end
23
21
  end
24
22
 
23
+ attr_reader :manifest_url, :manifest
24
+
25
25
  def repo(url, manifest = 'latest', run: nil, script: nil, dev: nil, prod: nil, ref: @ref, group: @group)
26
26
  @home = if (val = env('REPO_HOME'))
27
27
  home = Pathname.new(val)
@@ -59,10 +59,10 @@ module Squared
59
59
  when 'verbose'
60
60
  @verbose = 1
61
61
  if script.is_a?(::Array)
62
- script[0] = "#{script[0]}:verbose"
62
+ script[0] = task_join(script[0], 'verbose')
63
63
  script
64
64
  else
65
- "#{script}:verbose"
65
+ task_join(script, 'verbose')
66
66
  end
67
67
  when 'silent'
68
68
  @verbose = false
@@ -114,7 +114,7 @@ module Squared
114
114
  kwargs.delete(:parallel) if env('REPO_SYNC', ignore: '0')
115
115
 
116
116
  branch = env('REPO_MANIFEST') || Repo.read_manifest(root)
117
- target = branch || @manifest
117
+ target = branch || manifest
118
118
  stage = nil
119
119
  failfast = true
120
120
  cmd = []
@@ -140,22 +140,31 @@ module Squared
140
140
  status = lambda do |val, alt = nil|
141
141
  return 'inactive' unless (ver = branch || alt)
142
142
 
143
- message(@prefix || '', 'repo', val.sub('{0}', 'opts*=force,rebase,detach,gc,no-update,no-fail'), ver)
143
+ message(@prefix, 'repo', val.sub('{0}', 'opts*=force,rebase,detach,gc,no-update,no-fail'), ver, empty: true)
144
144
  end
145
145
 
146
- namespace task_name('repo') do |repo|
146
+ namespace(name = task_name('repo')) do |repo|
147
147
  desc status.('all[{0}]')
148
148
  task 'all', [:opts] do |_, args|
149
149
  parse_opts.(args)
150
150
  stage ||= 'all'
151
151
  repo['sync'].invoke
152
152
  @project.select do |_, proj|
153
- next unless proj.enabled?(Project::Base.ref)
153
+ next unless proj.enabled?(proj.workspace.baseref)
154
154
 
155
- proj.depend if proj.depend?
155
+ proj.depend(sync: true) if proj.depend?
156
156
  proj.build?
157
157
  end
158
- .each_value { |proj| proj.has?('dev') ? proj.refresh : proj.build }
158
+ .each_value do |proj|
159
+ proj.build(sync: true)
160
+ next unless proj.dev? && proj.copy?
161
+
162
+ if (ws = proj.workspace).task_defined?(target = ws.task_name(task_join(proj.name, 'copy')))
163
+ task_invoke(target, **ws.invokeargs)
164
+ else
165
+ proj.copy(sync: true)
166
+ end
167
+ end
159
168
  end
160
169
 
161
170
  desc status.("init[manifest?=#{target},{0}]", target)
@@ -163,7 +172,7 @@ module Squared
163
172
  parse_opts.(args)
164
173
  stage = 'init'
165
174
  puts if newline
166
- system("repo init -u #{@manifest_url} -m #{args.manifest || target}.xml", chdir: root)
175
+ system("repo init -u #{manifest_url} -m #{args.manifest || target}.xml", chdir: root)
167
176
  repo['all'].invoke
168
177
  end
169
178
 
@@ -177,20 +186,25 @@ module Squared
177
186
  cmd << '--fail-fast' if failfast
178
187
  puts if newline && stage != 'init'
179
188
  begin
180
- shell("repo sync #{cmd.join(' ')}", chdir: root, exception: failfast)
189
+ Common::System.shell("repo sync #{cmd.join(' ')}", chdir: root, exception: failfast)
181
190
  rescue StandardError => e
182
- emphasize(e, title: "rake stash #{task_name("repo:#{stage || 'sync'}")}")
191
+ emphasize(e, title: "rake stash #{task_name(task_join('repo', stage || 'sync'))}")
183
192
  raise
184
193
  end
185
194
  end
186
195
  end
196
+ series.sync.push(
197
+ task_join(name, 'all'),
198
+ task_join(name, 'init'),
199
+ task_join(name, 'sync')
200
+ )
187
201
  end
188
202
 
189
203
  def repo_confirm
190
204
  return false unless root.directory?
191
205
 
192
206
  path = sub_style(root, styles: theme[:inline])
193
- @override = confirm(
207
+ @repo_override = Common::Prompt.confirm(
194
208
  "#{log_title(:warn)} \"#{path}\" is not empty. Continue with installation? [y/N] ",
195
209
  'N',
196
210
  timeout: env('REPO_TIMEOUT', 15, ignore: '0')
@@ -198,7 +212,7 @@ module Squared
198
212
  end
199
213
 
200
214
  def repo?
201
- !@manifest_url.nil? && (repo_install? || !!@override)
215
+ !manifest_url.nil? && (repo_install? || @repo_override == true)
202
216
  end
203
217
 
204
218
  def repo_install?(dir = root, parent: false)
@@ -8,22 +8,52 @@ module Squared
8
8
  include ::Rake::DSL
9
9
  extend Forwardable
10
10
 
11
- TASK_BASE = %i[build refresh depend outdated doc test copy clean].freeze
12
- TASK_ALIAS = {
13
- refresh: :build
14
- }
15
- TASK_KEYS = TASK_BASE.dup
11
+ TASK_BASE = %i[build depend graph doc test copy clean]
12
+ TASK_BATCH = {}
16
13
  TASK_EXTEND = {}
17
- private_constant :TASK_BASE, :TASK_ALIAS, :TASK_KEYS, :TASK_EXTEND
14
+ TASK_KEYS = TASK_BASE.dup + TASK_BATCH.keys
15
+ TASK_ALIAS = {}
16
+ TASK_NAME = {}
17
+ private_constant :TASK_BASE, :TASK_BATCH, :TASK_KEYS, :TASK_NAME, :TASK_EXTEND
18
18
 
19
19
  class << self
20
20
  def add(task, obj)
21
- TASK_KEYS << task unless TASK_KEYS.include?(task)
21
+ key_set task
22
22
  (TASK_EXTEND[task] ||= []).push(obj)
23
23
  end
24
24
 
25
- def alias(key, task)
26
- TASK_ALIAS[key.to_sym] = task.to_sym
25
+ def batch(*args, obj)
26
+ if obj.is_a?(::Hash)
27
+ obj.each do |key, val|
28
+ key_set key
29
+ data = TASK_BATCH[key] ||= {}
30
+ args.each { |ref| (data[ref] ||= []).concat(val) }
31
+ end
32
+ elsif (data = TASK_BATCH[obj])
33
+ args.each { |ref| data.delete(ref) }
34
+ TASK_KEYS.delete(obj) if data.empty?
35
+ end
36
+ end
37
+
38
+ def alias(ref, obj)
39
+ if obj.is_a?(::Hash)
40
+ obj.each { |key, val| (TASK_ALIAS[key] ||= {})[ref] = val }
41
+ else
42
+ TASK_ALIAS[obj]&.delete(ref)
43
+ end
44
+ end
45
+
46
+ def rename(key, task)
47
+ TASK_NAME[key.to_sym] = task.to_sym
48
+ end
49
+
50
+ private
51
+
52
+ def key_set(val)
53
+ return if TASK_KEYS.include?(val)
54
+
55
+ TASK_KEYS << val
56
+ TASK_BASE.delete(val)
27
57
  end
28
58
  end
29
59
 
@@ -45,57 +75,48 @@ module Squared
45
75
  TASK_KEYS.each { |key| @data[key] = [] }
46
76
  end
47
77
 
48
- def __set__(key)
49
- @data[key.to_sym] ||= []
50
- end
51
-
52
- def __populate__(proj)
53
- return unless @session
54
-
78
+ def populate(proj)
55
79
  group, parent, id = @session.values
56
80
  ws = proj.workspace
57
- ref = Project::Base.ref
58
81
  @data.each do |key, items|
59
- task = "#{proj.name}:#{key}"
60
- unless (base = include?(key)) ? proj.has?(key, ref) : ws.task_extend?(proj, key)
61
- next if (base && !proj.ref?(ref)) || (alt = TASK_ALIAS[key]).nil?
62
-
63
- task = "#{proj.name}:#{alt}"
64
- end
65
- next unless ws.task_defined?(task)
82
+ next if (tasks = ws.task_resolve(proj, key)).empty?
66
83
 
67
84
  if (g = proj.group)
68
85
  id << g
69
- (group[:"#{key}:#{g}"] ||= []).push(task)
86
+ (group[:"#{key}:#{g}"] ||= []).concat(tasks)
70
87
  else
71
- items << task
88
+ items.concat(tasks)
89
+ end
90
+ if tasks.size > 1 && (data = batch_get(key)) && data.keys.any? { |ref| proj.ref?(ref) }
91
+ desc ws.task_name(t = ws.task_join(proj.name, key), desc: true)
92
+ task ws.task_name(t) => tasks
72
93
  end
73
- next unless (b = ws.find_base(proj)) && (name = b.ref.to_s) != g
94
+ next unless (b = ws.find_base(proj)) && (n = b.ref.to_s) != g
74
95
 
75
- id << name
76
- (parent[:"#{key}:#{name}"] ||= []).push(task)
96
+ id << n
97
+ (parent[:"#{key}:#{n}"] ||= []).concat(tasks)
77
98
  end
78
99
  end
79
100
 
80
- def __build__(parallel: [], **)
81
- group, parent, id = @session.values
82
- @data.merge!(parent) if id.uniq.size > 1
83
- @data.merge!(group)
101
+ def build(parallel: [], **)
102
+ @data.merge!(@session[:parent]) if @session[:id].uniq.size > 1
103
+ @data.merge!(@session[:group])
84
104
  @data.each do |key, items|
85
105
  next if items.empty?
86
106
 
87
- key = @workspace.task_name(name = key.to_s)
88
- val = @workspace.task_name(name, desc: true)
107
+ key = @workspace.task_name(t = name_get(key))
108
+ val = @workspace.task_name(t, desc: true)
89
109
  if items.size > 1
90
110
  @multiple << key
91
- if parallel.include?(name) || ((ns = @workspace.task_namespace(name)) && parallel.include?(ns))
111
+ if parallel.include?(t) || ((ns = @workspace.task_namespace(t)) && parallel.include?(ns))
92
112
  desc "#{val} (thread)"
93
113
  multitask key => items
94
114
  @parallel << key
95
115
 
116
+ s = @workspace.task_join(key, 'sync')
96
117
  desc "#{val} (sync)"
97
- task "#{key}:sync" => items
98
- @sync << "#{key}:sync"
118
+ task s => items
119
+ @sync << s
99
120
  next
100
121
  end
101
122
  end
@@ -103,19 +124,31 @@ module Squared
103
124
  desc val
104
125
  task key => items
105
126
  end
106
- TASK_ALIAS.each_key do |key|
107
- suf = ":#{key}"
108
- @data[key].clear unless @data[key].any? { |val| val.end_with?(suf) }
109
- end
110
127
  @multiple += sync
111
- @session = nil
128
+ end
129
+
130
+ def name_get(key)
131
+ (TASK_NAME[key] || key).to_s
132
+ end
133
+
134
+ def batch_get(key)
135
+ TASK_BATCH[key]
136
+ end
137
+
138
+ def alias_get(key)
139
+ TASK_ALIAS[key]
112
140
  end
113
141
 
114
142
  def some?(key)
115
- @data.key?(key) && !@data[key].empty?
143
+ return @data.key?(key) && !@data[key].empty? unless (batch = batch_get(key))
144
+
145
+ batch.each_value do |items|
146
+ return true if items.all? { |val| some?(val) || alias_get(val)&.any? { |_, alt| some?(alt) } }
147
+ end
148
+ false
116
149
  end
117
150
 
118
- def include?(key)
151
+ def base?(key)
119
152
  TASK_BASE.include?(key)
120
153
  end
121
154
 
@@ -137,17 +170,13 @@ module Squared
137
170
 
138
171
  private
139
172
 
140
- def method_missing(key, *)
141
- raise NoMethodError, key unless @data.key?(key)
142
-
143
- @data[key]
144
- end
145
-
146
173
  def already_invoked?(list, val)
147
- return list.include?(val) && Common::Task.invoked?(val) if val
174
+ return false if val && !list.include?(val)
148
175
 
149
- ::Rake::Task.tasks.any? { |obj| obj.already_invoked && list.include?(obj.name) }
176
+ ::Rake::Task.tasks.any? { |obj| obj.already_invoked && (val ? val == obj.name : list.include?(obj.name)) }
150
177
  end
151
178
  end
179
+
180
+ Application.impl_series = Series
152
181
  end
153
182
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'common'
4
-
5
3
  module Squared
6
4
  module Workspace
7
5
  class << self
@@ -23,7 +21,7 @@ module Squared
23
21
  ret = project(name)
24
22
  return ret if ret&.path&.directory?
25
23
 
26
- raise NoMethodError, message('project is not initialized', hint: name)
24
+ raise NoMethodError, "project is not initialized (#{name})"
27
25
  end
28
26
 
29
27
  def dirpath(val, absolute: true)
@@ -39,12 +37,15 @@ module Squared
39
37
  private
40
38
 
41
39
  def project(name)
42
- __get__(:project)[name.to_sym]
40
+ __get__(:project)[name.to_s]
43
41
  end
44
42
  end
45
43
  end
46
44
  end
47
45
 
48
- require_relative 'workspace/series'
49
46
  require_relative 'workspace/application'
47
+ require_relative 'workspace/series'
50
48
  require_relative 'workspace/project'
49
+
50
+ Workspace = Squared::Workspace
51
+ Project = Squared::Workspace::Project
data/lib/squared.rb CHANGED
@@ -1,14 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'squared/version'
4
- require_relative 'squared/workspace'
5
-
6
- Workspace = Squared::Workspace
7
- Project = Squared::Workspace::Project
8
-
9
- Workspace::Application.implement(
10
- Project::Git,
11
- Project::Node,
12
- Project::Python,
13
- Project::Ruby
14
- )
4
+ require_relative 'squared/common'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-21 00:00:00.000000000 Z
11
+ date: 2024-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -63,13 +63,14 @@ files:
63
63
  - README.md
64
64
  - README.ruby.md
65
65
  - lib/squared.rb
66
+ - lib/squared/app.rb
66
67
  - lib/squared/common.rb
67
68
  - lib/squared/common/base.rb
68
69
  - lib/squared/common/class.rb
69
70
  - lib/squared/common/format.rb
71
+ - lib/squared/common/prompt.rb
70
72
  - lib/squared/common/shell.rb
71
73
  - lib/squared/common/system.rb
72
- - lib/squared/common/task.rb
73
74
  - lib/squared/common/utils.rb
74
75
  - lib/squared/config.rb
75
76
  - lib/squared/version.rb
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rake'
4
-
5
- module Squared
6
- module Common
7
- module Task
8
- module_function
9
-
10
- def invoke(series, *args, exception: true, warning: true)
11
- series = [series] unless series.is_a?(::Array)
12
- series.each { |name| ::Rake::Task[name].invoke(*args) }
13
- rescue StandardError => e
14
- raise if exception
15
-
16
- warn e if warning
17
- end
18
-
19
- def invoked?(name)
20
- ::Rake::Task.tasks.any? { |obj| obj.already_invoked && obj.name == name.to_s }
21
- end
22
- end
23
- end
24
- end