bashly 2.0.0.rc1 → 2.0.0.rc3

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: 6e96439b1894f3097d9c8ea8d49b42254075a41bf02b233aa7d57674030e2d7f
4
- data.tar.gz: 14963288238d456e105ce739fdc076d0bb950f497a234851725ba3f887a4a982
3
+ metadata.gz: b1b1d33984cddf5a4c3853a1189e82633fe43d9f1d9c5b8dcbde05204571bcb0
4
+ data.tar.gz: 4d898b9019f4d9fde7c0b3ff0857fbf580a50db5eebb4f7fbb196ae48ac27e71
5
5
  SHA512:
6
- metadata.gz: 474e72b43adcba1b0860f123be0584dbf8d7d7d14797f44018603f6f805e6a792b92282201d7930383e40ff48d771094e339e0c279c12940558a17d07dc09f06
7
- data.tar.gz: 343351f0dbcb3d182ef2050e99a22f2ff39a1839ba11b208712c3cb85178f44678628f05ac1d2b2a4370e2dc77055f66972d16e94f5a4122dff409b937d9e956
6
+ metadata.gz: 5ed3e82b235dc599e3698a98ddb8c135084ba4c76995693e9440e5f26e977d5cce29c23fc56a070c4ce5e600da7a9ca141ff17f0aea75a3028505da75bc4fc79
7
+ data.tar.gz: 3804b6705fad255c15e23327b2f4a02f9ecb9ec63762dbee790d3d5c6a7f33ddb03e51090d4dc0e2a6326a9c63ecb5deb06bcfe03d971f02fb4f8843b2a87cc1
@@ -29,7 +29,7 @@ module Bashly
29
29
  else
30
30
  add_lib args['LIBRARY']
31
31
  end
32
-
32
+ ensure
33
33
  lib_source.cleanup if lib_source.git?
34
34
  end
35
35
 
@@ -107,6 +107,8 @@ module Bashly
107
107
  quiet_say "r`warning` not upgrading c`#{existing_file}`, " \
108
108
  "unknown library '#{library_name}'"
109
109
  end
110
+ ensure
111
+ source.cleanup if source&.git?
110
112
  end
111
113
 
112
114
  def upgrade!(existing_file, library)
@@ -1,5 +1,3 @@
1
- require 'lp'
2
-
3
1
  module Bashly
4
2
  module Commands
5
3
  class Validate < Base
@@ -13,7 +11,7 @@ module Bashly
13
11
 
14
12
  def run
15
13
  if args['--verbose']
16
- lp config
14
+ puts config.to_yaml
17
15
  puts '---'
18
16
  end
19
17
  validate_config
@@ -0,0 +1,37 @@
1
+ module Bashly
2
+ module SettingsCompletions
3
+ COMPLETION_SHELLS = %w[bash zsh].freeze
4
+
5
+ def completions
6
+ @completions ||= get :completions
7
+ end
8
+
9
+ def completions?
10
+ completions == 'minimal' || completion_shells.any?
11
+ end
12
+
13
+ def completion_shells
14
+ case completions
15
+ when nil, false, 'minimal' then []
16
+ when 'full' then COMPLETION_SHELLS
17
+ when String then validate_completion_shells completions
18
+ else invalid_completions
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def validate_completion_shells(value)
25
+ shells = value.split(',', -1).map(&:strip)
26
+ valid = shells.any? && (shells - COMPLETION_SHELLS).empty?
27
+ return shells if valid && shells.uniq == shells
28
+
29
+ invalid_completions
30
+ end
31
+
32
+ def invalid_completions
33
+ raise ConfigurationError,
34
+ "completions must be false, minimal, full, or a comma-separated list of: #{COMPLETION_SHELLS.join ', '}"
35
+ end
36
+ end
37
+ end
@@ -2,6 +2,8 @@ module Bashly
2
2
  class ConfigValidator
3
3
  include ValidationHelpers
4
4
 
5
+ COMPLETION_OPTIONS = %w[files directories no-space].freeze
6
+
5
7
  attr_reader :data
6
8
 
7
9
  def initialize(data)
@@ -97,7 +99,7 @@ module Bashly
97
99
  assert_array "#{key}.options", value['options'], of: :string
98
100
 
99
101
  Array(value['options']).each do |option|
100
- assert %w[files directories no-space].include?(option),
102
+ assert COMPLETION_OPTIONS.include?(option),
101
103
  "#{key}.options contains an unknown option: #{option}"
102
104
  end
103
105
  end
@@ -1,5 +1,6 @@
1
1
  # render script - mandoc
2
2
  require 'gtx'
3
+ require 'shellwords'
3
4
 
4
5
  # Load the GTX template
5
6
  template = "#{source}/mandoc.gtx"
@@ -12,9 +13,12 @@ save_manpage = lambda { |command|
12
13
  save mdfile, gtx.parse(command)
13
14
 
14
15
  # The pandoc command that creates a manpage from markdown
15
- cmd = %[pandoc -f markdown-smart -s --to man "#{mdfile}" > "#{manfile}"]
16
- success = system cmd
17
- raise "Failed running pandoc\nMake sure the following command succeeds and try again:\n\n #{cmd}" unless success
16
+ command = ['pandoc', '-f', 'markdown-smart', '-s', '--to', 'man', mdfile, '-o', manfile]
17
+ success = system(*command)
18
+ unless success
19
+ command_string = Shellwords.join command
20
+ raise "Failed running pandoc\nMake sure the following command succeeds and try again:\n\n #{command_string}"
21
+ end
18
22
 
19
23
  say "g`saved` #{manfile}"
20
24
  }
@@ -30,5 +34,5 @@ end
30
34
  # Show one of the files if requested
31
35
  if show
32
36
  file = "#{target}/#{show}"
33
- system "man #{file}" if File.exist?(file)
37
+ system 'man', file if File.exist?(file)
34
38
  end
@@ -177,11 +177,8 @@ completions: ~
177
177
  # DEVELOPER OPTIONS
178
178
  #-------------------------------------------------------------------------------
179
179
 
180
- # When true, use filesystem evented watching instead of polling
181
- watch_evented: false
182
-
183
- # File change detection latency (seconds)
184
- watch_latency: 1.0
180
+ # File change detection polling interval (seconds)
181
+ watch_latency: 2.0
185
182
 
186
183
 
187
184
  #-------------------------------------------------------------------------------
@@ -200,5 +197,6 @@ var_aliases:
200
197
 
201
198
  # Choose different names for some of the internal functions.
202
199
  function_names:
200
+ start: ~
203
201
  run: ~
204
202
  initialize: ~
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'shellwords'
2
3
  require 'tmpdir'
3
4
 
4
5
  module Bashly
@@ -34,7 +35,8 @@ module Bashly
34
35
  end
35
36
 
36
37
  def cleanup
37
- FileUtils.rm_rf(File.join(Dir.tmpdir, 'bashly-libs-*'))
38
+ FileUtils.rm_rf @tmpdir if @tmpdir
39
+ @tmpdir = nil
38
40
  end
39
41
 
40
42
  private
@@ -48,11 +50,11 @@ module Bashly
48
50
  end
49
51
 
50
52
  def git_clone
51
- dir = Dir.mktmpdir 'bashly-libs-'
52
- safe_run "git clone --quiet #{git_specs[:url]} #{dir}"
53
- safe_run %[git -C "#{dir}" checkout --quiet #{git_specs[:ref]}] if git_specs[:ref]
53
+ @tmpdir = Dir.mktmpdir 'bashly-libs-'
54
+ safe_run 'git', 'clone', '--quiet', git_specs[:url], @tmpdir
55
+ safe_run 'git', '-C', @tmpdir, 'checkout', '--quiet', git_specs[:ref] if git_specs[:ref]
54
56
 
55
- "#{dir}#{git_specs[:path]}"
57
+ "#{@tmpdir}#{git_specs[:path]}"
56
58
  end
57
59
 
58
60
  def git_specs
@@ -70,8 +72,8 @@ module Bashly
70
72
  end
71
73
  end
72
74
 
73
- def safe_run(cmd)
74
- raise "Failed running command:\nm`#{cmd}`" unless system cmd
75
+ def safe_run(*command)
76
+ raise "Failed running command:\nm`#{Shellwords.join command}`" unless system(*command)
75
77
  end
76
78
 
77
79
  def transform_github_uri
@@ -35,6 +35,11 @@ module Bashly
35
35
  completions&.fetch('options', []) || []
36
36
  end
37
37
 
38
+ def completion?
39
+ allowed&.any? || completion_static.any? ||
40
+ completion_dynamic.any? || completion_options.any?
41
+ end
42
+
38
43
  def label
39
44
  repeatable ? "#{name.upcase}..." : name.upcase
40
45
  end
@@ -1,9 +1,10 @@
1
1
  module Bashly
2
2
  class Settings
3
- COMPLETION_SHELLS = %w[bash zsh].freeze
3
+ COMPLETION_SHELLS = SettingsCompletions::COMPLETION_SHELLS
4
4
 
5
5
  class << self
6
6
  include AssetHelper
7
+ include SettingsCompletions
7
8
 
8
9
  attr_writer(
9
10
  :argfile_var,
@@ -32,7 +33,6 @@ module Bashly
32
33
  :target_dir,
33
34
  :usage_colors,
34
35
  :var_aliases,
35
- :watch_evented,
36
36
  :watch_latency,
37
37
  :word_wrap
38
38
  )
@@ -53,28 +53,6 @@ module Bashly
53
53
  @compact_short_flags ||= get :compact_short_flags
54
54
  end
55
55
 
56
- def completions
57
- @completions ||= get :completions
58
- end
59
-
60
- def completions?
61
- completions == 'minimal' || completion_shells.any?
62
- end
63
-
64
- def completion_shells
65
- value = completions
66
- return [] if value.nil? || value == false || value == 'minimal'
67
- return COMPLETION_SHELLS if value == 'full'
68
-
69
- shells = value.split(',', -1).map(&:strip) if value.is_a? String
70
- valid = shells&.any? && shells.all? { |shell| COMPLETION_SHELLS.include? shell }
71
- unique = shells&.uniq == shells
72
- return shells if valid && unique
73
-
74
- raise ConfigurationError,
75
- "completions must be false, minimal, full, or a comma-separated list of: #{COMPLETION_SHELLS.join ', '}"
76
- end
77
-
78
56
  def conjoined_flag_args
79
57
  @conjoined_flag_args ||= get :conjoined_flag_args
80
58
  end
@@ -206,10 +184,6 @@ module Bashly
206
184
  @var_aliases ||= get :var_aliases
207
185
  end
208
186
 
209
- def watch_evented
210
- @watch_evented ||= get :watch_evented
211
- end
212
-
213
187
  def watch_latency
214
188
  @watch_latency ||= get :watch_latency
215
189
  end
@@ -1,3 +1,3 @@
1
1
  module Bashly
2
- VERSION = '2.0.0.rc1'
2
+ VERSION = '2.0.0.rc3'
3
3
  end
@@ -1,9 +1,10 @@
1
- if args.any?
1
+ completion_args = args.each_with_index.select { |arg, _index| arg.completion? }
2
+ if completion_args.any?
2
3
  > if [[ $completion_current != -* ]]; then
3
4
  > case "$completion_arg_index" in
4
- args.each_with_index do |arg, index|
5
+ completion_args.each do |arg, index|
5
6
  > {{ index }})
6
- = arg.render(:completion).indent 6
7
+ = arg.render(:completion).strip.indent 6
7
8
  > ;;
8
9
  end
9
10
  > esac
@@ -13,12 +13,14 @@
13
13
  = render :initialize
14
14
  = render :run
15
15
 
16
- >
16
+ >
17
+ = render :start
18
+ >
17
19
  if Settings.enabled? :sourcing
18
20
  > if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
19
- = render(:start).indent 2
21
+ > {{ Settings.function_name :start }} "$@"
20
22
  > fi
21
23
  else
22
- = render :start
24
+ > {{ Settings.function_name :start }} "$@"
23
25
  end
24
- >
26
+ >
@@ -18,6 +18,16 @@ if catch_all.enabled?
18
18
  > break
19
19
  > ;;
20
20
  >
21
+ else
22
+ > --)
23
+ > shift
24
+ > while [[ $# -gt 0 ]]; do
25
+ > key="$1"
26
+ = render(:parse_requirements_case).indent(8)
27
+ > done
28
+ > break
29
+ > ;;
30
+ >
21
31
  end
22
32
 
23
33
  > -?*)
@@ -1,14 +1,14 @@
1
1
  = view_marker
2
2
 
3
- > command_line_args=("$@")
3
+ > {{ Settings.function_name :start }}() {
4
4
  if Settings.completions?
5
- > if [[ "${command_line_args[0]:-}" == "__complete" ]]; then
6
- > completion_run "${command_line_args[@]:1}"
7
- > else
5
+ > if [[ ${1:-} == "__complete" ]]; then
6
+ > completion_run "${@:2}"
7
+ > return
8
+ > fi
9
+ >
10
+ end
11
+ > command_line_args=("$@")
8
12
  > {{ Settings.function_name :initialize }}
9
13
  > {{ Settings.function_name :run }} "${command_line_args[@]}"
10
- > fi
11
- else
12
- > {{ Settings.function_name :initialize }}
13
- > {{ Settings.function_name :run }} "${command_line_args[@]}"
14
- end
14
+ > }
data/lib/bashly/watch.rb CHANGED
@@ -1,68 +1,40 @@
1
- require 'listen'
1
+ require 'watchly'
2
2
 
3
3
  module Bashly
4
- # File system watcher - an ergonomic wrapper around the Listen gem
4
+ # File system watcher - an ergonomic wrapper around the Watchly gem
5
5
  class Watch
6
- attr_reader :dirs, :options
6
+ attr_reader :interval, :targets
7
7
 
8
- def initialize(*dirs, **options)
9
- @options = default_options.merge(options).freeze
10
- @dirs = dirs.empty? ? ['.'] : dirs
8
+ def initialize(*targets, interval: nil)
9
+ @targets = targets.empty? ? ['.'] : targets
10
+ @interval = interval || default_interval
11
11
  end
12
12
 
13
- def on_change(&)
14
- start(&)
15
- wait
16
- ensure
17
- stop
18
- end
19
-
20
- private
13
+ def on_change
14
+ raise ArgumentError, 'block required' unless block_given?
21
15
 
22
- def default_options
23
- {
24
- force_polling: force_polling?,
25
- latency: latency,
26
- }
16
+ watcher.on_change do |changes|
17
+ yield normalize(changes)
18
+ end
19
+ rescue ::Interrupt => e
20
+ raise Bashly::Interrupt, cause: e
27
21
  end
28
22
 
29
- def force_polling?
30
- !Settings.watch_evented
31
- end
23
+ private
32
24
 
33
- def latency
25
+ def default_interval
34
26
  value = Settings.watch_latency.to_f
35
27
  value.positive? ? value : 0.1
36
28
  end
37
29
 
38
- def start(&block)
39
- raise ArgumentError, 'block required' unless block
40
-
41
- @listener = build_listener(&block)
42
- @listener.start
43
- end
44
-
45
- def stop
46
- @listener&.stop
47
- @listener = nil
48
- end
49
-
50
- def wait
51
- sleep
52
- rescue ::Interrupt => e
53
- raise Bashly::Interrupt, cause: e
54
- end
55
-
56
- def build_listener
57
- listen.to(*dirs, **options) do |modified, added, removed|
58
- yield changes(modified, added, removed)
59
- end
60
- end
61
-
62
- def changes(modified, added, removed)
63
- { modified:, added:, removed: }
30
+ def normalize(changes)
31
+ {
32
+ modified: changes.modified,
33
+ added: changes.added,
34
+ removed: changes.removed,
35
+ }
64
36
  end
65
37
 
66
- def listen = Listen
38
+ def watcher = @watcher ||= Watchly::Watcher.new(*targets, interval:)
67
39
  end
68
40
  end
data/lib/bashly.rb CHANGED
@@ -12,7 +12,7 @@ module Bashly
12
12
  ]
13
13
 
14
14
  autoloads 'bashly/concerns', %i[
15
- AssetHelper Renderable ValidationHelpers
15
+ AssetHelper Renderable SettingsCompletions ValidationHelpers
16
16
  ]
17
17
 
18
18
  module Script
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bashly
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.rc1
4
+ version: 2.0.0.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
@@ -38,75 +38,61 @@ dependencies:
38
38
  - !ruby/object:Gem::Version
39
39
  version: 0.1.1
40
40
  - !ruby/object:Gem::Dependency
41
- name: listen
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '3.9'
47
- type: :runtime
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '3.9'
54
- - !ruby/object:Gem::Dependency
55
- name: lp
41
+ name: mister_bin
56
42
  requirement: !ruby/object:Gem::Requirement
57
43
  requirements:
58
44
  - - "~>"
59
45
  - !ruby/object:Gem::Version
60
- version: 0.2.0
46
+ version: 0.9.0
61
47
  type: :runtime
62
48
  prerelease: false
63
49
  version_requirements: !ruby/object:Gem::Requirement
64
50
  requirements:
65
51
  - - "~>"
66
52
  - !ruby/object:Gem::Version
67
- version: 0.2.0
53
+ version: 0.9.0
68
54
  - !ruby/object:Gem::Dependency
69
- name: mister_bin
55
+ name: requires
70
56
  requirement: !ruby/object:Gem::Requirement
71
57
  requirements:
72
58
  - - "~>"
73
59
  - !ruby/object:Gem::Version
74
- version: 0.9.0
60
+ version: '1.1'
75
61
  type: :runtime
76
62
  prerelease: false
77
63
  version_requirements: !ruby/object:Gem::Requirement
78
64
  requirements:
79
65
  - - "~>"
80
66
  - !ruby/object:Gem::Version
81
- version: 0.9.0
67
+ version: '1.1'
82
68
  - !ruby/object:Gem::Dependency
83
- name: requires
69
+ name: tty-markdown
84
70
  requirement: !ruby/object:Gem::Requirement
85
71
  requirements:
86
72
  - - "~>"
87
73
  - !ruby/object:Gem::Version
88
- version: '1.1'
74
+ version: 0.7.2
89
75
  type: :runtime
90
76
  prerelease: false
91
77
  version_requirements: !ruby/object:Gem::Requirement
92
78
  requirements:
93
79
  - - "~>"
94
80
  - !ruby/object:Gem::Version
95
- version: '1.1'
81
+ version: 0.7.2
96
82
  - !ruby/object:Gem::Dependency
97
- name: tty-markdown
83
+ name: watchly
98
84
  requirement: !ruby/object:Gem::Requirement
99
85
  requirements:
100
86
  - - "~>"
101
87
  - !ruby/object:Gem::Version
102
- version: 0.7.2
88
+ version: 0.2.0
103
89
  type: :runtime
104
90
  prerelease: false
105
91
  version_requirements: !ruby/object:Gem::Requirement
106
92
  requirements:
107
93
  - - "~>"
108
94
  - !ruby/object:Gem::Version
109
- version: 0.7.2
95
+ version: 0.2.0
110
96
  description: Generate bash command line tools using YAML configuration
111
97
  email: db@dannyben.com
112
98
  executables:
@@ -135,6 +121,7 @@ files:
135
121
  - lib/bashly/concerns/asset_helper.rb
136
122
  - lib/bashly/concerns/indentation_helper.rb
137
123
  - lib/bashly/concerns/renderable.rb
124
+ - lib/bashly/concerns/settings_completions.rb
138
125
  - lib/bashly/concerns/validation_helpers.rb
139
126
  - lib/bashly/config.rb
140
127
  - lib/bashly/config_validator.rb
@@ -299,7 +286,7 @@ files:
299
286
  - lib/bashly/views/wrapper/header.gtx
300
287
  - lib/bashly/views/wrapper/wrapper.gtx
301
288
  - lib/bashly/watch.rb
302
- homepage: https://github.com/bashly-framework/bashly
289
+ homepage: https://bashly.dev
303
290
  licenses:
304
291
  - MIT
305
292
  metadata:
@@ -322,7 +309,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
322
309
  - !ruby/object:Gem::Version
323
310
  version: '0'
324
311
  requirements: []
325
- rubygems_version: 4.0.17
312
+ rubygems_version: 4.0.19
326
313
  specification_version: 4
327
- summary: Bash Command Line Tool Generator
314
+ summary: Bash command-line framework and CLI generator
328
315
  test_files: []