squared 0.0.1 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 867bfab9c2ffade3d9158228c67fca5f0f4675ecd24a3d7201d0b85f42945d8f
4
- data.tar.gz: 0ee6b84388949cd03c7a0667e7bd0d8aab8b3b30c597da6ae8b486fa3063d89e
3
+ metadata.gz: ef428776d582a23bb5560efdc5c6f6d77fa5fb1adaecca5f11500b978126283a
4
+ data.tar.gz: cd8dfbae3f5162b55fd081ac65e31f0e2fca1167d4932e52ccd723f128a1a312
5
5
  SHA512:
6
- metadata.gz: ce95fe135ead9dec6e92106955e921442f3a9fe73a8a11863a8d3022187065056236b52449b8e40e30cd34bd3a95c949a296817af30932b9edc64032cb255919
7
- data.tar.gz: 63d8d2d3e22572d614b3a3d214427a1864cb528c5231e107db984949214955efa804376548b769f90ee7390223dd2b7715fd85ad78d2f15b85e77fe4b48b710e
6
+ metadata.gz: e8bf3197a021dadc3bf8d15d4f80d5064a4254359a23b9e7576babe716189e0d17564acae48e018fc64b7caddde250f53eb479cae3e4997d7a3792fe66e07d5a
7
+ data.tar.gz: 312231359e1bd8f7052c91250234750ba9c41f5be1b806e852c60517d4c04e8d4ef55450d1b65fb35a946b2c6138d83bccc8280587b6c5b9832d717fa377c84a
data/README.md CHANGED
@@ -81,13 +81,13 @@
81
81
  #### Install
82
82
 
83
83
  ```sh
84
- mkdir -p ~/.bin
85
- PATH="${HOME}/.bin:${PATH}"
84
+ mkdir -p ~/bin/repo
85
+ PATH="${HOME}/bin:${PATH}"
86
86
 
87
- curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
88
- chmod a+rx ~/.bin/repo
87
+ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
88
+ chmod a+rx ~/bin/repo
89
89
  # OR
90
- scripts/repo-install.sh ~/.bin
90
+ scripts/repo-install.sh ~/bin
91
91
  ```
92
92
 
93
93
  #### Usage
data/README.ruby.md CHANGED
@@ -4,17 +4,14 @@
4
4
  * [manifest](https://github.com/anpham6/squared-repo)
5
5
  * [docs](https://squared.readthedocs.io)
6
6
 
7
- ## Installation
8
-
9
- ```sh
10
- gem install squared
11
- ```
12
-
13
7
  ## Prerequisites
14
8
 
15
9
  * Ruby 2.4+
16
- * Python 3.6+
10
+
11
+ ### Optional
12
+
17
13
  * [Repo](https://source.android.com/docs/setup/reference/repo)
14
+ * Python 3.6+
18
15
 
19
16
  ```sh
20
17
  mkdir -p ~/.bin
@@ -23,26 +20,64 @@ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
23
20
  chmod a+rx ~/.bin/repo
24
21
  ```
25
22
 
23
+ ## Installation
24
+
25
+ ```sh
26
+ gem install squared
27
+ ```
28
+
26
29
  ## Example - Rakefile
27
30
 
28
31
  ```ruby
29
32
  require "squared"
30
33
 
31
34
  Repo::Workspace
32
- .new("squared")
33
- .repo("https://github.com/anpham6/squared-repo", "nightly")
34
- .add(:pathname, run: "rake compile", copy: "rake install", clean: "rake clean", ref: :ruby, group: "default") # Ruby
35
- .add(:optparse, group: "default")
36
- .add(:emc, "e-mc", copy: { from: "publish", into: "@e-mc", also: [:pir] }) # Node
37
- .add(:pir, "pi-r", copy: { from: "publish", into: "@pi-r" })
38
- .add(:squared)
39
- .build(parallel: %i[pull fetch rebase copy clean])
35
+ .new("squared") # REPO_HOME
36
+ .repo("https://github.com/anpham6/squared-repo", "nightly", run: 'build') # Optional
37
+ .run("rake install", ref: :ruby)
38
+ .clean("rake clean", group: "default") # depend test doc
39
+ .clean(["build/"], group: "app")
40
+ .add("pathname", run: "rake compile", copy: "rake install", test: "rake test", group: "default", ref: :ruby) # Ruby (with C extensions)
41
+ .add("optparse", doc: "rake rdoc", group: "default") # Uses bundler/gem_tasks (without C extensions)
42
+ .add("logger", copy: { from: "lib", glob: "**/*.rb", gemdir: "~/.rvm/gems/ruby-3.3.5/gems/logger-1.6.1" }, clean: ["tmp/"]) # autodetect: true
43
+ .add("android", "android-docs", run: false, doc: "make html", ref: :python) # task namespace "android" | directory "android-docs"
44
+ .add("emc", "e-mc", copy: { from: "publish", into: "@e-mc", also: [:pir, "squared-express/"] }, ref: :node) # Node
45
+ .add("pir", "pi-r", copy: { from: "publish", into: "@pi-r" }, clean: ["publish/**/*.js", "tmp/"]) # Trailing slash required for directories
46
+ .add("squared", log: { file: "tmp/%Y-%m-%d.log", level: "debug" }, group: "app") # Copy target (main)
47
+ .style(:banner, 255.255) # 256 colors (fg | fg.bg | -0.bg)
48
+ .build(default: "status", parallel: ["pull", "fetch", "rebase", "copy", "clean"]) do |workspace|
49
+ workspace
50
+ .enable_aixterm
51
+ .style(:banner, "bright_cyan", "bold", "bright_black!")
52
+ .finalize! # Optional
53
+ end
40
54
  ```
41
55
 
56
+ **NOTE**: The use of "**ref**" (class name) is only necessary when running `repo:init` for the first time into an empty directory.
57
+
42
58
  ## Usage
43
59
 
44
60
  ```sh
45
- rake -T
61
+ rake -T # List tasks
62
+ rake # rake status (usually "build")
63
+
64
+ # GIT_OPTIONS=rebase
65
+ rake pull # All except "default" + "app"
66
+ rake pull:ruby # pathname + optparse + logger
67
+ rake pull:default # pathname + optparse
68
+ rake pull:app # squared
69
+ rake pull:node # emc + pir + squared
70
+
71
+ rake build # All except "android"
72
+ rake doc # optparse + android
73
+
74
+ rake build:ruby # rake compile + rake install + rake install
75
+
76
+ rake clean # All except "default" + "app"
77
+ rake clean:ruby # rake clean + rake clean + ["tmp/"]
78
+ rake clean:default # rake clean + rake clean + skip
79
+ rake clean:app # none + skip + ["build/"]
80
+ rake clean:node # none + ["publish/**/*.js", "tmp/"] + ["build/"]
46
81
  ```
47
82
 
48
83
  ## LICENSE
@@ -1,8 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'set'
4
+
3
5
  module Squared
4
6
  module Common
5
7
  class JoinSet < ::Set
8
+ def self.to_s
9
+ /[^:]+$/.match(super.to_s)[0]
10
+ end
11
+
6
12
  def initialize(data = [], delim: ' ')
7
13
  super(data.compact)
8
14
  @delim = delim
@@ -3,7 +3,37 @@
3
3
  module Squared
4
4
  module Common
5
5
  module Format
6
- def emphasize(val, title: nil, cols: nil, sub: nil)
6
+ include Common
7
+
8
+ AIX_TERM = {
9
+ bright_black: '90',
10
+ bright_red: '91',
11
+ bright_green: '92',
12
+ bright_yellow: '93',
13
+ bright_blue: '94',
14
+ bright_magenta: '95',
15
+ bright_cyan: '96',
16
+ bright_white: '97',
17
+ bright_black!: '100',
18
+ bright_red!: '101',
19
+ bright_green!: '102',
20
+ bright_yellow!: '103',
21
+ bright_blue!: '104',
22
+ bright_magenta!: '105',
23
+ bright_cyan!: '106',
24
+ bright_white!: '107'
25
+ }.freeze
26
+ TEXT_STYLE = [:bold, :dim, :italic, :underline, :blinking, nil, :inverse, :hidden, :strikethrough].freeze
27
+ private_constant :AIX_TERM, :TEXT_STYLE
28
+
29
+ def enable_aixterm
30
+ unless (colors = __get__(:colors)).frozen?
31
+ colors.merge!(AIX_TERM)
32
+ end
33
+ block_given? ? yield(self) : self
34
+ end
35
+
36
+ def emphasize(val, title: nil, cols: nil, sub: nil, pipe: nil)
7
37
  n = 0
8
38
  if title
9
39
  title = title.to_s
@@ -20,21 +50,27 @@ module Squared
20
50
  require 'io/console'
21
51
  (n = [n, $stdout.winsize[1] - 4].min) rescue nil
22
52
  end
53
+ out = []
23
54
  bord = '-' * (n + 4)
24
- write = ->(line) { err ? warn(line) : puts(line) }
25
55
  sub = as_a(sub)
26
56
  pr = lambda do |line|
27
57
  s = line.ljust(n)
28
58
  sub.each { |h| s = sub_style(s, **h) }
29
59
  "| #{s} |"
30
60
  end
31
- write.(bord)
32
- if title
33
- write.(pr.(title))
34
- write.(bord)
61
+ out << bord
62
+ out.push(pr.(title), bord) if title
63
+ lines.each { |line| out << pr.(line) }
64
+ out << bord
65
+ if block_given?
66
+ yield out
67
+ elsif pipe.respond_to?(:puts)
68
+ pipe.puts out
69
+ elsif err
70
+ defined?(__warn__) == 'method' ? __warn__(out) : warn(out)
71
+ else
72
+ puts out
35
73
  end
36
- lines.each { |line| write.(pr.(line)) }
37
- write.(bord)
38
74
  end
39
75
 
40
76
  def sub_style(val, *args, pat: nil, styles: nil, index: 1)
@@ -59,20 +95,25 @@ module Squared
59
95
  else
60
96
  s = ret
61
97
  end
62
- case (t = type.to_sym)
63
- when :bold
64
- s = "\x1B[1m#{s}\x1B[22m"
65
- when :italic
66
- s = "\x1B[3m#{s}\x1B[23m"
67
- when :underline
68
- s = "\x1B[4m#{s}\x1B[24m"
98
+ if type.is_a?(Numeric)
99
+ f, b = type.to_s.split('.')
100
+ s = wrap.(s, ['38', '5', f]) if f[0] != '-' && f.to_i <= 255
101
+ if b
102
+ b = b[0..2]
103
+ s = wrap.(s, ['48', '5', b]) unless b.to_i > 255
104
+ end
69
105
  else
70
- if (c = get(:colors)[t])
106
+ t = type.to_sym
107
+ if (c = __get__(:colors)[t])
71
108
  if index == -1
72
109
  s = wrap.(s, [c])
73
110
  else
74
111
  code << c
75
112
  end
113
+ else
114
+ next unless (n = TEXT_STYLE.index { |style| style == t })
115
+
116
+ s = "\x1B[#{n + 1}m#{s}\x1B[#{n == 0 ? 22 : n + 21}m"
76
117
  end
77
118
  end
78
119
  if index == -1
@@ -99,20 +140,34 @@ module Squared
99
140
  out
100
141
  end
101
142
 
102
- def check_style(iter, empty: true)
143
+ def check_style(*args, empty: true)
103
144
  ret = []
104
- colors = get(:colors)
105
- as_a(iter).each do |val|
106
- case (val = val.to_sym)
107
- when :bold, :italic, :underline
145
+ colors = __get__(:colors)
146
+ as_a(args, flat: true).each do |val|
147
+ if !val.is_a?(Numeric)
148
+ val = val.to_sym
149
+ ret << val if colors.key?(val) || TEXT_STYLE.include?(val)
150
+ elsif val >= 0 && val <= 256
108
151
  ret << val
109
- else
110
- ret << val if colors.key?(val)
152
+ elsif val < 0 && (b = val.to_s.split('.')[1])
153
+ b = b[0..2]
154
+ ret << "-0.#{b}".to_f unless b.to_i > 255
111
155
  end
112
156
  end
113
157
  !empty && ret.empty? ? nil : ret
114
158
  end
115
159
 
160
+ def apply_style(data, key, *args, empty: true)
161
+ return unless !data.is_a?(Symbol) || (data = __get__(:theme)[data])
162
+
163
+ set = ->(k, v) { data[k.to_sym] = check_style(v, empty: empty) }
164
+ if key.is_a?(Hash)
165
+ key.each { |k, v| set.(k, v || args.flatten) }
166
+ else
167
+ set.(key, args.flatten)
168
+ end
169
+ end
170
+
116
171
  def log_title(level, color: true)
117
172
  level = if level.is_a?(::Numeric)
118
173
  case level
@@ -132,7 +187,8 @@ module Squared
132
187
  else
133
188
  level.to_s.downcase.to_sym
134
189
  end
135
- val = get(:logger)[level] || get(:logger)[level = :unknown]
190
+ theme = __get__(:theme)[:logger]
191
+ val = theme[level] || theme[level = :unknown]
136
192
  level = +level.to_s.upcase
137
193
  case level
138
194
  when 'WARN', 'ERROR', 'FATAL'
@@ -6,16 +6,24 @@ module Squared
6
6
  def shell_escape(val)
7
7
  return val if ::Rake::Win32.windows?
8
8
 
9
+ require 'shellwords'
9
10
  Shellwords.escape(val)
10
11
  end
11
12
 
12
13
  def shell_quote(val, force: true)
13
14
  ret = val.to_s.strip
14
- return ret if (!force && !ret.include?(' ')) || /(?:^|=)(["']).+\1$/m.match?(ret)
15
+ return ret if (!force && !ret.include?(' ')) || ret.match?(/(?:^|=)(["']).+\1$/m)
15
16
 
16
17
  ::Rake::Win32.windows? ? "\"#{double_quote(ret)}\"" : "'#{single_quote(ret)}'"
17
18
  end
18
19
 
20
+ def fill_option(val)
21
+ return "-#{val}" if val.size == 1 || val.match?(/^[a-z]\d+$/i)
22
+
23
+ val = "--#{val}" unless val.start_with?('-')
24
+ shell_escape(val).sub('\\=', '=')
25
+ end
26
+
19
27
  def single_quote(val)
20
28
  val.gsub("'", "'\\\\''")
21
29
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pathname'
4
+
3
5
  module Squared
4
6
  module Common
5
7
  module System
@@ -16,7 +18,7 @@ module Squared
16
18
  end
17
19
 
18
20
  def copy_d(src, dest, glob: ['**/*'], create: false, verbose: true)
19
- raise message(src, dest, hint: 'not found') if !create && !dest.exist?
21
+ raise "#{dest} (not found)" if !create && !dest.exist?
20
22
 
21
23
  subdir = []
22
24
  files = 0
@@ -36,7 +38,7 @@ module Squared
36
38
  files += 1
37
39
  end
38
40
  end
39
- puts message(dest.realpath, subdir.size.to_s, files.to_s) if verbose
41
+ puts [dest.realpath, subdir.size.to_s, files.to_s].join(' => ') if verbose
40
42
  end
41
43
 
42
44
  def copy_f(src, dest, overwrite: true, verbose: false)
@@ -16,7 +16,7 @@ module Squared
16
16
  rescue StandardError => e
17
17
  raise if exception
18
18
 
19
- warn e
19
+ defined?(__warn__) == 'method' ? __warn__(e) : warn(e)
20
20
  end
21
21
 
22
22
  def invoked?(name)
@@ -1,23 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pathname'
4
- require 'shellwords'
5
4
  require 'logger'
6
- require 'set'
7
5
  require 'rake'
8
6
 
9
7
  module Squared
10
8
  module Common
11
9
  VAR = {
12
10
  project: {},
13
- logger: {
14
- unknown: %i[cyan],
15
- fatal: %i[white bold red!],
16
- error: %i[red bold],
17
- warn: %i[yellow bold],
18
- info: %i[blue],
19
- debug: %i[green]
20
- },
21
11
  colors: {
22
12
  black: '30',
23
13
  red: '31',
@@ -35,26 +25,58 @@ module Squared
35
25
  magenta!: '45',
36
26
  cyan!: '46',
37
27
  white!: '47'
38
- }.freeze
39
- }
28
+ },
29
+ theme: {
30
+ workspace: {},
31
+ project: {},
32
+ viewer: {
33
+ banner: %i[blue bold],
34
+ key: %i[bold],
35
+ value: %i[green],
36
+ string: %i[yellow],
37
+ hash: %i[green black!],
38
+ array: %i[blue black!],
39
+ number: %i[magenta],
40
+ undefined: %i[red italic]
41
+ },
42
+ logger: {
43
+ unknown: %i[cyan],
44
+ fatal: %i[white bold red!],
45
+ error: %i[red bold],
46
+ warn: %i[yellow bold],
47
+ info: %i[blue],
48
+ debug: %i[green]
49
+ }
50
+ }
51
+ }.compare_by_identity
40
52
  private_constant :VAR
41
53
 
42
- def get(key)
54
+ def __get__(key)
43
55
  VAR[key.is_a?(::String) ? key.to_sym : key]
44
56
  end
45
57
 
46
- def set(key, val)
58
+ def __set__(key, val)
59
+ return if VAR.frozen?
60
+
47
61
  VAR[key.is_a?(::String) ? key.to_sym : key] = val
48
62
  end
49
63
 
64
+ def finalize!
65
+ VAR.each_value(&:freeze)
66
+ VAR[:theme].each_value(&:freeze)
67
+ VAR.freeze
68
+ end
69
+
50
70
  def message(*args, hint: nil)
51
71
  args.reject(&:empty?).join(' => ') + (hint ? " (#{hint})" : '')
52
72
  end
53
73
 
54
- def as_a(obj)
74
+ def as_a(obj, flat: nil)
55
75
  return [] if obj.nil?
76
+ return [obj] unless obj.is_a?(::Array)
77
+ return obj unless flat
56
78
 
57
- obj.is_a?(::Array) ? obj : [obj]
79
+ obj.flatten(flat == true ? nil : flat)
58
80
  end
59
81
  end
60
82
  end