Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
- [command-paths](command-paths#readme) - configuring nested paths for your source scripts
- [command-function](command-function#readme) - configuring custom internal function names
- [split-config](split-config#readme) - splitting your `bashly.yml` into several smaller files
- [multiple-lib-dirs](multiple-lib-dirs#readme) - loading libraries from multiple locations

## Bashly library features

Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -79,7 +79,7 @@ commands:
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/settings.yml
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
2 changes: 1 addition & 1 deletion examples/custom-includes/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,7 +56,7 @@ echo "After custom code"
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-includes/src/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
1 change: 1 addition & 0 deletions examples/multiple-lib-dirs/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
download
77 changes: 77 additions & 0 deletions examples/multiple-lib-dirs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
# Multiple Lib Dirs

Demonstrates how to include more than one lib directories in the generated
script.

This example was generated with:

```bash
$ bashly init --minimal
$ bashly add settings
# ... now edit settings.yml to match the example ...
$ bashly generate
# ... now edit src/root_command.sh to match the example ...
$ bashly generate
```

<!-- include: settings.yml src/root_command.sh -->

-----

## `bashly.yml`

````yaml
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
````

## `settings.yml`

````yaml
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]

````

## `src/root_command.sh`

````bash
# Calling library functions
common_function
cloud_function
````


## Output

### `$ ./download some_source`

````shell
common_function called
cloud_function called


````



3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/cloud_lib/cloud_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
cloud_function() {
echo "cloud_function called"
}
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/common_lib/common_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
common_function() {
echo "common_function called"
}
5 changes: 5 additions & 0 deletions examples/multiple-lib-dirs/settings.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]
19 changes: 19 additions & 0 deletions examples/multiple-lib-dirs/src/bashly.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/src/root_command.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
# Calling library functions
common_function
cloud_function
9 changes: 9 additions & 0 deletions examples/multiple-lib-dirs/test.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -x

bashly generate

### Try Me ###

./download some_source
2 changes: 1 addition & 1 deletion lib/bashly/libraries/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
## Note that code here should be wrapped inside bash functions, and it is
## recommended to have a separate file for each function.
##
## Subdirectories will also be scanned for *.sh, so you have no reason not
## Sub-directories will also be scanned for *.sh, so you have no reason not
## to organize your code neatly.
##
sample_function() {
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/libraries/settings/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,10 +53,16 @@ target_dir: .
# The path to use for common library files, relative to source_dir
lib_dir: lib

# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: ~

# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory
commands_dir: ~

# The extension to use when reading/writing partial script snippets
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/script/command.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -153,7 +153,13 @@ def base_usage_pattern
# This is meant to provide the user with the ability to add custom
# functions
def user_lib
@user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
@user_lib ||= begin
result = Settings.all_lib_dirs.map do |dir|
Dir["#{dir}/**/*.#{Settings.partials_extension}"]
end

result.flatten
end
end

# Returns a mixed array of Argument and Flag objects that have validations
Expand Down
16 changes: 16 additions & 0 deletions lib/bashly/settings.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,6 +15,7 @@ class << self
:enable_inspect_args,
:enable_sourcing,
:enable_view_markers,
:extra_lib_dirs,
:formatter,
:function_names,
:lib_dir,
Expand DownExpand Up@@ -107,6 +108,21 @@ def lib_dir
@lib_dir ||= get :lib_dir
end

def extra_lib_dirs
@extra_lib_dirs ||= begin
dirs = get :extra_lib_dirs
case dirs
when Array then dirs
when String then dirs.split(',').map(&:strip)
else []
end
end
end

def all_lib_dirs
@all_lib_dirs = [full_lib_dir] + extra_lib_dirs
end

def partials_extension
@partials_extension ||= get :partials_extension
end
Expand Down
31 changes: 31 additions & 0 deletions schemas/settings.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,6 +66,37 @@
"minLength": 1,
"default": "lib"
},
"extra_lib_dirs": {
"title": "extra lib dirs",
"description": "One or more paths to use for common library files, relative to the working directory.\nMay be provided as an array or a comma delimited string.\nhttps://bashly.dev/usage/settings/#extra_lib_dirs",
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"minLength": 1,
"examples": [
"common, org_lib",
"lib"
]
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"examples": [
[
"common",
"org_lib"
]
]
}
],
"default": null
},
"commands_dir": {
"title": "commands dir",
"description": "The path to use for command files, relative to source_dir\nhttps://bashly.dev/usage/settings/#commands_dir",
Expand Down
8 changes: 8 additions & 0 deletions spec/approvals/examples/multiple-lib-dirs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
+ bashly generate
creating user files in src
skipped src/root_command.sh (exists)
created ./download
run ./download --help to test your bash script
+ ./download some_source
common_function called
cloud_function called
20 changes: 20 additions & 0 deletions spec/bashly/settings_spec.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,6 +103,26 @@
end
end

describe '::extra_lib_dirs' do
context 'when set using env var as a comma delimited string' do
before { ENV['BASHLY_EXTRA_LIB_DIRS'] = 'one,two' }
after { ENV['BASHLY_EXTRA_LIB_DIRS'] = nil }

it 'converts comma delimited string to an array' do
expect(subject.extra_lib_dirs).to match_array %w[one two]
end
end

context 'when provided as an array' do
let(:config) { Config.new({ 'extra_lib_dirs' => %w[item1 item2] }) }

it 'returns the array as is' do
allow(subject).to receive(:user_settings).and_return(config)
expect(subject.extra_lib_dirs).to match_array %w[item1 item2]
end
end
end

describe '::production?' do
it 'returns false by default' do
expect(subject.production?).to be false
Expand Down
21 changes: 21 additions & 0 deletions support/schema/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,6 +63,27 @@ properties:
type: string
minLength: 1
default: lib
extra_lib_dirs:
title: extra lib dirs
description: |-
One or more paths to use for common library files, relative to the working directory.
May be provided as an array or a comma delimited string.
https://bashly.dev/usage/settings/#extra_lib_dirs
oneOf:
- type: "null"
- type: string
minLength: 1
examples:
- "common, org_lib"
- "lib"
- type: array
items:
type: string
minLength: 1
examples:
- [common, org_lib]
default: null

commands_dir:
title: commands dir
description: |-
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
- [command-paths](command-paths#readme) - configuring nested paths for your source scripts
- [command-function](command-function#readme) - configuring custom internal function names
- [split-config](split-config#readme) - splitting your `bashly.yml` into several smaller files
- [multiple-lib-dirs](multiple-lib-dirs#readme) - loading libraries from multiple locations

## Bashly library features

Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -79,7 +79,7 @@ commands:
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/settings.yml
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
2 changes: 1 addition & 1 deletion examples/custom-includes/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,7 +56,7 @@ echo "After custom code"
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-includes/src/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
1 change: 1 addition & 0 deletions examples/multiple-lib-dirs/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
download
77 changes: 77 additions & 0 deletions examples/multiple-lib-dirs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
# Multiple Lib Dirs

Demonstrates how to include more than one lib directories in the generated
script.

This example was generated with:

```bash
$ bashly init --minimal
$ bashly add settings
# ... now edit settings.yml to match the example ...
$ bashly generate
# ... now edit src/root_command.sh to match the example ...
$ bashly generate
```

<!-- include: settings.yml src/root_command.sh -->

-----

## `bashly.yml`

````yaml
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
````

## `settings.yml`

````yaml
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]

````

## `src/root_command.sh`

````bash
# Calling library functions
common_function
cloud_function
````


## Output

### `$ ./download some_source`

````shell
common_function called
cloud_function called


````



3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/cloud_lib/cloud_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
cloud_function() {
echo "cloud_function called"
}
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/common_lib/common_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
common_function() {
echo "common_function called"
}
5 changes: 5 additions & 0 deletions examples/multiple-lib-dirs/settings.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]
19 changes: 19 additions & 0 deletions examples/multiple-lib-dirs/src/bashly.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/src/root_command.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
# Calling library functions
common_function
cloud_function
9 changes: 9 additions & 0 deletions examples/multiple-lib-dirs/test.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -x

bashly generate

### Try Me ###

./download some_source
2 changes: 1 addition & 1 deletion lib/bashly/libraries/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
## Note that code here should be wrapped inside bash functions, and it is
## recommended to have a separate file for each function.
##
## Subdirectories will also be scanned for *.sh, so you have no reason not
## Sub-directories will also be scanned for *.sh, so you have no reason not
## to organize your code neatly.
##
sample_function() {
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/libraries/settings/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,10 +53,16 @@ target_dir: .
# The path to use for common library files, relative to source_dir
lib_dir: lib

# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: ~

# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory
commands_dir: ~

# The extension to use when reading/writing partial script snippets
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/script/command.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -153,7 +153,13 @@ def base_usage_pattern
# This is meant to provide the user with the ability to add custom
# functions
def user_lib
@user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
@user_lib ||= begin
result = Settings.all_lib_dirs.map do |dir|
Dir["#{dir}/**/*.#{Settings.partials_extension}"]
end

result.flatten
end
end

# Returns a mixed array of Argument and Flag objects that have validations
Expand Down
16 changes: 16 additions & 0 deletions lib/bashly/settings.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,6 +15,7 @@ class << self
:enable_inspect_args,
:enable_sourcing,
:enable_view_markers,
:extra_lib_dirs,
:formatter,
:function_names,
:lib_dir,
Expand DownExpand Up@@ -107,6 +108,21 @@ def lib_dir
@lib_dir ||= get :lib_dir
end

def extra_lib_dirs
@extra_lib_dirs ||= begin
dirs = get :extra_lib_dirs
case dirs
when Array then dirs
when String then dirs.split(',').map(&:strip)
else []
end
end
end

def all_lib_dirs
@all_lib_dirs = [full_lib_dir] + extra_lib_dirs
end

def partials_extension
@partials_extension ||= get :partials_extension
end
Expand Down
31 changes: 31 additions & 0 deletions schemas/settings.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,6 +66,37 @@
"minLength": 1,
"default": "lib"
},
"extra_lib_dirs": {
"title": "extra lib dirs",
"description": "One or more paths to use for common library files, relative to the working directory.\nMay be provided as an array or a comma delimited string.\nhttps://bashly.dev/usage/settings/#extra_lib_dirs",
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"minLength": 1,
"examples": [
"common, org_lib",
"lib"
]
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"examples": [
[
"common",
"org_lib"
]
]
}
],
"default": null
},
"commands_dir": {
"title": "commands dir",
"description": "The path to use for command files, relative to source_dir\nhttps://bashly.dev/usage/settings/#commands_dir",
Expand Down
8 changes: 8 additions & 0 deletions spec/approvals/examples/multiple-lib-dirs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
+ bashly generate
creating user files in src
skipped src/root_command.sh (exists)
created ./download
run ./download --help to test your bash script
+ ./download some_source
common_function called
cloud_function called
20 changes: 20 additions & 0 deletions spec/bashly/settings_spec.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,6 +103,26 @@
end
end

describe '::extra_lib_dirs' do
context 'when set using env var as a comma delimited string' do
before { ENV['BASHLY_EXTRA_LIB_DIRS'] = 'one,two' }
after { ENV['BASHLY_EXTRA_LIB_DIRS'] = nil }

it 'converts comma delimited string to an array' do
expect(subject.extra_lib_dirs).to match_array %w[one two]
end
end

context 'when provided as an array' do
let(:config) { Config.new({ 'extra_lib_dirs' => %w[item1 item2] }) }

it 'returns the array as is' do
allow(subject).to receive(:user_settings).and_return(config)
expect(subject.extra_lib_dirs).to match_array %w[item1 item2]
end
end
end

describe '::production?' do
it 'returns false by default' do
expect(subject.production?).to be false
Expand Down
21 changes: 21 additions & 0 deletions support/schema/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,6 +63,27 @@ properties:
type: string
minLength: 1
default: lib
extra_lib_dirs:
title: extra lib dirs
description: |-
One or more paths to use for common library files, relative to the working directory.
May be provided as an array or a comma delimited string.
https://bashly.dev/usage/settings/#extra_lib_dirs
oneOf:
- type: "null"
- type: string
minLength: 1
examples:
- "common, org_lib"
- "lib"
- type: array
items:
type: string
minLength: 1
examples:
- [common, org_lib]
default: null

commands_dir:
title: commands dir
description: |-
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
- [command-paths](command-paths#readme) - configuring nested paths for your source scripts
- [command-function](command-function#readme) - configuring custom internal function names
- [split-config](split-config#readme) - splitting your `bashly.yml` into several smaller files
- [multiple-lib-dirs](multiple-lib-dirs#readme) - loading libraries from multiple locations

## Bashly library features

Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -79,7 +79,7 @@ commands:
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/settings.yml
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
2 changes: 1 addition & 1 deletion examples/custom-includes/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,7 +56,7 @@ echo "After custom code"
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-includes/src/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
1 change: 1 addition & 0 deletions examples/multiple-lib-dirs/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
download
77 changes: 77 additions & 0 deletions examples/multiple-lib-dirs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
# Multiple Lib Dirs

Demonstrates how to include more than one lib directories in the generated
script.

This example was generated with:

```bash
$ bashly init --minimal
$ bashly add settings
# ... now edit settings.yml to match the example ...
$ bashly generate
# ... now edit src/root_command.sh to match the example ...
$ bashly generate
```

<!-- include: settings.yml src/root_command.sh -->

-----

## `bashly.yml`

````yaml
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
````

## `settings.yml`

````yaml
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]

````

## `src/root_command.sh`

````bash
# Calling library functions
common_function
cloud_function
````


## Output

### `$ ./download some_source`

````shell
common_function called
cloud_function called


````



3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/cloud_lib/cloud_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
cloud_function() {
echo "cloud_function called"
}
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/common_lib/common_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
common_function() {
echo "common_function called"
}
5 changes: 5 additions & 0 deletions examples/multiple-lib-dirs/settings.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]
19 changes: 19 additions & 0 deletions examples/multiple-lib-dirs/src/bashly.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/src/root_command.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
# Calling library functions
common_function
cloud_function
9 changes: 9 additions & 0 deletions examples/multiple-lib-dirs/test.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -x

bashly generate

### Try Me ###

./download some_source
2 changes: 1 addition & 1 deletion lib/bashly/libraries/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
## Note that code here should be wrapped inside bash functions, and it is
## recommended to have a separate file for each function.
##
## Subdirectories will also be scanned for *.sh, so you have no reason not
## Sub-directories will also be scanned for *.sh, so you have no reason not
## to organize your code neatly.
##
sample_function() {
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/libraries/settings/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,10 +53,16 @@ target_dir: .
# The path to use for common library files, relative to source_dir
lib_dir: lib

# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: ~

# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory
commands_dir: ~

# The extension to use when reading/writing partial script snippets
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/script/command.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -153,7 +153,13 @@ def base_usage_pattern
# This is meant to provide the user with the ability to add custom
# functions
def user_lib
@user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
@user_lib ||= begin
result = Settings.all_lib_dirs.map do |dir|
Dir["#{dir}/**/*.#{Settings.partials_extension}"]
end

result.flatten
end
end

# Returns a mixed array of Argument and Flag objects that have validations
Expand Down
16 changes: 16 additions & 0 deletions lib/bashly/settings.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,6 +15,7 @@ class << self
:enable_inspect_args,
:enable_sourcing,
:enable_view_markers,
:extra_lib_dirs,
:formatter,
:function_names,
:lib_dir,
Expand DownExpand Up@@ -107,6 +108,21 @@ def lib_dir
@lib_dir ||= get :lib_dir
end

def extra_lib_dirs
@extra_lib_dirs ||= begin
dirs = get :extra_lib_dirs
case dirs
when Array then dirs
when String then dirs.split(',').map(&:strip)
else []
end
end
end

def all_lib_dirs
@all_lib_dirs = [full_lib_dir] + extra_lib_dirs
end

def partials_extension
@partials_extension ||= get :partials_extension
end
Expand Down
31 changes: 31 additions & 0 deletions schemas/settings.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,6 +66,37 @@
"minLength": 1,
"default": "lib"
},
"extra_lib_dirs": {
"title": "extra lib dirs",
"description": "One or more paths to use for common library files, relative to the working directory.\nMay be provided as an array or a comma delimited string.\nhttps://bashly.dev/usage/settings/#extra_lib_dirs",
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"minLength": 1,
"examples": [
"common, org_lib",
"lib"
]
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"examples": [
[
"common",
"org_lib"
]
]
}
],
"default": null
},
"commands_dir": {
"title": "commands dir",
"description": "The path to use for command files, relative to source_dir\nhttps://bashly.dev/usage/settings/#commands_dir",
Expand Down
8 changes: 8 additions & 0 deletions spec/approvals/examples/multiple-lib-dirs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
+ bashly generate
creating user files in src
skipped src/root_command.sh (exists)
created ./download
run ./download --help to test your bash script
+ ./download some_source
common_function called
cloud_function called
20 changes: 20 additions & 0 deletions spec/bashly/settings_spec.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,6 +103,26 @@
end
end

describe '::extra_lib_dirs' do
context 'when set using env var as a comma delimited string' do
before { ENV['BASHLY_EXTRA_LIB_DIRS'] = 'one,two' }
after { ENV['BASHLY_EXTRA_LIB_DIRS'] = nil }

it 'converts comma delimited string to an array' do
expect(subject.extra_lib_dirs).to match_array %w[one two]
end
end

context 'when provided as an array' do
let(:config) { Config.new({ 'extra_lib_dirs' => %w[item1 item2] }) }

it 'returns the array as is' do
allow(subject).to receive(:user_settings).and_return(config)
expect(subject.extra_lib_dirs).to match_array %w[item1 item2]
end
end
end

describe '::production?' do
it 'returns false by default' do
expect(subject.production?).to be false
Expand Down
21 changes: 21 additions & 0 deletions support/schema/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,6 +63,27 @@ properties:
type: string
minLength: 1
default: lib
extra_lib_dirs:
title: extra lib dirs
description: |-
One or more paths to use for common library files, relative to the working directory.
May be provided as an array or a comma delimited string.
https://bashly.dev/usage/settings/#extra_lib_dirs
oneOf:
- type: "null"
- type: string
minLength: 1
examples:
- "common, org_lib"
- "lib"
- type: array
items:
type: string
minLength: 1
examples:
- [common, org_lib]
default: null

commands_dir:
title: commands dir
description: |-
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
- [command-paths](command-paths#readme) - configuring nested paths for your source scripts
- [command-function](command-function#readme) - configuring custom internal function names
- [split-config](split-config#readme) - splitting your `bashly.yml` into several smaller files
- [multiple-lib-dirs](multiple-lib-dirs#readme) - loading libraries from multiple locations

## Bashly library features

Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -79,7 +79,7 @@ commands:
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/settings.yml
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
2 changes: 1 addition & 1 deletion examples/custom-includes/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,7 +56,7 @@ echo "After custom code"
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-includes/src/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
1 change: 1 addition & 0 deletions examples/multiple-lib-dirs/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
download
77 changes: 77 additions & 0 deletions examples/multiple-lib-dirs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
# Multiple Lib Dirs

Demonstrates how to include more than one lib directories in the generated
script.

This example was generated with:

```bash
$ bashly init --minimal
$ bashly add settings
# ... now edit settings.yml to match the example ...
$ bashly generate
# ... now edit src/root_command.sh to match the example ...
$ bashly generate
```

<!-- include: settings.yml src/root_command.sh -->

-----

## `bashly.yml`

````yaml
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
````

## `settings.yml`

````yaml
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]

````

## `src/root_command.sh`

````bash
# Calling library functions
common_function
cloud_function
````


## Output

### `$ ./download some_source`

````shell
common_function called
cloud_function called


````



3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/cloud_lib/cloud_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
cloud_function() {
echo "cloud_function called"
}
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/common_lib/common_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
common_function() {
echo "common_function called"
}
5 changes: 5 additions & 0 deletions examples/multiple-lib-dirs/settings.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]
19 changes: 19 additions & 0 deletions examples/multiple-lib-dirs/src/bashly.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/src/root_command.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
# Calling library functions
common_function
cloud_function
9 changes: 9 additions & 0 deletions examples/multiple-lib-dirs/test.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -x

bashly generate

### Try Me ###

./download some_source
2 changes: 1 addition & 1 deletion lib/bashly/libraries/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
## Note that code here should be wrapped inside bash functions, and it is
## recommended to have a separate file for each function.
##
## Subdirectories will also be scanned for *.sh, so you have no reason not
## Sub-directories will also be scanned for *.sh, so you have no reason not
## to organize your code neatly.
##
sample_function() {
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/libraries/settings/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,10 +53,16 @@ target_dir: .
# The path to use for common library files, relative to source_dir
lib_dir: lib

# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: ~

# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory
commands_dir: ~

# The extension to use when reading/writing partial script snippets
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/script/command.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -153,7 +153,13 @@ def base_usage_pattern
# This is meant to provide the user with the ability to add custom
# functions
def user_lib
@user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
@user_lib ||= begin
result = Settings.all_lib_dirs.map do |dir|
Dir["#{dir}/**/*.#{Settings.partials_extension}"]
end

result.flatten
end
end

# Returns a mixed array of Argument and Flag objects that have validations
Expand Down
16 changes: 16 additions & 0 deletions lib/bashly/settings.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,6 +15,7 @@ class << self
:enable_inspect_args,
:enable_sourcing,
:enable_view_markers,
:extra_lib_dirs,
:formatter,
:function_names,
:lib_dir,
Expand DownExpand Up@@ -107,6 +108,21 @@ def lib_dir
@lib_dir ||= get :lib_dir
end

def extra_lib_dirs
@extra_lib_dirs ||= begin
dirs = get :extra_lib_dirs
case dirs
when Array then dirs
when String then dirs.split(',').map(&:strip)
else []
end
end
end

def all_lib_dirs
@all_lib_dirs = [full_lib_dir] + extra_lib_dirs
end

def partials_extension
@partials_extension ||= get :partials_extension
end
Expand Down
31 changes: 31 additions & 0 deletions schemas/settings.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,6 +66,37 @@
"minLength": 1,
"default": "lib"
},
"extra_lib_dirs": {
"title": "extra lib dirs",
"description": "One or more paths to use for common library files, relative to the working directory.\nMay be provided as an array or a comma delimited string.\nhttps://bashly.dev/usage/settings/#extra_lib_dirs",
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"minLength": 1,
"examples": [
"common, org_lib",
"lib"
]
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"examples": [
[
"common",
"org_lib"
]
]
}
],
"default": null
},
"commands_dir": {
"title": "commands dir",
"description": "The path to use for command files, relative to source_dir\nhttps://bashly.dev/usage/settings/#commands_dir",
Expand Down
8 changes: 8 additions & 0 deletions spec/approvals/examples/multiple-lib-dirs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
+ bashly generate
creating user files in src
skipped src/root_command.sh (exists)
created ./download
run ./download --help to test your bash script
+ ./download some_source
common_function called
cloud_function called
20 changes: 20 additions & 0 deletions spec/bashly/settings_spec.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,6 +103,26 @@
end
end

describe '::extra_lib_dirs' do
context 'when set using env var as a comma delimited string' do
before { ENV['BASHLY_EXTRA_LIB_DIRS'] = 'one,two' }
after { ENV['BASHLY_EXTRA_LIB_DIRS'] = nil }

it 'converts comma delimited string to an array' do
expect(subject.extra_lib_dirs).to match_array %w[one two]
end
end

context 'when provided as an array' do
let(:config) { Config.new({ 'extra_lib_dirs' => %w[item1 item2] }) }

it 'returns the array as is' do
allow(subject).to receive(:user_settings).and_return(config)
expect(subject.extra_lib_dirs).to match_array %w[item1 item2]
end
end
end

describe '::production?' do
it 'returns false by default' do
expect(subject.production?).to be false
Expand Down
21 changes: 21 additions & 0 deletions support/schema/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,6 +63,27 @@ properties:
type: string
minLength: 1
default: lib
extra_lib_dirs:
title: extra lib dirs
description: |-
One or more paths to use for common library files, relative to the working directory.
May be provided as an array or a comma delimited string.
https://bashly.dev/usage/settings/#extra_lib_dirs
oneOf:
- type: "null"
- type: string
minLength: 1
examples:
- "common, org_lib"
- "lib"
- type: array
items:
type: string
minLength: 1
examples:
- [common, org_lib]
default: null

commands_dir:
title: commands dir
description: |-
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
- [command-paths](command-paths#readme) - configuring nested paths for your source scripts
- [command-function](command-function#readme) - configuring custom internal function names
- [split-config](split-config#readme) - splitting your `bashly.yml` into several smaller files
- [multiple-lib-dirs](multiple-lib-dirs#readme) - loading libraries from multiple locations

## Bashly library features

Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -79,7 +79,7 @@ commands:
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/settings.yml
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
2 changes: 1 addition & 1 deletion examples/custom-includes/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,7 +56,7 @@ echo "After custom code"
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-includes/src/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
1 change: 1 addition & 0 deletions examples/multiple-lib-dirs/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
download
77 changes: 77 additions & 0 deletions examples/multiple-lib-dirs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
# Multiple Lib Dirs

Demonstrates how to include more than one lib directories in the generated
script.

This example was generated with:

```bash
$ bashly init --minimal
$ bashly add settings
# ... now edit settings.yml to match the example ...
$ bashly generate
# ... now edit src/root_command.sh to match the example ...
$ bashly generate
```

<!-- include: settings.yml src/root_command.sh -->

-----

## `bashly.yml`

````yaml
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
````

## `settings.yml`

````yaml
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]

````

## `src/root_command.sh`

````bash
# Calling library functions
common_function
cloud_function
````


## Output

### `$ ./download some_source`

````shell
common_function called
cloud_function called


````



3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/cloud_lib/cloud_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
cloud_function() {
echo "cloud_function called"
}
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/common_lib/common_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
common_function() {
echo "common_function called"
}
5 changes: 5 additions & 0 deletions examples/multiple-lib-dirs/settings.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]
19 changes: 19 additions & 0 deletions examples/multiple-lib-dirs/src/bashly.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/src/root_command.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
# Calling library functions
common_function
cloud_function
9 changes: 9 additions & 0 deletions examples/multiple-lib-dirs/test.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -x

bashly generate

### Try Me ###

./download some_source
2 changes: 1 addition & 1 deletion lib/bashly/libraries/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
## Note that code here should be wrapped inside bash functions, and it is
## recommended to have a separate file for each function.
##
## Subdirectories will also be scanned for *.sh, so you have no reason not
## Sub-directories will also be scanned for *.sh, so you have no reason not
## to organize your code neatly.
##
sample_function() {
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/libraries/settings/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,10 +53,16 @@ target_dir: .
# The path to use for common library files, relative to source_dir
lib_dir: lib

# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: ~

# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory
commands_dir: ~

# The extension to use when reading/writing partial script snippets
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/script/command.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -153,7 +153,13 @@ def base_usage_pattern
# This is meant to provide the user with the ability to add custom
# functions
def user_lib
@user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
@user_lib ||= begin
result = Settings.all_lib_dirs.map do |dir|
Dir["#{dir}/**/*.#{Settings.partials_extension}"]
end

result.flatten
end
end

# Returns a mixed array of Argument and Flag objects that have validations
Expand Down
16 changes: 16 additions & 0 deletions lib/bashly/settings.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,6 +15,7 @@ class << self
:enable_inspect_args,
:enable_sourcing,
:enable_view_markers,
:extra_lib_dirs,
:formatter,
:function_names,
:lib_dir,
Expand DownExpand Up@@ -107,6 +108,21 @@ def lib_dir
@lib_dir ||= get :lib_dir
end

def extra_lib_dirs
@extra_lib_dirs ||= begin
dirs = get :extra_lib_dirs
case dirs
when Array then dirs
when String then dirs.split(',').map(&:strip)
else []
end
end
end

def all_lib_dirs
@all_lib_dirs = [full_lib_dir] + extra_lib_dirs
end

def partials_extension
@partials_extension ||= get :partials_extension
end
Expand Down
31 changes: 31 additions & 0 deletions schemas/settings.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,6 +66,37 @@
"minLength": 1,
"default": "lib"
},
"extra_lib_dirs": {
"title": "extra lib dirs",
"description": "One or more paths to use for common library files, relative to the working directory.\nMay be provided as an array or a comma delimited string.\nhttps://bashly.dev/usage/settings/#extra_lib_dirs",
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"minLength": 1,
"examples": [
"common, org_lib",
"lib"
]
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"examples": [
[
"common",
"org_lib"
]
]
}
],
"default": null
},
"commands_dir": {
"title": "commands dir",
"description": "The path to use for command files, relative to source_dir\nhttps://bashly.dev/usage/settings/#commands_dir",
Expand Down
8 changes: 8 additions & 0 deletions spec/approvals/examples/multiple-lib-dirs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
+ bashly generate
creating user files in src
skipped src/root_command.sh (exists)
created ./download
run ./download --help to test your bash script
+ ./download some_source
common_function called
cloud_function called
20 changes: 20 additions & 0 deletions spec/bashly/settings_spec.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,6 +103,26 @@
end
end

describe '::extra_lib_dirs' do
context 'when set using env var as a comma delimited string' do
before { ENV['BASHLY_EXTRA_LIB_DIRS'] = 'one,two' }
after { ENV['BASHLY_EXTRA_LIB_DIRS'] = nil }

it 'converts comma delimited string to an array' do
expect(subject.extra_lib_dirs).to match_array %w[one two]
end
end

context 'when provided as an array' do
let(:config) { Config.new({ 'extra_lib_dirs' => %w[item1 item2] }) }

it 'returns the array as is' do
allow(subject).to receive(:user_settings).and_return(config)
expect(subject.extra_lib_dirs).to match_array %w[item1 item2]
end
end
end

describe '::production?' do
it 'returns false by default' do
expect(subject.production?).to be false
Expand Down
21 changes: 21 additions & 0 deletions support/schema/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,6 +63,27 @@ properties:
type: string
minLength: 1
default: lib
extra_lib_dirs:
title: extra lib dirs
description: |-
One or more paths to use for common library files, relative to the working directory.
May be provided as an array or a comma delimited string.
https://bashly.dev/usage/settings/#extra_lib_dirs
oneOf:
- type: "null"
- type: string
minLength: 1
examples:
- "common, org_lib"
- "lib"
- type: array
items:
type: string
minLength: 1
examples:
- [common, org_lib]
default: null

commands_dir:
title: commands dir
description: |-
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
- [command-paths](command-paths#readme) - configuring nested paths for your source scripts
- [command-function](command-function#readme) - configuring custom internal function names
- [split-config](split-config#readme) - splitting your `bashly.yml` into several smaller files
- [multiple-lib-dirs](multiple-lib-dirs#readme) - loading libraries from multiple locations

## Bashly library features

Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -79,7 +79,7 @@ commands:
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/settings.yml
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
2 changes: 1 addition & 1 deletion examples/custom-includes/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,7 +56,7 @@ echo "After custom code"
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-includes/src/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
1 change: 1 addition & 0 deletions examples/multiple-lib-dirs/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
download
77 changes: 77 additions & 0 deletions examples/multiple-lib-dirs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
# Multiple Lib Dirs

Demonstrates how to include more than one lib directories in the generated
script.

This example was generated with:

```bash
$ bashly init --minimal
$ bashly add settings
# ... now edit settings.yml to match the example ...
$ bashly generate
# ... now edit src/root_command.sh to match the example ...
$ bashly generate
```

<!-- include: settings.yml src/root_command.sh -->

-----

## `bashly.yml`

````yaml
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
````

## `settings.yml`

````yaml
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]

````

## `src/root_command.sh`

````bash
# Calling library functions
common_function
cloud_function
````


## Output

### `$ ./download some_source`

````shell
common_function called
cloud_function called


````



3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/cloud_lib/cloud_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
cloud_function() {
echo "cloud_function called"
}
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/common_lib/common_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
common_function() {
echo "common_function called"
}
5 changes: 5 additions & 0 deletions examples/multiple-lib-dirs/settings.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]
19 changes: 19 additions & 0 deletions examples/multiple-lib-dirs/src/bashly.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/src/root_command.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
# Calling library functions
common_function
cloud_function
9 changes: 9 additions & 0 deletions examples/multiple-lib-dirs/test.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -x

bashly generate

### Try Me ###

./download some_source
2 changes: 1 addition & 1 deletion lib/bashly/libraries/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
## Note that code here should be wrapped inside bash functions, and it is
## recommended to have a separate file for each function.
##
## Subdirectories will also be scanned for *.sh, so you have no reason not
## Sub-directories will also be scanned for *.sh, so you have no reason not
## to organize your code neatly.
##
sample_function() {
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/libraries/settings/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,10 +53,16 @@ target_dir: .
# The path to use for common library files, relative to source_dir
lib_dir: lib

# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: ~

# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory
commands_dir: ~

# The extension to use when reading/writing partial script snippets
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/script/command.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -153,7 +153,13 @@ def base_usage_pattern
# This is meant to provide the user with the ability to add custom
# functions
def user_lib
@user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
@user_lib ||= begin
result = Settings.all_lib_dirs.map do |dir|
Dir["#{dir}/**/*.#{Settings.partials_extension}"]
end

result.flatten
end
end

# Returns a mixed array of Argument and Flag objects that have validations
Expand Down
16 changes: 16 additions & 0 deletions lib/bashly/settings.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,6 +15,7 @@ class << self
:enable_inspect_args,
:enable_sourcing,
:enable_view_markers,
:extra_lib_dirs,
:formatter,
:function_names,
:lib_dir,
Expand DownExpand Up@@ -107,6 +108,21 @@ def lib_dir
@lib_dir ||= get :lib_dir
end

def extra_lib_dirs
@extra_lib_dirs ||= begin
dirs = get :extra_lib_dirs
case dirs
when Array then dirs
when String then dirs.split(',').map(&:strip)
else []
end
end
end

def all_lib_dirs
@all_lib_dirs = [full_lib_dir] + extra_lib_dirs
end

def partials_extension
@partials_extension ||= get :partials_extension
end
Expand Down
31 changes: 31 additions & 0 deletions schemas/settings.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,6 +66,37 @@
"minLength": 1,
"default": "lib"
},
"extra_lib_dirs": {
"title": "extra lib dirs",
"description": "One or more paths to use for common library files, relative to the working directory.\nMay be provided as an array or a comma delimited string.\nhttps://bashly.dev/usage/settings/#extra_lib_dirs",
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"minLength": 1,
"examples": [
"common, org_lib",
"lib"
]
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"examples": [
[
"common",
"org_lib"
]
]
}
],
"default": null
},
"commands_dir": {
"title": "commands dir",
"description": "The path to use for command files, relative to source_dir\nhttps://bashly.dev/usage/settings/#commands_dir",
Expand Down
8 changes: 8 additions & 0 deletions spec/approvals/examples/multiple-lib-dirs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
+ bashly generate
creating user files in src
skipped src/root_command.sh (exists)
created ./download
run ./download --help to test your bash script
+ ./download some_source
common_function called
cloud_function called
20 changes: 20 additions & 0 deletions spec/bashly/settings_spec.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,6 +103,26 @@
end
end

describe '::extra_lib_dirs' do
context 'when set using env var as a comma delimited string' do
before { ENV['BASHLY_EXTRA_LIB_DIRS'] = 'one,two' }
after { ENV['BASHLY_EXTRA_LIB_DIRS'] = nil }

it 'converts comma delimited string to an array' do
expect(subject.extra_lib_dirs).to match_array %w[one two]
end
end

context 'when provided as an array' do
let(:config) { Config.new({ 'extra_lib_dirs' => %w[item1 item2] }) }

it 'returns the array as is' do
allow(subject).to receive(:user_settings).and_return(config)
expect(subject.extra_lib_dirs).to match_array %w[item1 item2]
end
end
end

describe '::production?' do
it 'returns false by default' do
expect(subject.production?).to be false
Expand Down
21 changes: 21 additions & 0 deletions support/schema/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,6 +63,27 @@ properties:
type: string
minLength: 1
default: lib
extra_lib_dirs:
title: extra lib dirs
description: |-
One or more paths to use for common library files, relative to the working directory.
May be provided as an array or a comma delimited string.
https://bashly.dev/usage/settings/#extra_lib_dirs
oneOf:
- type: "null"
- type: string
minLength: 1
examples:
- "common, org_lib"
- "lib"
- type: array
items:
type: string
minLength: 1
examples:
- [common, org_lib]
default: null

commands_dir:
title: commands dir
description: |-
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
- [command-paths](command-paths#readme) - configuring nested paths for your source scripts
- [command-function](command-function#readme) - configuring custom internal function names
- [split-config](split-config#readme) - splitting your `bashly.yml` into several smaller files
- [multiple-lib-dirs](multiple-lib-dirs#readme) - loading libraries from multiple locations

## Bashly library features

Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -79,7 +79,7 @@ commands:
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/settings.yml
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
2 changes: 1 addition & 1 deletion examples/custom-includes/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,7 +56,7 @@ echo "After custom code"
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-includes/src/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
1 change: 1 addition & 0 deletions examples/multiple-lib-dirs/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
download
77 changes: 77 additions & 0 deletions examples/multiple-lib-dirs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
# Multiple Lib Dirs

Demonstrates how to include more than one lib directories in the generated
script.

This example was generated with:

```bash
$ bashly init --minimal
$ bashly add settings
# ... now edit settings.yml to match the example ...
$ bashly generate
# ... now edit src/root_command.sh to match the example ...
$ bashly generate
```

<!-- include: settings.yml src/root_command.sh -->

-----

## `bashly.yml`

````yaml
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
````

## `settings.yml`

````yaml
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]

````

## `src/root_command.sh`

````bash
# Calling library functions
common_function
cloud_function
````


## Output

### `$ ./download some_source`

````shell
common_function called
cloud_function called


````



3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/cloud_lib/cloud_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
cloud_function() {
echo "cloud_function called"
}
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/common_lib/common_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
common_function() {
echo "common_function called"
}
5 changes: 5 additions & 0 deletions examples/multiple-lib-dirs/settings.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]
19 changes: 19 additions & 0 deletions examples/multiple-lib-dirs/src/bashly.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/src/root_command.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
# Calling library functions
common_function
cloud_function
9 changes: 9 additions & 0 deletions examples/multiple-lib-dirs/test.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -x

bashly generate

### Try Me ###

./download some_source
2 changes: 1 addition & 1 deletion lib/bashly/libraries/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
## Note that code here should be wrapped inside bash functions, and it is
## recommended to have a separate file for each function.
##
## Subdirectories will also be scanned for *.sh, so you have no reason not
## Sub-directories will also be scanned for *.sh, so you have no reason not
## to organize your code neatly.
##
sample_function() {
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/libraries/settings/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,10 +53,16 @@ target_dir: .
# The path to use for common library files, relative to source_dir
lib_dir: lib

# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: ~

# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory
commands_dir: ~

# The extension to use when reading/writing partial script snippets
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/script/command.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -153,7 +153,13 @@ def base_usage_pattern
# This is meant to provide the user with the ability to add custom
# functions
def user_lib
@user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
@user_lib ||= begin
result = Settings.all_lib_dirs.map do |dir|
Dir["#{dir}/**/*.#{Settings.partials_extension}"]
end

result.flatten
end
end

# Returns a mixed array of Argument and Flag objects that have validations
Expand Down
16 changes: 16 additions & 0 deletions lib/bashly/settings.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,6 +15,7 @@ class << self
:enable_inspect_args,
:enable_sourcing,
:enable_view_markers,
:extra_lib_dirs,
:formatter,
:function_names,
:lib_dir,
Expand DownExpand Up@@ -107,6 +108,21 @@ def lib_dir
@lib_dir ||= get :lib_dir
end

def extra_lib_dirs
@extra_lib_dirs ||= begin
dirs = get :extra_lib_dirs
case dirs
when Array then dirs
when String then dirs.split(',').map(&:strip)
else []
end
end
end

def all_lib_dirs
@all_lib_dirs = [full_lib_dir] + extra_lib_dirs
end

def partials_extension
@partials_extension ||= get :partials_extension
end
Expand Down
31 changes: 31 additions & 0 deletions schemas/settings.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,6 +66,37 @@
"minLength": 1,
"default": "lib"
},
"extra_lib_dirs": {
"title": "extra lib dirs",
"description": "One or more paths to use for common library files, relative to the working directory.\nMay be provided as an array or a comma delimited string.\nhttps://bashly.dev/usage/settings/#extra_lib_dirs",
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"minLength": 1,
"examples": [
"common, org_lib",
"lib"
]
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"examples": [
[
"common",
"org_lib"
]
]
}
],
"default": null
},
"commands_dir": {
"title": "commands dir",
"description": "The path to use for command files, relative to source_dir\nhttps://bashly.dev/usage/settings/#commands_dir",
Expand Down
8 changes: 8 additions & 0 deletions spec/approvals/examples/multiple-lib-dirs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
+ bashly generate
creating user files in src
skipped src/root_command.sh (exists)
created ./download
run ./download --help to test your bash script
+ ./download some_source
common_function called
cloud_function called
20 changes: 20 additions & 0 deletions spec/bashly/settings_spec.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,6 +103,26 @@
end
end

describe '::extra_lib_dirs' do
context 'when set using env var as a comma delimited string' do
before { ENV['BASHLY_EXTRA_LIB_DIRS'] = 'one,two' }
after { ENV['BASHLY_EXTRA_LIB_DIRS'] = nil }

it 'converts comma delimited string to an array' do
expect(subject.extra_lib_dirs).to match_array %w[one two]
end
end

context 'when provided as an array' do
let(:config) { Config.new({ 'extra_lib_dirs' => %w[item1 item2] }) }

it 'returns the array as is' do
allow(subject).to receive(:user_settings).and_return(config)
expect(subject.extra_lib_dirs).to match_array %w[item1 item2]
end
end
end

describe '::production?' do
it 'returns false by default' do
expect(subject.production?).to be false
Expand Down
21 changes: 21 additions & 0 deletions support/schema/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,6 +63,27 @@ properties:
type: string
minLength: 1
default: lib
extra_lib_dirs:
title: extra lib dirs
description: |-
One or more paths to use for common library files, relative to the working directory.
May be provided as an array or a comma delimited string.
https://bashly.dev/usage/settings/#extra_lib_dirs
oneOf:
- type: "null"
- type: string
minLength: 1
examples:
- "common, org_lib"
- "lib"
- type: array
items:
type: string
minLength: 1
examples:
- [common, org_lib]
default: null

commands_dir:
title: commands dir
description: |-
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
- [command-paths](command-paths#readme) - configuring nested paths for your source scripts
- [command-function](command-function#readme) - configuring custom internal function names
- [split-config](split-config#readme) - splitting your `bashly.yml` into several smaller files
- [multiple-lib-dirs](multiple-lib-dirs#readme) - loading libraries from multiple locations

## Bashly library features

Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -79,7 +79,7 @@ commands:
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
Expand Down
2 changes: 1 addition & 1 deletion examples/command-paths/settings.yml
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory

# commands_dir: ~
commands_dir: commands
2 changes: 1 addition & 1 deletion examples/custom-includes/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,7 +56,7 @@ echo "After custom code"
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-includes/src/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
# Note that code here should be wrapped inside bash functions, and it is
# recommended to have a separate file for each function.
#
# Subdirectories will also be scanned for *.sh, so you have no reason not
# Sub-directories will also be scanned for *.sh, so you have no reason not
# to organize your code neatly.
#
sample_function() {
Expand Down
1 change: 1 addition & 0 deletions examples/multiple-lib-dirs/.gitignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
download
77 changes: 77 additions & 0 deletions examples/multiple-lib-dirs/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
# Multiple Lib Dirs

Demonstrates how to include more than one lib directories in the generated
script.

This example was generated with:

```bash
$ bashly init --minimal
$ bashly add settings
# ... now edit settings.yml to match the example ...
$ bashly generate
# ... now edit src/root_command.sh to match the example ...
$ bashly generate
```

<!-- include: settings.yml src/root_command.sh -->

-----

## `bashly.yml`

````yaml
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
````

## `settings.yml`

````yaml
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]

````

## `src/root_command.sh`

````bash
# Calling library functions
common_function
cloud_function
````


## Output

### `$ ./download some_source`

````shell
common_function called
cloud_function called


````



3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/cloud_lib/cloud_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
cloud_function() {
echo "cloud_function called"
}
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/common_lib/common_function.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
common_function() {
echo "common_function called"
}
5 changes: 5 additions & 0 deletions examples/multiple-lib-dirs/settings.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: [common_lib, cloud_lib]
19 changes: 19 additions & 0 deletions examples/multiple-lib-dirs/src/bashly.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
name: download
help: Sample minimal application without commands
version: 0.1.0

args:
- name: source
required: true
help: URL to download from
- name: target
help: "Target filename (default: same as source)"

flags:
- long: --force
short: -f
help: Overwrite existing files

examples:
- download example.com
- download example.com ./output -f
3 changes: 3 additions & 0 deletions examples/multiple-lib-dirs/src/root_command.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
# Calling library functions
common_function
cloud_function
9 changes: 9 additions & 0 deletions examples/multiple-lib-dirs/test.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -x

bashly generate

### Try Me ###

./download some_source
2 changes: 1 addition & 1 deletion lib/bashly/libraries/lib/sample_function.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@
## Note that code here should be wrapped inside bash functions, and it is
## recommended to have a separate file for each function.
##
## Subdirectories will also be scanned for *.sh, so you have no reason not
## Sub-directories will also be scanned for *.sh, so you have no reason not
## to organize your code neatly.
##
sample_function() {
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/libraries/settings/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -53,10 +53,16 @@ target_dir: .
# The path to use for common library files, relative to source_dir
lib_dir: lib

# An array or comma delimited string of additional directories to search for
# bash functions. Any bash script found in any of these directories
# (or sub-directories) will be merged into the final script.
# Note that this is relative to the working directory.
extra_lib_dirs: ~

# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
# directory, and each command will get its own sub-directory
commands_dir: ~

# The extension to use when reading/writing partial script snippets
Expand Down
8 changes: 7 additions & 1 deletion lib/bashly/script/command.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -153,7 +153,13 @@ def base_usage_pattern
# This is meant to provide the user with the ability to add custom
# functions
def user_lib
@user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
@user_lib ||= begin
result = Settings.all_lib_dirs.map do |dir|
Dir["#{dir}/**/*.#{Settings.partials_extension}"]
end

result.flatten
end
end

# Returns a mixed array of Argument and Flag objects that have validations
Expand Down
16 changes: 16 additions & 0 deletions lib/bashly/settings.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,6 +15,7 @@ class << self
:enable_inspect_args,
:enable_sourcing,
:enable_view_markers,
:extra_lib_dirs,
:formatter,
:function_names,
:lib_dir,
Expand DownExpand Up@@ -107,6 +108,21 @@ def lib_dir
@lib_dir ||= get :lib_dir
end

def extra_lib_dirs
@extra_lib_dirs ||= begin
dirs = get :extra_lib_dirs
case dirs
when Array then dirs
when String then dirs.split(',').map(&:strip)
else []
end
end
end

def all_lib_dirs
@all_lib_dirs = [full_lib_dir] + extra_lib_dirs
end

def partials_extension
@partials_extension ||= get :partials_extension
end
Expand Down
31 changes: 31 additions & 0 deletions schemas/settings.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,6 +66,37 @@
"minLength": 1,
"default": "lib"
},
"extra_lib_dirs": {
"title": "extra lib dirs",
"description": "One or more paths to use for common library files, relative to the working directory.\nMay be provided as an array or a comma delimited string.\nhttps://bashly.dev/usage/settings/#extra_lib_dirs",
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"minLength": 1,
"examples": [
"common, org_lib",
"lib"
]
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"examples": [
[
"common",
"org_lib"
]
]
}
],
"default": null
},
"commands_dir": {
"title": "commands dir",
"description": "The path to use for command files, relative to source_dir\nhttps://bashly.dev/usage/settings/#commands_dir",
Expand Down
8 changes: 8 additions & 0 deletions spec/approvals/examples/multiple-lib-dirs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
+ bashly generate
creating user files in src
skipped src/root_command.sh (exists)
created ./download
run ./download --help to test your bash script
+ ./download some_source
common_function called
cloud_function called
20 changes: 20 additions & 0 deletions spec/bashly/settings_spec.rb
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,6 +103,26 @@
end
end

describe '::extra_lib_dirs' do
context 'when set using env var as a comma delimited string' do
before { ENV['BASHLY_EXTRA_LIB_DIRS'] = 'one,two' }
after { ENV['BASHLY_EXTRA_LIB_DIRS'] = nil }

it 'converts comma delimited string to an array' do
expect(subject.extra_lib_dirs).to match_array %w[one two]
end
end

context 'when provided as an array' do
let(:config) { Config.new({ 'extra_lib_dirs' => %w[item1 item2] }) }

it 'returns the array as is' do
allow(subject).to receive(:user_settings).and_return(config)
expect(subject.extra_lib_dirs).to match_array %w[item1 item2]
end
end
end

describe '::production?' do
it 'returns false by default' do
expect(subject.production?).to be false
Expand Down
21 changes: 21 additions & 0 deletions support/schema/settings.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,6 +63,27 @@ properties:
type: string
minLength: 1
default: lib
extra_lib_dirs:
title: extra lib dirs
description: |-
One or more paths to use for common library files, relative to the working directory.
May be provided as an array or a comma delimited string.
https://bashly.dev/usage/settings/#extra_lib_dirs
oneOf:
- type: "null"
- type: string
minLength: 1
examples:
- "common, org_lib"
- "lib"
- type: array
items:
type: string
minLength: 1
examples:
- [common, org_lib]
default: null

commands_dir:
title: commands dir
description: |-
Expand Down