bashly 1.0.6 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58a2804698490f003611b4f607614fef9995bea16f426c6d56d527d78b770a29
4
- data.tar.gz: 24a4c1d97b45332e424fc6932092225bab7b3ade618f5eec5e9c187ca91389ac
3
+ metadata.gz: b82e5ead650cc1774cf3870af91b9046b1e5f69f05484d833f72dd4090eab091
4
+ data.tar.gz: 26626b09b79382d2d4530241b5517ed04d3e4a27c004130adadad3b27421f100
5
5
  SHA512:
6
- metadata.gz: 0e62c14ede0d0295e01411cd946859a21413e50b43313f850ea494c4ed5dafe6f402b914dfc8f682c3abc8e38d9004917dbd654d78f8983b961f2f35228e97e4
7
- data.tar.gz: '00309d231db02bb61fe7d9ae2c95d9d615888830a6a95c2815cda9e8b08fa4dd73e6ccc0f0127bf46a467deee4888297975f421a2a1e0c80fa5b23d871124726'
6
+ metadata.gz: 9e3b78d5975c92954347be94d567f28d240d628e080fb3d136382cc4f8fa1ae81827057ad3b61ac144b5ab930c3f5353128f9d6068b983d0e2e77ac996d4ab0d
7
+ data.tar.gz: 2595428ca74b3ada25619fc7839f99993f98bcda169b47fcda84c82b279ebcaa1882864d2d842c67f05ca1ca946f2f64867d6905892f2ff5f5f5107f32f49037
data/README.md CHANGED
@@ -32,7 +32,6 @@ a [docker image](https://hub.docker.com/r/dannyben/bashly).
32
32
  <table>
33
33
  <tr>
34
34
  <td><a href="https://rhodecode.com/"><img src='support/img/RhodeCode-logo.png' width=240></a></td>
35
- <td><a href="https://decisiohealth.com/"><img src='support/img/decisio-logo.png' width=240></a></td>
36
35
  </tr>
37
36
  </table>
38
37
 
@@ -82,11 +81,6 @@ to contribute, feel free to [open an issue][issues] or
82
81
 
83
82
  Visit the *[How to contribute][contributing]* page for more information.
84
83
 
85
- ## Stargazers and Forkers
86
-
87
- [![Stargazers repo roster for @DannyBen/bashly](https://reporoster.com/stars/DannyBen/bashly)](https://github.com/DannyBen/bashly/stargazers)
88
-
89
- [![Forkers repo roster for @DannyBen/bashly](https://reporoster.com/forks/DannyBen/bashly)](https://github.com/DannyBen/bashly/network/members)
90
84
 
91
85
  [issues]: https://github.com/DannyBen/bashly/issues
92
86
  [discussions]: https://github.com/DannyBen/bashly/discussions
@@ -4,7 +4,7 @@ module Bashly
4
4
  summary 'Install bash completions for bashly itself'
5
5
  help 'Display the bash completions script or install it directly to your bash completions directory'
6
6
 
7
- usage 'bashly completions [--install --uninstall]'
7
+ usage 'bashly completions [--install|--uninstall]'
8
8
  usage 'bashly completions (-h|--help)'
9
9
 
10
10
  option '-i --install', 'Install the completions script to your bash completions directory'
data/lib/bashly/config.rb CHANGED
@@ -2,7 +2,11 @@ require 'yaml'
2
2
 
3
3
  module Bashly
4
4
  # A convenience class to use either a hash or a filename as a configuration
5
- # source
5
+ # source.
6
+ #
7
+ # When a filename is provided, it is loaded with these extra features:
8
+ # - Support for `import` keyword to merge additional YAML files
9
+ # - Preprocessing with ERB
6
10
  class Config
7
11
  using ComposeRefinements
8
12
 
@@ -10,7 +14,7 @@ module Bashly
10
14
 
11
15
  def self.new(config)
12
16
  if config.is_a? String
13
- YAML.properly_load_file(config).compose
17
+ YAML.load_erb_file(config).compose
14
18
  else
15
19
  config
16
20
  end
@@ -13,6 +13,10 @@ class String
13
13
  gsub(/(.)([A-Z])/, '\1_\2').gsub(/[- ]/, '_').downcase
14
14
  end
15
15
 
16
+ def to_path
17
+ tr(' ', '/').downcase
18
+ end
19
+
16
20
  def wrap(length = 80)
17
21
  strip!
18
22
  split("\n").collect! do |line|
@@ -1,10 +1,12 @@
1
1
  module YAML
2
- # This awkward patch is due to https://bugs.ruby-lang.org/issues/17866
3
- def self.properly_load_file(path)
4
- YAML.load_file path, aliases: true
5
- rescue ArgumentError
6
- # :nocov:
7
- YAML.load_file path
8
- # :nocov:
2
+ # We trust our loaded YAMLs
3
+ # This patch is due to https://bugs.ruby-lang.org/issues/17866
4
+ # StackOverflow: https://stackoverflow.com/questions/71191685/visit-psych-nodes-alias-unknown-alias-default-psychbadalias/71192990#71192990
5
+ class << self
6
+ alias load unsafe_load
7
+
8
+ def load_erb_file(path)
9
+ YAML.load ERB.new(File.read(path)).result
10
+ end
9
11
  end
10
12
  end
@@ -1,128 +1,108 @@
1
- ## Config functions [@bashly-upgrade config]
1
+ ## Config (INI) functions [@bashly-upgrade config]
2
2
  ## This file is a part of Bashly standard library
3
3
  ##
4
4
  ## Usage:
5
- ## - In your script, set the CONFIG_FILE variable. For rxample:
6
- ## CONFIG_FILE=settings.ini.
7
- ## If it is unset, it will default to 'config.ini'.
8
- ## - Use any of the functions below to access the config file.
9
5
  ##
10
- ## Create a new config file.
11
- ## There is normally no need to use this function, it is used by other
12
- ## functions as needed.
6
+ ## - Set the global variable CONFIG_FILE to the path of your INI file somewhere
7
+ ## in your script (for example, in src/initialize.sh).
8
+ ## - Use any of the following functions to access and manipulate the values.
9
+ ## - INI sections are optional (i.e., sectionless key=value pairs are allowed).
13
10
  ##
14
- config_init() {
15
- CONFIG_FILE=${CONFIG_FILE:=config.ini}
16
- [[ -f "$CONFIG_FILE" ]] || touch "$CONFIG_FILE"
11
+
12
+ ## Show all the key=value pairs from your config file
13
+ config_show() {
14
+ config_load
15
+ ini_show
17
16
  }
18
17
 
19
- ## Get a value from the config.
20
- ## Usage: result=$(config_get hello)
18
+ ## Get a single value from the config file:
19
+ ##
20
+ ## config_get login.email
21
+ ##
22
+ ## Get the value or a default one if it is not set:
23
+ ##
24
+ ## config_get login.user guest
25
+ ##
26
+ ## Assign the result to a variable:
27
+ ##
28
+ ## theme="$(config_get interface.theme)"
29
+ ##
21
30
  config_get() {
22
- local key=$1
23
- local regex="^$key *= *(.+)$"
24
- local value=""
25
-
26
- config_init
31
+ local key="$1"
32
+ local default_value="$2"
27
33
 
28
- while IFS= read -r line || [ -n "$line" ]; do
29
- if [[ $line =~ $regex ]]; then
30
- value="${BASH_REMATCH[1]}"
31
- break
32
- fi
33
- done <"$CONFIG_FILE"
34
-
35
- echo "$value"
34
+ config_load
35
+ echo "${ini["$key"]:-$default_value}"
36
36
  }
37
37
 
38
- ## Add or update a key=value pair in the config.
39
- ## Usage: config_set key value
38
+ ## Create/update a key=value pair:
39
+ ##
40
+ ## config_set cloud.provider aws
41
+ ##
40
42
  config_set() {
41
- local key=$1
43
+ local key="$1"
42
44
  shift
43
45
  local value="$*"
44
46
 
45
- config_init
46
-
47
- local regex="^($key) *= *.+$"
48
- local output=""
49
- local found_key=""
50
- local newline
51
-
52
- while IFS= read -r line || [ -n "$line" ]; do
53
- newline=$line
54
- if [[ $line =~ $regex ]]; then
55
- found_key="${BASH_REMATCH[1]}"
56
- newline="$key = $value"
57
- output="$output$newline\n"
58
- elif [[ $line ]]; then
59
- output="$output$line\n"
60
- fi
61
- done <"$CONFIG_FILE"
62
-
63
- if [[ -z $found_key ]]; then
64
- output="$output$key = $value\n"
65
- fi
66
-
67
- printf "%b\n" "$output" >"$CONFIG_FILE"
47
+ config_load
48
+ ini["$key"]="$value"
49
+ config_save
68
50
  }
69
51
 
70
- ## Delete a key from the config.
71
- ## Usage: config_del key
52
+ ## Delete a key=value pair:
53
+ ##
54
+ ## config_del login.email
55
+ ##
72
56
  config_del() {
73
- local key=$1
57
+ local key="$1"
74
58
 
75
- local regex="^($key) *="
76
- local output=""
77
-
78
- config_init
79
-
80
- while IFS= read -r line || [ -n "$line" ]; do
81
- if [[ $line ]] && [[ ! $line =~ $regex ]]; then
82
- output="$output$line\n"
83
- fi
84
- done <"$CONFIG_FILE"
85
-
86
- printf "%b\n" "$output" >"$CONFIG_FILE"
87
- }
88
-
89
- ## Show the config file
90
- config_show() {
91
- config_init
92
- cat "$CONFIG_FILE"
59
+ config_load
60
+ unset "ini[$key]"
61
+ config_save
93
62
  }
94
63
 
95
- ## Return an array of the keys in the config file.
96
- ## Usage:
64
+ ## Get an array of all keys:
97
65
  ##
98
- ## for k in $(config_keys); do
99
- ## echo "- $k = $(config_get "$k")";
66
+ ## for key in $(config_keys); do
67
+ ## echo "- $key = $(config_get "$key")";
100
68
  ## done
101
69
  ##
102
70
  config_keys() {
103
- local regex="^([a-zA-Z0-9_\-\/\.]+) *="
104
-
105
- config_init
106
-
107
- local keys=()
108
- local key
109
-
110
- while IFS= read -r line || [ -n "$line" ]; do
111
- if [[ $line =~ $regex ]]; then
112
- key="${BASH_REMATCH[1]}"
113
- keys+=("$key")
114
- fi
115
- done <"$CONFIG_FILE"
116
- echo "${keys[@]}"
71
+ config_load
72
+ ini_keys
117
73
  }
118
74
 
119
- ## Returns true if the specified key exists in the config file.
120
- ## Usage:
75
+ ## Check if a key exists:
121
76
  ##
122
- ## if config_has_key "key"; then
77
+ ## if config_has_key login.password; then
123
78
  ## echo "key exists"
124
79
  ## fi
125
80
  ##
126
81
  config_has_key() {
127
82
  [[ $(config_get "$1") ]]
128
83
  }
84
+
85
+ ## Force-load from file
86
+ ## This should normally not be called, unless you suspect that the INI file
87
+ ## was modified by external means during the run of your script.
88
+ config_reload() {
89
+ declare -g config_loaded=false
90
+ config_load
91
+ }
92
+
93
+ ## Load an INI file (unless loaded) and populate the associative array
94
+ ## NOTE: Normally there is no need to call this function, it is called as needed
95
+ config_load() {
96
+ [[ "$config_loaded" == "true" ]] && return
97
+
98
+ declare -g CONFIG_FILE=${CONFIG_FILE:=config.ini}
99
+ declare -g config_loaded=true
100
+ [[ -f "$CONFIG_FILE" ]] || touch "$CONFIG_FILE"
101
+ ini_load "$CONFIG_FILE"
102
+ }
103
+
104
+ ## Save the associative array back to a file
105
+ ## NOTE: Normally there is no need to call this function, it is called as needed
106
+ config_save() {
107
+ ini_save "$CONFIG_FILE"
108
+ }
@@ -0,0 +1,110 @@
1
+ ## INI functions [@bashly-upgrade ini]
2
+ ## This file is a part of Bashly standard library
3
+ ##
4
+ ## Usage:
5
+ ##
6
+ ## - In your script, call `ini_load path/to/config.ini`.
7
+ ## - A global associative array named `ini` will become available to you,
8
+ ## - When updating any of the associative array's values, call
9
+ ## `ini_save path/to/config.ini` to save the data.
10
+ ## - INI sections are optional.
11
+ ##
12
+ ## Get a value:
13
+ ##
14
+ ## ${ini[section1.key1]} # for keys under a [section]
15
+ ## ${ini[key1]} # for keys not under a [section]
16
+ ## ${ini[key1]:-default} # get a default value if the INI key is unset
17
+ ##
18
+ ## Update/create a value:
19
+ ##
20
+ ## ini[section1.key1]="value"
21
+ ## ini_save path/to/config.ini
22
+ ##
23
+ ## Delete a value
24
+ ##
25
+ ## unset ini[section1.key1]
26
+ ## ini_save path/to/config.ini
27
+ ##
28
+
29
+ ## Load an INI file and populate the associative array `ini`.
30
+ ini_load() {
31
+ declare -gA ini
32
+
33
+ local ini_file="$1"
34
+
35
+ local section=""
36
+ local key=""
37
+ local value=""
38
+ local section_regex="^\[(.+)\]"
39
+ local key_regex="^([^ =]+) *= *(.*) *$"
40
+ local comment_regex="^;"
41
+
42
+ while IFS= read -r line; do
43
+ if [[ $line =~ $comment_regex ]]; then
44
+ continue
45
+ elif [[ $line =~ $section_regex ]]; then
46
+ section="${BASH_REMATCH[1]}."
47
+ elif [[ $line =~ $key_regex ]]; then
48
+ key="${BASH_REMATCH[1]}"
49
+ value="${BASH_REMATCH[2]}"
50
+ ini["${section}${key}"]="$value"
51
+ fi
52
+ done <"$ini_file"
53
+ }
54
+
55
+ ## Save the associative array `ini` back to a file
56
+ ini_save() {
57
+ declare -gA ini
58
+
59
+ local ini_file="$1"
60
+
61
+ local current_section=""
62
+ local has_free_keys=false
63
+
64
+ rm -f "$ini_file"
65
+
66
+ for key in $(ini_keys); do
67
+ [[ $key == *.* ]] && continue
68
+ has_free_keys=true
69
+ value="${ini[$key]}"
70
+ echo "$key = $value" >>"$ini_file"
71
+ done
72
+
73
+ [[ "${has_free_keys}" == "true" ]] && echo >>"$ini_file"
74
+
75
+ for key in $(ini_keys); do
76
+ [[ $key == *.* ]] || continue
77
+ value="${ini[$key]}"
78
+ IFS="." read -r section_name key_name <<<"$key"
79
+
80
+ if [[ "$current_section" != "$section_name" ]]; then
81
+ [[ $current_section ]] && echo >>"$ini_file"
82
+ echo "[$section_name]" >>"$ini_file"
83
+ current_section="$section_name"
84
+ fi
85
+
86
+ echo "$key_name = $value" >>"$ini_file"
87
+ done
88
+ }
89
+
90
+ ## Show all loaded key-value pairs
91
+ ini_show() {
92
+ declare -gA ini
93
+
94
+ for key in $(ini_keys); do
95
+ echo "$key = ${ini[$key]}"
96
+ done
97
+ }
98
+
99
+ ## Get an array of all keys:
100
+ ##
101
+ ## for key in $(ini_keys); do
102
+ ## echo "- $key = ${ini[$key]}";
103
+ ## done
104
+ ##
105
+ ini_keys() {
106
+ declare -gA ini
107
+
108
+ local keys=("${!ini[@]}")
109
+ for a in "${keys[@]}"; do echo "$a"; done | sort
110
+ }
@@ -20,10 +20,12 @@ completions_yaml:
20
20
  handler: Bashly::Libraries::CompletionsYAML
21
21
 
22
22
  config:
23
- help: Add standard functions for handling INI files to the lib directory.
23
+ help: Add functions for handling INI configuration files to the lib directory.
24
24
  files:
25
25
  - source: "config/config.sh"
26
26
  target: "%{user_lib_dir}/config.%{user_ext}"
27
+ - source: "ini/ini.sh"
28
+ target: "%{user_lib_dir}/ini.%{user_ext}"
27
29
 
28
30
  help:
29
31
  help: Add a help command, in addition to the standard --help flag.
@@ -39,6 +41,12 @@ hooks:
39
41
  - source: "hooks/after.sh"
40
42
  target: "%{user_source_dir}/after.%{user_ext}"
41
43
 
44
+ ini:
45
+ help: Add low level functions for reading/writing INI files to the lib directory.
46
+ files:
47
+ - source: "ini/ini.sh"
48
+ target: "%{user_lib_dir}/ini.%{user_ext}"
49
+
42
50
  lib:
43
51
  help: |-
44
52
  Create the lib directory for any additional user scripts.
@@ -18,9 +18,15 @@ config_path: "%{source_dir}/bashly.yml"
18
18
  # The path to use for creating the bash script
19
19
  target_dir: .
20
20
 
21
- # The path to use for common library files, relative to the source dir
21
+ # The path to use for common library files, relative to source_dir
22
22
  lib_dir: lib
23
23
 
24
+ # The path to use for command files, relative to source_dir
25
+ # When set to nil (~), command files will be placed directly under source_dir
26
+ # When set to any other string, command files will be placed under this
27
+ # directory, and each command will get its own subdirectory
28
+ commands_dir: ~
29
+
24
30
  # Configure the bash options that will be added to the initialize function:
25
31
  # strict: true Bash strict mode (set -euo pipefail)
26
32
  # strict: false Only exit on errors (set -e)
@@ -14,7 +14,7 @@ module Bashly
14
14
  end
15
15
 
16
16
  def config
17
- @config ||= YAML.properly_load_file config_path
17
+ @config ||= YAML.load_file config_path
18
18
  end
19
19
 
20
20
  def libraries
@@ -13,7 +13,7 @@ module Bashly
13
13
  private
14
14
 
15
15
  def values!
16
- defaults = YAML.properly_load_file asset('libraries/strings/strings.yml')
16
+ defaults = YAML.load_file asset('libraries/strings/strings.yml')
17
17
  defaults.merge project_strings
18
18
  end
19
19
 
@@ -23,7 +23,7 @@ module Bashly
23
23
 
24
24
  def project_strings!
25
25
  if File.exist? project_strings_path
26
- YAML.properly_load_file project_strings_path
26
+ YAML.load_file project_strings_path
27
27
  else
28
28
  {}
29
29
  end
@@ -22,7 +22,7 @@ module ComposeRefinements
22
22
  end
23
23
 
24
24
  def safe_load_yaml(path)
25
- loaded = YAML.properly_load_file path
25
+ loaded = YAML.load_erb_file path
26
26
  return loaded if loaded.is_a?(Array) || loaded.is_a?(Hash)
27
27
 
28
28
  raise Bashly::ConfigurationError, "Cannot find a valid YAML in g`#{path}`"
@@ -159,10 +159,10 @@ module Bashly
159
159
  options['examples'].is_a?(Array) ? options['examples'] : [options['examples']]
160
160
  end
161
161
 
162
- # Returns the bash filename that is expected to hold the user code
163
- # for this command
162
+ # Returns the filename that is expected to hold the user code for this
163
+ # command
164
164
  def filename
165
- options['filename'] || "#{action_name.to_underscore}_command.#{Settings.partials_extension}"
165
+ options['filename'] || implicit_filename
166
166
  end
167
167
 
168
168
  # Returns an array of Flags
@@ -314,6 +314,18 @@ module Bashly
314
314
  def whitelisted_flags
315
315
  flags.select(&:allowed)
316
316
  end
317
+
318
+ private
319
+
320
+ # Returns either a flat filename (docker_status_command.sh) or a nested
321
+ # path (commands/docker/status.sh)
322
+ def implicit_filename
323
+ if Settings.commands_dir
324
+ "#{Settings.commands_dir}/#{action_name.to_path}.#{Settings.partials_extension}"
325
+ else
326
+ "#{action_name.to_underscore}_command.#{Settings.partials_extension}"
327
+ end
328
+ end
317
329
  end
318
330
  end
319
331
  end
@@ -4,6 +4,7 @@ module Bashly
4
4
  include AssetHelper
5
5
 
6
6
  attr_writer(
7
+ :commands_dir,
7
8
  :compact_short_flags,
8
9
  :config_path,
9
10
  :lib_dir,
@@ -15,6 +16,10 @@ module Bashly
15
16
  :usage_colors
16
17
  )
17
18
 
19
+ def commands_dir
20
+ @commands_dir ||= get :commands_dir
21
+ end
22
+
18
23
  def compact_short_flags
19
24
  @compact_short_flags ||= get :compact_short_flags
20
25
  end
@@ -1,3 +1,3 @@
1
1
  module Bashly
2
- VERSION = '1.0.6'
2
+ VERSION = '1.0.8'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bashly
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-27 00:00:00.000000000 Z
11
+ date: 2023-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colsole
@@ -114,6 +114,26 @@ dependencies:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
116
  version: '1.0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: psych
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: 3.3.2
124
+ - - "<"
125
+ - !ruby/object:Gem::Version
126
+ version: '7'
127
+ type: :runtime
128
+ prerelease: false
129
+ version_requirements: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: 3.3.2
134
+ - - "<"
135
+ - !ruby/object:Gem::Version
136
+ version: '7'
117
137
  description: Generate bash command line tools using YAML configuration
118
138
  email: db@dannyben.com
119
139
  executables:
@@ -164,6 +184,7 @@ files:
164
184
  - lib/bashly/libraries/hooks/after.sh
165
185
  - lib/bashly/libraries/hooks/before.sh
166
186
  - lib/bashly/libraries/hooks/initialize.sh
187
+ - lib/bashly/libraries/ini/ini.sh
167
188
  - lib/bashly/libraries/lib/sample_function.sh
168
189
  - lib/bashly/libraries/libraries.yml
169
190
  - lib/bashly/libraries/settings/settings.yml
@@ -253,7 +274,7 @@ metadata:
253
274
  homepage_uri: https://bashly.dannyb.co/
254
275
  source_code_uri: https://github.com/DannyBen/bashly
255
276
  rubygems_mfa_required: 'true'
256
- post_install_message:
277
+ post_install_message:
257
278
  rdoc_options: []
258
279
  require_paths:
259
280
  - lib
@@ -268,8 +289,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
268
289
  - !ruby/object:Gem::Version
269
290
  version: '0'
270
291
  requirements: []
271
- rubygems_version: 3.4.14
272
- signing_key:
292
+ rubygems_version: 3.4.18
293
+ signing_key:
273
294
  specification_version: 4
274
295
  summary: Bash Command Line Tool Generator
275
296
  test_files: []