diff --git a/.gitallowed b/.gitallowed new file mode 100644 index 0000000..a462a19 --- /dev/null +++ b/.gitallowed @@ -0,0 +1,5 @@ +# Gitleaks allowed patterns - false positives +# These are secret detection patterns used in git-secrets configuration, not actual secrets + +BEGIN.*PRIVATE.*KEY +git secrets --add --global diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..33e21e9 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,130 @@ +name: ๐Ÿ”’ Security & Quality Checks + +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] + +jobs: + secret-scan: + name: ๐Ÿ” Secret Detection + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Run gitleaks scan + uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + shellcheck: + name: ๐Ÿš Shell Script Analysis + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run shellcheck + uses: ludeeus/action-shellcheck@master + with: + scandir: '.' + severity: warning + format: gcc + + shfmt: + name: ๐ŸŽจ Shell Code Formatting + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install shfmt + run: | + curl -sS https://webi.sh/shfmt | sh + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Check shell formatting + run: shfmt -i 4 -bn -ci -sr -d . + + lint: + name: ๐Ÿ“‹ Linting & Validation + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Validate shell scripts + run: | + set +e + errors=0 + + for script in $(find . -name '*.sh' -type f ! -path './.git/*' ! -path './.github/*'); do + if ! bash -n "$script" 2>&1; then + echo "โŒ Syntax error in $script" + errors=$((errors + 1)) + fi + done + + if [ $errors -gt 0 ]; then + echo "๐Ÿšจ Found $errors shell scripts with syntax errors" + exit 1 + fi + echo "โœ… All shell scripts have valid syntax" + + readme-check: + name: ๐Ÿ“– README Validation + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Verify README content + run: | + # Check if README mentions security or has a link to SECURITY.md + if grep -q "security\|SECURITY" README.md; then + echo "โœ… README references security documentation" + else + echo "โš ๏ธ README should reference SECURITY.md" + fi + + # Check for hardcoded credentials (basic check) + if grep -rE "password\s*=|token\s*=|secret\s*=|key\s*=" README.md | grep -v "^[[:space:]]*#" | grep -v "xxxx" | grep -v "example"; then + echo "๐Ÿšจ README may contain hardcoded credentials" + exit 1 + fi + echo "โœ… README validation passed" + + security-summary: + name: ๐Ÿ“Š Security Summary + runs-on: ubuntu-latest + needs: [secret-scan, shellcheck, shfmt, lint, readme-check] + if: always() + steps: + - name: Generate security report + run: | + echo "## ๐Ÿ”’ Security Check Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY + echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY + echo "| Secret Detection | ${{ needs.secret-scan.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| Shell Analysis | ${{ needs.shellcheck.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| Code Formatting | ${{ needs.shfmt.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| Linting | ${{ needs.lint.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| README Check | ${{ needs.readme-check.result }} |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "See [Security Policy](SECURITY.md) for details." >> $GITHUB_STEP_SUMMARY + + - name: Fail if security checks failed + if: | + needs.secret-scan.result == 'failure' || + needs.shellcheck.result == 'failure' || + needs.shfmt.result == 'failure' || + needs.lint.result == 'failure' || + needs.readme-check.result == 'failure' + run: | + echo "๐Ÿšจ Security checks failed" + exit 1 diff --git a/.gitignore b/.gitignore index d19a789..5641df3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ services/tmp.sh -service/temp.sh \ No newline at end of file +service/temp.sh +# Testing scan secret files +test-private-key-demo.txt diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 0000000..b70e674 --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1,9 @@ +# Gitleaks ignore file for false positives +# These are secret detection patterns, not actual secrets + +# Allow secret detection patterns in docker.sh +services/docker.sh:98:BEGIN.*PRIVATE.*KEY +services/docker.sh:*:RUN git secrets --add --global + +# Allow patterns used for git-secrets configuration +**/*.sh:*:git secrets --add diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..58c4d95 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,55 @@ +# Pre-commit configuration +# Install: brew install pre-commit && pre-commit install + +repos: + # Shell script linting + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.9.0.5 + hooks: + - id: shellcheck + name: ๐Ÿš Lint shell scripts + args: ['--severity=warning'] + stages: [commit] + + # Shell script formatting + - repo: https://github.com/scop/pre-commit-shfmt + rev: v3.7.0-1 + hooks: + - id: shfmt + name: ๐ŸŽจ Format shell scripts + args: ['-i', '2', '-bn', '-ci', '-sr'] + stages: [commit] + + # Trailing whitespace and file fixes + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + name: ๐Ÿ“ Trim trailing whitespace + stages: [commit] + - id: end-of-file-fixer + name: ๐Ÿ“ Fix end of file + stages: [commit] + - id: check-yaml + name: โœ… Validate YAML + stages: [commit] + - id: check-added-large-files + name: ๐Ÿ“ฆ Check for large files + args: ['--maxkb=1000'] + stages: [commit] + - id: detect-private-key + name: ๐Ÿ”‘ Detect private keys + stages: [commit] + + # Secret detection using gitleaks + - repo: https://github.com/gitleaks/gitleaks + rev: v8.18.2 + hooks: + - id: gitleaks + name: ๐Ÿ” Detect secrets with gitleaks + entry: gitleaks detect --source . --verbose + language: golang + stages: [commit] + +default_language_version: + python: python3 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1e6fec2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,22 @@ +{ + "shellformat.effectiveLanguages": [ + "shellscript", + "dockerfile", + "dotenv", + "hosts", + "jvmoptions", + "ignore", + "gitignore", + "properties", + "spring-boot-properties", + "azcli", + "bats" + ], + "shellformat.flag": "-i 4 -bn -ci -sr", + "[shellscript]": { + "editor.defaultFormatter": "foxundermoon.shell-format", + "editor.formatOnSave": true, + "editor.tabSize": 4, + "editor.insertSpaces": true + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..01331cc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,65 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.1.0] - 2025-12-15 + +### Added +- ๐ŸŽฏ Initial release with core functionality +- ๐Ÿ” Security scanning capabilities with git-secrets Docker integration +- ๐Ÿ“ฆ Docker utilities (MongoDB, MySQL clients, git-secrets image builder) +- ๐Ÿ”ง Git utilities (peco-based tools for interactive selection) +- ๐Ÿ—„๏ธ Terraform utilities +- โ˜ธ๏ธ Kubernetes utilities +- ๐ŸŽช Service utilities (CI/CD, console editors, cURL, Git, Jenkins) +- ๐Ÿ”’ Security policy and documentation (SECURITY.md) +- โœ… Automated CI/CD pipeline with secret detection, shellcheck, and formatting checks +- ๐Ÿ“‹ Pre-commit hooks for local development security + +### Security +- ๐Ÿ” Gitleaks integration for secret detection +- ๐Ÿš Shellcheck validation for all shell scripts +- ๐ŸŽจ Code formatting standardization with shfmt +- ๐Ÿ“ Pre-commit hooks for preventing credential leaks +- ๐Ÿ“– Comprehensive security policy in SECURITY.md + +### Documentation +- ๐Ÿ“š Complete README with setup instructions +- ๐Ÿ”’ SECURITY.md with vulnerability reporting guidelines +- ๐Ÿ“– Inline documentation in functions +- ๐Ÿ’ก Usage examples for all major functions + +### Quality +- โœ… Shell script linting and validation +- ๐ŸŽจ Consistent code formatting +- ๐Ÿ“‹ Pre-commit configuration for development +- ๐Ÿ”„ GitHub Actions CI/CD pipeline + +--- + +## Versioning Policy + +- **v0.x.y**: Pre-release versions with potential breaking changes +- **v1.0.0+**: Stable versions following semantic versioning +- All releases are tagged with Git tags and available via Homebrew + +## Security Updates + +For security-related changes and updates, please see [SECURITY.md](SECURITY.md). + +## Contributing + +Before contributing, please review: +1. [SECURITY.md](SECURITY.md) - Security policies +2. [README.md](README.md) - Project overview +3. Our CI/CD checks run automatically on pull requests + +## Support + +For issues or questions: +1. Check existing issues and discussions +2. Review [SECURITY.md](SECURITY.md) for security concerns +3. See GitHub Actions logs for CI/CD failures diff --git a/LICENSE b/LICENSE index f49a4e1..261eeb9 100644 --- a/LICENSE +++ b/LICENSE @@ -198,4 +198,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/README.md b/README.md index ec75689..f5b36b0 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,110 @@ # helpful-commandlines This is the repo to collect helpful commandlines that is used for MAC OS. +> **Security Notice**: This repository implements automated security scanning to prevent credential leaks and ensure code quality. See [SECURITY.md](SECURITY.md) for our security policy and CI/CD checks. + ## Setup dependencies Notes: This document is for macos environment. -### Install gitlab cli +### Install GitHub cli +``` +brew install gh +export GH_TOKEN=xxxx +``` + +### Install peco +To allow searching by console. +![image](./images/peco_history_menu.png) + ``` -brew install glab -export GITLAB_TOKEN=xxxxx +brew install peco +peco --version +peco version v0.5.10 (built with go1.19.2) +``` + +### Install jq +``` +brew install jq +jq --version +jq-1.6 ``` + +## Setup lhs-helpful-commandlines +### Setup from homebrew +**It is easy to setup and run and don't want to change or optimize it** +#### Install +``` +brew tap lamhaison/formulae +brew install lamhaison/formulae/lhs-helpful-commandlines +``` +## Load when start an Iterm terminal +Add these lines to ~/.bashrc or ~/.zshrc or ~/.bash_profile +``` +source "$(which lhs-helpful-commandlines.sh)" "/opt/homebrew/Cellar/lhs-helpful-commandlines/$(brew info lhs-helpful-commandlines | grep -E '==> .*: stable (.*)$' | sed -E 's|==> .*: stable (.*)$|\1|g')" "True" "True" +``` + +### Re-install the latest version(If there are new versions) +``` +brew uninstall lhs-helpful-commandlines +brew untap lamhaison/formulae +brew tap lamhaison/formulae +brew install lamhaison/formulae/lhs-helpful-commandlines +``` + +## Settings when open terminal (I am using Iterm2) +**It is easy for you to custom your scripting to fix with your style** + +``` +mkdir -p /opt/lamhaison-tools && cd /opt/lamhaison-tools +git clone https://github.com/lamhaison/helpful-commandlines.git +echo "source /opt/lamhaison-tools/helpful-commandlines/main.sh" >> ~/.bashrc +``` + +# How to use it? + +## How to search helpful commandline +``` +Ctrl + h: to and choose the commandline that you want to run(searching and enter to auto fill it to your terminal) +lhs_help_helpful cmd: only for searching, it will not automatically fill in to your terminal +``` + +## How to search your history commandlines +``` +Option + r: to select the history commandline that you wan to re-run(searching and enter to auto fill it to your terminal) +search history commandline: only for searching history, it will not automatically fill in to your termial +``` + +## How to enable git commit suggestions +``` +lhs_git_commit_suggestions: only for searching the list commit message pattern +``` + +## Security & Contributing + +### ๐Ÿ”’ Security Commitment +- โœ… No hardcoded credentials or secrets +- โœ… Automated secret detection on every commit +- โœ… Shell script validation and quality checks +- โœ… Code formatting standards enforcement + +**Report security issues**: See [SECURITY.md](SECURITY.md) - Do NOT open public issues for security vulnerabilities. + +### CI/CD Security Checks +All pull requests are automatically scanned for: +- ๐Ÿ” Secrets and credentials (gitleaks) +- ๐Ÿš Shell script quality (shellcheck) +- ๐ŸŽจ Code formatting (shfmt) +- โœ… Syntax validation + +View the [security workflow](.github/workflows/security.yml) and [changelog](CHANGELOG.md). + +## License + +This project is licensed under the Apache License 2.0 - see [LICENSE](LICENSE) file for details. + +Notes: This document is for macos environment. + ### Install GitHub cli ``` brew install gh diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..767a6de --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,116 @@ +# Security Policy + +## Security Best Practices + +This repository implements security best practices to protect against accidental exposure of sensitive information and maintain code quality standards. + +### Automated Security Measures + +#### 1. Secret Detection +- **Tool**: [gitleaks](https://github.com/gitleaks/gitleaks) +- **Frequency**: Pre-commit hooks + CI/CD pipeline +- **Coverage**: Scans entire git history and all files +- **Patterns Detected**: + - AWS credentials and keys + - GitHub, GitLab, and other platform tokens + - API keys and authentication tokens + - Private keys and certificates + - Database connection strings + - JWT tokens + - Custom pattern matching + +#### 2. Shell Script Quality +- **Tool**: [shellcheck](https://www.shellcheck.net/) +- **Frequency**: Pre-commit + CI/CD +- **Purpose**: Detects common shell scripting errors and security issues + +#### 3. Code Formatting +- **Tool**: [shfmt](https://github.com/mvdan/sh) +- **Frequency**: Pre-commit + CI/CD +- **Purpose**: Ensures consistent code style and prevents formatting-related issues + +### Reporting a Vulnerability + +If you discover a security vulnerability in this repository, please: + +1. **Do NOT open a public issue** +2. **Email security concerns privately** to the repository maintainers +3. **Include**: + - Description of the vulnerability + - Steps to reproduce + - Potential impact + - Any suggested fix (if available) + +The maintainers will: +- Acknowledge receipt within 48 hours +- Assess the severity and impact +- Work on a fix or mitigation +- Coordinate a responsible disclosure timeline + +### CI/CD Security Checks + +All pull requests and commits are automatically scanned by GitHub Actions: + +- โœ… **Secret Scan**: Prevents credentials from being committed +- โœ… **Shell Analysis**: Validates shell script quality and security +- โœ… **Code Format Check**: Ensures consistent formatting + +You can view the security checks in [.github/workflows/security.yml](.github/workflows/security.yml) + +### Pre-commit Setup (Local Development) + +To set up security checks locally: + +```bash +# Install pre-commit framework +brew install pre-commit + +# Install git hooks +pre-commit install + +# (Optional) Run against all files +pre-commit run --all-files +``` + +### False Positives + +If a security check flags a false positive (e.g., a test credential in documentation): + +1. Add the pattern to `.gitallowed` file in the repository root +2. Example patterns: + ``` + # Test/documentation patterns + EXAMPLE[_-]?API[_-]?KEY + test[_-]?key + ``` +3. Document why the pattern is a false positive + +### Third-Party Dependencies + +This repository primarily contains shell scripts with minimal external dependencies: +- Git +- Docker (for security scanning tools) +- GNU utilities (standard on most systems) + +### Compliance & Standards + +- โœ… Apache 2.0 License +- โœ… No hardcoded credentials +- โœ… Automated security scanning on every commit +- โœ… Shell script validation and formatting +- โœ… Security policy documentation + +### Security Changelog + +Breaking security changes or significant security updates will be documented in: +- GitHub Release notes +- CHANGELOG.md +- This SECURITY.md file + +For security-related updates, subscribe to [GitHub Release notifications](../../releases). + +## References + +- [OWASP Shell Script Security](https://owasp.org/www-community/attacks/Shell_Injection) +- [Git Security Best Practices](https://git-scm.com/docs/gitignore) +- [Credential Management](https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories) diff --git a/common/help_incident.sh b/common/help_incident.sh deleted file mode 100644 index 814cb80..0000000 --- a/common/help_incident.sh +++ /dev/null @@ -1,27 +0,0 @@ -function lhs_help_incident_report() { - echo " - Reference - https://sysadmincasts.com/episodes/20-how-to-write-an-incident-report-postmortem - Reference - https://blog.tolleiv.de/2015/01/post-mortem-documentations-or-how-to-build-knowledge-during-failures/ - Google API infrastructure outage incident report - https://developers.googleblog.com/2013/05/google-api-infrastructure-outage_3.html - Issue Summary - short summary (5 sentences) - list the duration along with start and end times (include timezone) - state the impact (most user requests resulted in 500 errors, at peak 100%) - close with root cause - Timeline - list the timezone - covers the outage duration - when outage began - when staff was notified - actions, events, โ€ฆ - when service was restored - Root Cause - give a detailed explanation of event - do not sugarcoat - Resolution and recovery - give detailed explanation of actions taken (includes times) - Corrective and Preventative Measures - itemized list of ways to prevent it from happening again - what can we do better next time? - " -} diff --git a/common/help_ips.sh b/common/help_ips.sh index 402d2c7..f77b9a0 100644 --- a/common/help_ips.sh +++ b/common/help_ips.sh @@ -8,7 +8,7 @@ # shellcheck disable=SC2148 function lhs_network_get_public_ip_instruction() { - echo " + echo " dig +short myip.opendns.com @resolver1.opendns.com " @@ -16,24 +16,24 @@ function lhs_network_get_public_ip_instruction() { function lhs_network_get_private_ip_ranges_instruction() { - # shellcheck disable=SC2155 - local lhs_docs=$( - cat <<-__EOF__ + # shellcheck disable=SC2155 + local lhs_docs=$( + cat <<- __EOF__ 10.0.0.0 - 10.255.255.255 (10/8 prefix) 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) __EOF__ - ) + ) - echo "$lhs_docs" + echo "$lhs_docs" } function lhs_network_get_public_ip() { - dig +short myip.opendns.com @resolver1.opendns.com + dig +short myip.opendns.com @resolver1.opendns.com } function lhs_network_tcp_traceroute() { - # https://www.redhat.com/sysadmin/traceroute-finding-meaning - sudo tcptraceroute 8.8.8.8 443 + # https://www.redhat.com/sysadmin/traceroute-finding-meaning + sudo tcptraceroute 8.8.8.8 443 } diff --git a/common/help_menu.sh b/common/help_menu.sh index 453e453..22a7e5d 100644 --- a/common/help_menu.sh +++ b/common/help_menu.sh @@ -1,33 +1,47 @@ #!/bin/bash function lhs_help_helpful() { - # Support both function function_name() { or function_name with prefix aws_bla_bla() { - local lhs_functions=$(lhs_peco_helpful_function_list) - local lhs_option=${1:-IgnoreCase} + # Support both function function_name() { or function_name with prefix aws_bla_bla() { + local lhs_functions + lhs_functions=$(lhs_peco_helpful_function_list) + local lhs_option=${1:-IgnoreCase} - BUFFER=$( - echo "${lhs_functions}" | peco --query "$LBUFFER" --initial-filter "${lhs_option}" - ) - CURSOR=$#BUFFER + # Use peco to filter and select from the list of helpful functions + # LBUFFER contains the current command line buffer content + # The selected function will be stored in BUFFER + BUFFER=$( + # shellcheck disable=SC2153 + echo "${lhs_functions}" | peco --query "$LBUFFER" --initial-filter "${lhs_option}" + ) + + # shellcheck disable=SC2034 + CURSOR=$#BUFFER } function lhs_help_all() { - # Support both function function_name() { or function_name with prefix aws_bla_bla() { - # shellcheck disable=SC2155 - local lhs_functions=$(lhs_peco_function_list) - local lhs_option=${1:-"${LHS_PECO_FILTER_TYPE}"} - BUFFER=$( - echo "${lhs_functions}" | peco --query "$LBUFFER" --initial-filter "${lhs_option}" - ) - CURSOR=$#BUFFER + # Support both function function_name() { or function_name with prefix aws_bla_bla() { + # shellcheck disable=SC2155 + local lhs_functions + local lhs_option + + lhs_functions=$(lhs_peco_function_list) + lhs_option=${1:-"${LHS_PECO_FILTER_TYPE}"} + + # shellcheck disable=SC2034 + BUFFER=$( + echo "${lhs_functions}" | peco --query "$LBUFFER" --initial-filter "${lhs_option}" + ) + + # shellcheck disable=SC2034 + CURSOR=$#BUFFER } function lhs_help_refresh() { - lhs_peco_disable_input_cached - lhs_peco_function_list >>/dev/null - lhs_peco_helpful_function_list >>/dev/null - lhs_peco_enable_input_cached + lhs_peco_disable_input_cached + lhs_peco_function_list >> /dev/null + lhs_peco_helpful_function_list >> /dev/null + lhs_peco_enable_input_cached } diff --git a/common/other.sh b/common/other.sh index f0ce969..5cba5ec 100644 --- a/common/other.sh +++ b/common/other.sh @@ -1,14 +1,14 @@ #!/bin/bash function lhs_help_install_macos_clipboard_instruction() { - cat <<-_EOF_ + cat <<- _EOF_ Install clipy Access Shift + command + v _EOF_ } function lhs_help_install_macos_peco_instruction() { - cat <<-_EOF_ + cat <<- _EOF_ # Install peco brew install peco _EOF_ @@ -17,7 +17,7 @@ function lhs_help_install_macos_peco_instruction() { function lhs_help_create_os_user_instruction() { - echo ' + echo ' visudo son.lam ALL=(ALL) ALL @@ -40,6 +40,6 @@ function lhs_help_create_os_user_instruction() { } function lhs_help_cache_disabled_all() { - lhs_peco_disable_input_cached - peco_aws_disable_input_cached + lhs_peco_disable_input_cached + peco_aws_disable_input_cached } diff --git a/common/peco/other.sh b/common/peco/other.sh index 70edcd1..c087986 100644 --- a/common/peco/other.sh +++ b/common/peco/other.sh @@ -2,8 +2,8 @@ # There ares some bugs, then I will overwrite it and use it in help_menu.sh of private-helpful-commandlines. # TODO Later (Fix latter, can't not get the function name - lhs_proj_rakkar_infra_aws_migrate_from_original_to_private_dns_record_for_dev) function lhs_peco_function_list() { - # Ignore private function - local lhs_function_list_cmd=" + # Ignore private function + local lhs_function_list_cmd=" find \"${LHS_HELPFUL_LOOKUP}\" \ -type d \( -name 'docs' -o -name 'snippets' -o -name '.git' \) -prune \ -o -type f -name '*.sh' -print \ @@ -11,13 +11,13 @@ function lhs_peco_function_list() { | grep -e '^function.*\(.+*\)' -e '^aws*\(.+*\)' -e '^peco*\(.+*\)' -e '^lhs*\(.+*\)' \ | tr -d '(){' | awk -F ' ' '{ print (\$1==\"function\") ? \$2 : \$1}' | sort " - # Cache in LHS_HELPFUL_LOOKUP_FUNCTIONS_CACHED_EXPIRED_TIME setting - lhs_peco_commandline_input "${lhs_function_list_cmd}" "${LHS_HELPFUL_LOOKUP_CACHED}" "${LHS_HELPFUL_LOOKUP_FUNCTIONS_CACHED_EXPIRED_TIME}" + # Cache in LHS_HELPFUL_LOOKUP_FUNCTIONS_CACHED_EXPIRED_TIME setting + lhs_peco_commandline_input "${lhs_function_list_cmd}" "${LHS_HELPFUL_LOOKUP_CACHED}" "${LHS_HELPFUL_LOOKUP_FUNCTIONS_CACHED_EXPIRED_TIME}" } function lhs_peco_helpful_function_list() { - local lhs_function_list_cmd=" + local lhs_function_list_cmd=" find \"${HELPFUL_COMMANDLINES_SOURCE_SCRIPTS}\" \ -type d \( -name 'docs' -o -name 'snippets' -o -name '.git' \) -prune \ -o -type f -name '*.sh' -print \ @@ -25,7 +25,7 @@ function lhs_peco_helpful_function_list() { | tr -d '(){' | awk -F ' ' '{ print (\$1==\"function\") ? \$2 : \$1}' | sort " - # Cache without expired time - lhs_peco_commandline_input "${lhs_function_list_cmd}" "${LHS_HELPFUL_LOOKUP_CACHED}" "0" + # Cache without expired time + lhs_peco_commandline_input "${lhs_function_list_cmd}" "${LHS_HELPFUL_LOOKUP_CACHED}" "0" } diff --git a/common/peco/peco.sh b/common/peco/peco.sh index 4b88ffd..46928ca 100644 --- a/common/peco/peco.sh +++ b/common/peco/peco.sh @@ -3,245 +3,227 @@ # PECO function lhs_peco_setting_set_filter_type_with_regex_option() { - lhs_peco_setting_set_filter_type_for_history_search "Regexp" - lhs_peco_setting_set_filter_type "Regexp" + lhs_peco_setting_set_filter_type_for_history_search "Regexp" + lhs_peco_setting_set_filter_type "Regexp" } function lhs_peco_setting_set_filter_type_for_history_search() { - filter_type=$1 + filter_type=$1 - # Check input invalid - if [[ -z "$filter_type" ]]; then return; fi - unset LHS_PECO_FILTER_HISTORY_TYPE - export LHS_PECO_FILTER_HISTORY_TYPE=${1:-'IgnoreCase'} - echo "Set the filter type for history commandline by peco is ${filter_type}" + # Check input invalid + if [[ -z "$filter_type" ]]; then return; fi + unset LHS_PECO_FILTER_HISTORY_TYPE + export LHS_PECO_FILTER_HISTORY_TYPE=${1:-'IgnoreCase'} + echo "Set the filter type for history commandline by peco is ${filter_type}" } function lhs_peco_setting_set_filter_type() { - filter_type=$1 - # Check input invalid - if [[ -z "$filter_type" ]]; then return; fi - unset LHS_PECO_FILTER_TYPE - export LHS_PECO_FILTER_TYPE=${1:-'IgnoreCase'} - echo "Set the filter type global for peco is ${filter_type}" + filter_type=$1 + # Check input invalid + if [[ -z "$filter_type" ]]; then return; fi + unset LHS_PECO_FILTER_TYPE + export LHS_PECO_FILTER_TYPE=${1:-'IgnoreCase'} + echo "Set the filter type global for peco is ${filter_type}" } function lhs_peco_setting_set_filter_type_for_history_search_with_hint() { - # shellcheck disable=SC2155 - local lhs_docs=$( - cat <<-__EOF__ + # shellcheck disable=SC2155 + local lhs_docs=$( + cat <<- __EOF__ IgnoreCase CaseSensitive SmartCase Regexp Fuzzy __EOF__ - ) + ) - # shellcheck disable=SC2155 - local filter_type=$(echo "$lhs_docs" | peco) + # shellcheck disable=SC2155 + local filter_type=$(echo "$lhs_docs" | peco) - # Check input is valid and process it - [ -z "$filter_type" ] || lhs_peco_setting_set_filter_type_for_history_search "${filter_type}" + # Check input is valid and process it + [ -z "$filter_type" ] || lhs_peco_setting_set_filter_type_for_history_search "${filter_type}" } function lhs_peco_setting_set_filter_type_with_hint() { - # shellcheck disable=SC2155 - local lhs_docs=$( - cat <<-__EOF__ + # shellcheck disable=SC2155 + local lhs_docs=$( + cat <<- __EOF__ IgnoreCase CaseSensitive SmartCase Regexp Fuzzy __EOF__ - ) + ) - # shellcheck disable=SC2155 - local filter_type=$(echo "$lhs_docs" | peco) + # shellcheck disable=SC2155 + local filter_type=$(echo "$lhs_docs" | peco) - # Check input is valid and process it - [ -z "$filter_type" ] || lhs_peco_setting_set_filter_type "${filter_type}" + # Check input is valid and process it + [ -z "$filter_type" ] || lhs_peco_setting_set_filter_type "${filter_type}" } function lhs_peco_select_history() { - local tac - if which tac >/dev/null; then - tac="tac" - else - # Displays the output from the end of the file in reverse order. - tac="tail -r" - fi - BUFFER=$(history -n 1 | uniq | - eval $tac | - peco --query "$LBUFFER" --initial-filter ${LHS_PECO_FILTER_HISTORY_TYPE}) - # peco --query "$LBUFFER") - # Move the cursor at then end of the input($#variable_name is to get the length itself) - CURSOR=$#BUFFER - # zle clear-screen -} - -function lhs_peco_history() { - peco_select_history + local tac + if which tac > /dev/null; then + tac="tac" + else + # Displays the output from the end of the file in reverse order. + tac="tail -r" + fi + # shellcheck disable=SC2034 + + # shellcheck disable=SC2153 + BUFFER=$(history -n 1 | uniq \ + | eval $tac \ + | peco --query "$LBUFFER" --initial-filter ${LHS_PECO_FILTER_HISTORY_TYPE}) + # peco --query "$LBUFFER") + # Move the cursor at then end of the input($#variable_name is to get the length itself) + # shellcheck disable=SC2034 + CURSOR=$#BUFFER + # zle clear-screen } function lhs_peco_repo_list() { - # Almost expired (1000000) - project_list=$( - lhs_peco_commandline_input "\ + # Almost expired (1000000) + project_list=$( + lhs_peco_commandline_input "\ find ${LHS_PROJECTS_DIR} -type d -name '.git' -maxdepth 8 \ | awk -F '/' '{for (i=1; i"${input_file_path}" - echo "${format_text}" | tee -a "${input_file_path}" - else - echo "Can not get the data" - fi - - fi - - # set +x + # set -x + local commandline="${1}" + local result_cached=${2:-'false'} + local input_expired_time="${3:-$lhs_cli_peco_input_expired_time}" + local input_file_path + local md5_hash + local input_folder + local empty_file + local valid_file + local commandline_result + local format_text + + md5_hash=$(echo "$commandline" | md5) + input_folder="${lhs_cli_input:-/tmp/inputs}" + + # Check folder exists + if [[ ! -d "${input_folder}" ]]; then + mkdir -p "${input_folder}" + fi + + input_file_path="${input_folder}/${md5_hash}.txt" + empty_file=$(find "${input_folder}" -name "${md5_hash}.txt" -empty) + + # Disable cache as global setting + if [[ "$lhs_cli_peco_input_expired_time" = "-1" ]]; then + result_cached=false + elif [[ "$input_expired_time" -eq 0 ]]; then + # If input_expired_time is 0, cache without expiration (TTL is unlimited) + valid_file=$(find "${input_folder}" -name "${md5_hash}.txt") + elif [[ "$input_expired_time" -gt 0 ]]; then + # If input_expired_time is greater than 0, find the file that is not expired + # Check the file is created within the input_expired_time + valid_file=$(find "${input_folder}" -name "${md5_hash}.txt" -mmin -"${input_expired_time}") + else + # Default behavior for negative values other than -1 + result_cached=false + fi + + # The file is existed and not empty and the flag result_cached is not empty + if [[ "true" == "${result_cached}" ]] && [[ -f "${input_file_path}" ]] && [[ -z "${empty_file}" ]] && [[ -n "${valid_file}" ]]; then + # echo "load from cache" + # Ignore the first line. + grep -Ev "\*\*\*\*\*\*\*\* \[.*\]" "$input_file_path" + else + # echo "Query and save to cache" + commandline_result=$(lhs_peco_run_command_to_get_input "$commandline") + + format_text=$(lhs_peco_format_output_text "$commandline_result") + + if [[ -n "${format_text}" ]]; then + commandline=$(local_lhs_util_format_commandline_one_line "${commandline}") + echo "******** [ ${commandline} ] ********" > "${input_file_path}" + echo "${format_text}" | tee -a "${input_file_path}" + else + echo "Can not get the data" + fi + + fi + + # set +x } function lhs_peco_create_menu() { - local input_function=$1 - local peco_options=$2 - local peco_command="peco ${peco_options}" - local input_value - - # Check input_function is valid - if [[ -z "$input_function" ]]; then - echo "Input function is empty" - return 1 - fi - - input_value=$(eval "${input_function}" | eval "${peco_command}") - echo "${input_value:?'Can not get the input from peco menu'}" + local input_function=$1 + local peco_options=$2 + local peco_command="peco ${peco_options}" + local input_value + + # Check input_function is valid + if [[ -z "$input_function" ]]; then + echo "Input function is empty" + return 1 + fi + + input_value=$(eval "${input_function}" | eval "${peco_command}") + echo "${input_value:?'Can not get the input from peco menu'}" } diff --git a/common/peco/peco_git.sh b/common/peco/peco_git.sh index d016d6f..2c95d41 100644 --- a/common/peco/peco_git.sh +++ b/common/peco/peco_git.sh @@ -1,5 +1,5 @@ #!/bin/bash function lhs_peco_git_diff_name_only() { - lhs_peco_commandline_input 'git diff --name-only' + lhs_peco_commandline_input 'git diff --name-only' } diff --git a/common/peco/peco_helm.sh b/common/peco/peco_helm.sh index fcaaaeb..64e1936 100644 --- a/common/peco/peco_helm.sh +++ b/common/peco/peco_helm.sh @@ -1,23 +1,20 @@ #!/bin/bash function peco_k8s_helm_list() { - peco_k8s_input "lhs_helm_list_releases_all | grep -v "NAMESPACE" \ + peco_k8s_input "lhs_helm_list_releases_all | grep -v 'NAMESPACE' \ | awk -F '\t' 'BEGIN { OFS=\" | \" } { print \$1,\$2,\$3}' | grep -v 'NAME'" } function peco_k8s_helm_list_revisions() { - local release_name=$1 - local namespace=$2 + local release_name=$1 + local namespace=$2 - # Check invalid input - if [[ -z "${release_name}" || -z "${namespace}" ]]; then - echo "Invalid input: release_name or namespace is empty" - return 1 - fi + # Check invalid input + if [[ -z "${release_name}" || -z "${namespace}" ]]; then + echo "Invalid input: release_name or namespace is empty" + return 1 + fi - - peco_k8s_input "helm history '$release_name' -n '${namespace}' | grep -v 'REVISION' \ + peco_k8s_input "helm history '$release_name' -n '${namespace}' | grep -v 'REVISION' \ | awk -F '\t' 'BEGIN { OFS=\" | \" } { print \$1,\$2,\$3,\$4,\$5,\$6}' | grep -v 'NAME'" } - - diff --git a/common/peco/peco_k8s.sh b/common/peco/peco_k8s.sh index a71ba6e..cd12282 100644 --- a/common/peco/peco_k8s.sh +++ b/common/peco/peco_k8s.sh @@ -1,45 +1,45 @@ #!/bin/bash function peco_k8s_input() { - lhs_peco_commandline_input "${1}" 'true' + lhs_peco_commandline_input "${1}" 'true' } function peco_k8s_namespace_list() { - peco_k8s_input "kubectl get namespaces | awk -F ' ' '{print \$1}' | grep -v 'NAME'" + peco_k8s_input "kubectl get namespaces | awk -F ' ' '{print \$1}' | grep -v 'NAME'" } function peco_k8s_deployment_list() { - peco_k8s_input "kubectl get deployments --all-namespaces \ + peco_k8s_input "kubectl get deployments --all-namespaces \ | awk -F ' ' 'BEGIN { OFS=\" | \" } { print \$2,\$1}' | grep -v 'NAME'" } function peco_k8s_pod_list() { - peco_k8s_input "kubectl get pods --all-namespaces \ + peco_k8s_input "kubectl get pods --all-namespaces \ | awk -F ' ' 'BEGIN { OFS=\" | \" } { print \$2,\$1}' | grep -v 'NAME'" } function peco_k8s_pod_list_reloaded() { - lhs_peco_commandline_input "kubectl get pods --all-namespaces \ + lhs_peco_commandline_input "kubectl get pods --all-namespaces \ | awk -F ' ' 'BEGIN { OFS=\" | \" } { print \$2,\$1}' | grep -v 'NAME'" 'false' } function peco_k8s_ingress_list() { - peco_k8s_input "kubectl get ingress --all-namespaces \ + peco_k8s_input "kubectl get ingress --all-namespaces \ | awk -F ' ' 'BEGIN { OFS=\" | \" } { print \$2,\$1}' | grep -v 'NAME'" } function peco_k8s_daemonset_list() { - peco_k8s_input "kubectl get daemonset --all-namespaces \ + peco_k8s_input "kubectl get daemonset --all-namespaces \ | awk -F ' ' 'BEGIN { OFS=\" | \" } { print \$2,\$1}' | grep -v 'NAME'" } function peco_k8s_hpa_list() { - peco_k8s_input "kubectl get hpa --all-namespaces \ + peco_k8s_input "kubectl get hpa --all-namespaces \ | awk -F ' ' 'BEGIN { OFS=\" | \" } { print \$2,\$1}' | grep -v 'NAME'" } function peco_k8s_cronjob_list() { - peco_k8s_input "kubectl get cronjob --all-namespaces \ + peco_k8s_input "kubectl get cronjob --all-namespaces \ | awk -F ' ' 'BEGIN { OFS=\" | \" } { print \$2,\$1}' | grep -v 'NAME'" -} \ No newline at end of file +} diff --git a/common/utils.sh b/common/utils.sh index 999edc7..37dc2ab 100644 --- a/common/utils.sh +++ b/common/utils.sh @@ -3,27 +3,27 @@ # Get DateTime function lhs_cmd_date_get_month() { - date +%m + date +%m } function lhs_cmd_date_get_year() { - date +%Y + date +%Y } function lhs_cmd_date_get_with_format() { - echo $(date "+"${1:-"%Y-%m-%d-%H-%M-%S"}) + date "+${1:-"%Y-%m-%d-%H-%M-%S"}" } function lhs_cmd_date_get_with_format_yyyymmdd() { - lhs_cmd_date_get_with_format "%Y%m%d" + lhs_cmd_date_get_with_format "%Y%m%d" } function lhs_cmd_date_get_with_format_cw_log() { - lhs_cmd_date_get_with_format "%Y-%m-%d %H:%M:%S" + lhs_cmd_date_get_with_format "%Y-%m-%d %H:%M:%S" } function lhs_cmd_date_get_epoch_time() { - # unix-time-in-milliseconds - date -d '0 hour ago' +%s%N | cut -b1-13 + # unix-time-in-milliseconds + date -d '0 hour ago' +%s%N | cut -b1-13 } # TODO function lhs_cmd_time_convert_echo_to_human_readable_formaton_name to convert epoch time to human readable formnat. @@ -32,126 +32,125 @@ function lhs_cmd_date_get_epoch_time() { # function lhs_cmd_time_convert_echo_to_human_readable_format() { - # TODO Later (it didn't work rightnow) - local default_date_format=+${2:-'%Y-%m-%d-%H-%M-%S'} - date -r ${1:?'epoch_value is unset or empty'} ${default_date_format} + # TODO Later (it didn't work rightnow) + local default_date_format=+${2:-'%Y-%m-%d-%H-%M-%S'} + date -r ${1:?'epoch_value is unset or empty'} ${default_date_format} } -# Password generate -function lhs_cmd_password_generate() { - # openssl rand -base64 10 | tr -d '=' - - cd /tmp >/dev/null - mktemp XXXXXXXXXXXXX - cd - >/dev/null -} - -# Get DateTime -function lhs_cmd_file_name_get_random_name() { - local file_name=${1:-'FILENAME'} - cd /tmp >/dev/null - mktemp ${file_name}-XXXXXXXXXXXXXX - cd - >/dev/null -} - -# Trap to handle Ctrl+C -# Do later -# function lhs_demo_script_trap_handle_hotkey_ctrl_c() { - -# set -x -# TMPFILE1=$(mktemp /tmp/im1.XXXXXX) -# TMPFILE2=$(mktemp /tmp/im2.XXXXXX) - -# while [[ true ]]; do -# echo "Press Ctrl + C to exit" -# sleep 10 -# done - -# trap "rm -f $TMPFILE1 $TMPFILE2; exit 1" INT --snip-- - -# set +x -# } - function local_local_lhs_run_commandline_with_retry() { - local lhs_commandline=$1 - local silent_mode=$2 - local retry_counter=0 + local lhs_commandline=$1 + local silent_mode=$2 + local retry_counter=0 - # Check credential valid first - # lhs_assume_role_is_tmp_credential_valid + # Check credential valid first + # lhs_assume_role_is_tmp_credential_valid - while [[ "${retry_counter}" -le "${lhs_cli_retry_time}" ]]; do + # Skip SC2154 + # shellcheck disable=SC2154 + while [[ "${retry_counter}" -le "${lhs_cli_retry_time}" ]]; do - if [[ "${silent_mode}" = "true" ]]; then - eval $lhs_commandline 2>/dev/null - else - eval $lhs_commandline - fi + if [[ "${silent_mode}" = "true" ]]; then + eval $lhs_commandline 2> /dev/null + else + eval $lhs_commandline + fi - if [[ $? -ne 0 ]]; then - retry_counter=$(($retry_counter + 1)) + if [[ $? -ne 0 ]]; then + retry_counter=$(($retry_counter + 1)) - # if [[ "${silent_mode}" = "false" ]]; then - # echo "Retry ${retry_counter}" - # fi + # if [[ "${silent_mode}" = "false" ]]; then + # echo "Retry ${retry_counter}" + # fi - sleep ${lhs_cli_retry_sleep_interval} - else - break - fi - done + sleep ${lhs_cli_retry_sleep_interval} + else + break + fi + done } function local_lhs_run_commandline() { - local_lhs_run_commandline=$1 - local_lhs_run_commandline="${local_lhs_run_commandline:?'local_lhs_run_commandline is unset or empty'}" - local_local_lhs_run_commandline_with_logging "${local_lhs_run_commandline}" + local_lhs_run_commandline=$1 + local_lhs_run_commandline="${local_lhs_run_commandline:?'local_lhs_run_commandline is unset or empty'}" + local_local_lhs_run_commandline_with_logging "${local_lhs_run_commandline}" } function local_lhs_commandline_logging() { - local log_file_path=${aws_cli_logs}/${ASSUME_ROLE}.log - local tee_command="tee -a ${log_file_path}" + local log_file_path + local tee_command + local eval_commandline + local lhs_commandline + local local_lhs_commandline_logging + + lhs_commandline=$1 + eval_commandline=${2:-'False'} + + # shellcheck disable=SC2154 + # Check if ASSUME_ROLE is set, if it is not set, use hostname as log file name + if [[ -z "${ASSUME_ROLE}" ]]; then + log_file_path=${aws_cli_logs}/$(hostname).log + else + log_file_path=${aws_cli_logs}/${ASSUME_ROLE}.log + fi + + tee_command="tee -a ${log_file_path}" - local eval_commandline=${2:-'False'} + # Validate lhs_commandline - local local_lhs_commandline_logging=$(echo ${1:?'lhs_commandline is unset or empty'} | tr -d '\t' | tr -d '\n') + if [[ -z "${lhs_commandline}" ]]; then + echo "โŒ lhs_commandline is empty" + return 1 + fi - if [[ "${eval_commandline}" == "True" ]]; then - echo "${local_lhs_commandline_logging}" - else - echo "Running commandline [ ${local_lhs_commandline_logging} ]" | eval $tee_command - fi + local_lhs_commandline_logging=$(echo "${lhs_commandline}" | tr -d '\t' | tr -d '\n') + + if [[ "${eval_commandline}" == "True" ]]; then + echo "${local_lhs_commandline_logging}" + else + echo "Running commandline [ ${local_lhs_commandline_logging} ]" | eval $tee_command + fi } function local_local_lhs_run_commandline_with_logging() { - lhs_commandline=$1 - if [[ "$lhs_show_log_uploaded" = "true" ]]; then - local tee_command="tee -a ${lhs_cli_log_file_path} ${lhs_cli_log_uploaded_file_path}" - else - local tee_command="tee -a ${lhs_cli_log_file_path}" - fi - - if [[ "$lhs_cli_show_commandline" = "true" ]]; then - local detail_commandline_tee_command="${tee_command}" - else - local detail_commandline_tee_command="${tee_command} > /dev/null" - fi - - echo "------------------------------STARTED--$(date '+%Y-%m-%d-%H-%M-%S')-----------------------------------------" | eval $tee_command >/dev/null - local_lhs_commandline_logging $1 | eval $detail_commandline_tee_command - lhs_commandline_result=$(local_local_lhs_run_commandline_with_retry "${lhs_commandline}" "${ignored_error_when_retry}") - echo $lhs_commandline_result | eval $tee_command - echo "------------------------------FINISHED-$(date '+%Y-%m-%d-%H-%M-%S')-----------------------------------------" | eval $tee_command >/dev/null + lhs_commandline=$1 + + # shellcheck disable=SC2154 + if [[ "$lhs_show_log_uploaded" = "true" ]]; then + local tee_command="tee -a ${lhs_cli_log_file_path} ${lhs_cli_log_uploaded_file_path}" + else + local tee_command="tee -a ${lhs_cli_log_file_path}" + fi + + # shellcheck disable=SC2154 + if [[ "$lhs_cli_show_commandline" = "true" ]]; then + local detail_commandline_tee_command="${tee_command}" + else + local detail_commandline_tee_command="${tee_command} > /dev/null" + fi + + echo "------------------------------STARTED--$(date '+%Y-%m-%d-%H-%M-%S')-----------------------------------------" | eval $tee_command > /dev/null + local_lhs_commandline_logging $1 | eval $detail_commandline_tee_command + # shellcheck disable=SC2154 + # ignored_error_when_retry is defined in main.sh + lhs_commandline_result=$(local_local_lhs_run_commandline_with_retry "${lhs_commandline}" "${ignored_error_when_retry}") + echo $lhs_commandline_result | eval $tee_command + echo "------------------------------FINISHED-$(date '+%Y-%m-%d-%H-%M-%S')-----------------------------------------" | eval $tee_command > /dev/null } function local_lhs_util_rm_space() { - # Remove spaces from the input string - echo "${1}" | tr -d '\t' | tr -d ' ' + # Remove spaces from the input string + echo "${1}" | tr -d '\t' | tr -d ' ' } function local_lhs_util_format_commandline_one_line() { - echo ${1} | tr -d '\t' | tr -d '\n' | tr -s ' ' + echo ${1} | tr -d '\t' | tr -d '\n' | tr -s ' ' +} + +# Replace by using lhs-cli later +function lhs_cmd_file_name_get_random_name() { + local file_name=${1:-'FILENAME'} + echo "${file_name}-$(lhs_cmd_date_get_with_format)" } diff --git a/main.sh b/main.sh index 1a361b8..747e1ac 100644 --- a/main.sh +++ b/main.sh @@ -10,15 +10,15 @@ HELPFUL_COMMANDLINES_SOURCE_SCRIPTS=$1 if [[ -z "${HELPFUL_COMMANDLINES_SOURCE_SCRIPTS}" ]]; then - # Get the current directory of the main.sh script. - LOCAL_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS=$(dirname -- "$0") - if [[ "${LOCAL_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS}" = "." ]]; then - DEFAULT_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS='/opt/lamhaison-tools/helpful-commandlines' - fi + # Get the current directory of the main.sh script. + LOCAL_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS=$(dirname -- "$0") + if [[ "${LOCAL_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS}" = "." ]]; then + DEFAULT_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS='/opt/lamhaison-tools/helpful-commandlines' + fi - export HELPFUL_COMMANDLINES_SOURCE_SCRIPTS="${LOCAL_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS:-${DEFAULT_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS}}" + export HELPFUL_COMMANDLINES_SOURCE_SCRIPTS="${LOCAL_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS:-${DEFAULT_HELPFUL_COMMANDLINES_SOURCE_SCRIPTS}}" else - export HELPFUL_COMMANDLINES_SOURCE_SCRIPTS=${HELPFUL_COMMANDLINES_SOURCE_SCRIPTS} + export HELPFUL_COMMANDLINES_SOURCE_SCRIPTS=${HELPFUL_COMMANDLINES_SOURCE_SCRIPTS} fi export LHS_PROJECTS_DIR=~/projects @@ -32,14 +32,18 @@ export LHS_HELPFUL_LOOKUP_FUNCTIONS_CACHED_EXPIRED_TIME=$((60 * 8)) # https://yukimemi.netlify.app/all-you-need-is-peco/ # https://thevaluable.dev/zsh-line-editor-configuration-mouseless/ for script in $( - find "${HELPFUL_COMMANDLINES_SOURCE_SCRIPTS}" -type f -name '*.sh' | - grep -v -E '.*(main.sh|test.sh|temp.sh|helpful-commandlines.sh)$' + find "${HELPFUL_COMMANDLINES_SOURCE_SCRIPTS}" -type f -name '*.sh' \ + | grep -v -E '.*(main.sh|test.sh|temp.sh|helpful-commandlines.sh)$' ); do - # shellcheck disable=SC1090 - source "${script}" + # shellcheck disable=SC1090 + source "${script}" done +# -1: Disable caching +# 0: cache without expiration +# >0: cache with expiration time (in minutes) + export lhs_cli_peco_input_expired_time=10 export lhs_cli_show_commandline=true export lhs_cli_input=/tmp/lhs/inputs @@ -47,6 +51,10 @@ export lhs_cli_logs=/tmp/lhs/logs export lhs_cli_log_file_path="${lhs_cli_logs}/lhs-cli.log" export lhs_cli_log_uploaded_file_path="${lhs_cli_logs}/lhs-cli-uploaded.log" +# Retry settings + +export ignored_error_when_retry="false" + # For peco settings # --initial-filter IgnoreCase|CaseSensitive|SmartCase|Regexp|Fuzzy # Only for history @@ -56,31 +64,31 @@ export LHS_PECO_FILTER_TYPE=${5:-'IgnoreCase'} folder_list=("${lhs_cli_input}" "${lhs_cli_logs}") for folder in "${folder_list[@]}"; do - if [[ ! -d "$folder" ]]; then - mkdir -p "${folder}" - fi + if [[ ! -d "$folder" ]]; then + mkdir -p "${folder}" + fi done # Setup binding keys LHS_BIND_KEY=${2:-'True'} if [[ ${LHS_BIND_KEY} == "True" && "$(which zle)" != "" ]]; then - # Add hot-keys - zle -N lhs_peco_select_history + # Add hot-keys + zle -N lhs_peco_select_history - # Using zsh-history-substring-search reserved - # bindkey '^r' lhs_peco_select_history + # Using zsh-history-substring-search reserved + # bindkey '^r' lhs_peco_select_history - # Option + r - bindkey 'ยฎ' lhs_peco_select_history + # Option + r + bindkey 'ยฎ' lhs_peco_select_history - zle -N lhs_help_all - bindkey '^h' lhs_help_all + zle -N lhs_help_all + bindkey '^h' lhs_help_all - # Hot key for git commit suggestions - zle -N lhs_git_commit_suggestions_with_hint - # Hotkey: Option + gc - bindkey 'ยฉรง' lhs_git_commit_suggestions_with_hint + # Hot key for git commit suggestions + zle -N lhs_git_commit_suggestions_with_hint + # Hotkey: Option + gc + bindkey 'ยฉรง' lhs_git_commit_suggestions_with_hint fi # Setup for history commandlines feature @@ -91,27 +99,27 @@ fi LHS_CHANGE_HISTORY_SETTINGS=${3:-'True'} if [[ "${LHS_CHANGE_HISTORY_SETTINGS}" = "True" && "$(which setopt)" != "" ]]; then - export HISTFILE="$HOME/.zsh_history" - export HISTSIZE=1048576 - export SAVEHIST=1048576 - - # ignoredups - Do not record duplicate commands consecutively. - # ignoredups - Ignore commands prefixed with a space. - # ignoreboth - ignoredups and ignoredups - ignorespace:ignoredups - export HISTCONTROL=ignoreboth - - setopt BANG_HIST # Treat the '!' character specially during expansion. - setopt EXTENDED_HISTORY # Write the history file in the ":start:elapsed;command" format. - setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits. - setopt SHARE_HISTORY # Share history between all sessions. - setopt HIST_EXPIRE_DUPS_FIRST # Expire duplicate entries first when trimming history. - - setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again. - setopt HIST_IGNORE_ALL_DUPS # Delete old recorded entry if new entry is a duplicate. - setopt HIST_FIND_NO_DUPS # Do not display a line previously found. - setopt HIST_IGNORE_SPACE # Don't record an entry starting with a space. - setopt HIST_SAVE_NO_DUPS # Don't write duplicate entries in the history file. - setopt HIST_REDUCE_BLANKS # Remove superfluous blanks before recording entry. - setopt HIST_VERIFY # Don't execute immediately upon history expansion. - setopt HIST_BEEP # Beep when accessing nonexistent history. + export HISTFILE="$HOME/.zsh_history" + export HISTSIZE=1048576 + export SAVEHIST=1048576 + + # ignoredups: Do not record duplicate commands consecutively + # ignorespace: Ignore commands prefixed with a space + # ignoreboth: Combines both ignoredups and ignorespace + export HISTCONTROL=ignoreboth + + setopt BANG_HIST # Treat the '!' character specially during expansion. + setopt EXTENDED_HISTORY # Write the history file in the ":start:elapsed;command" format. + setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits. + setopt SHARE_HISTORY # Share history between all sessions. + setopt HIST_EXPIRE_DUPS_FIRST # Expire duplicate entries first when trimming history. + + setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again. + setopt HIST_IGNORE_ALL_DUPS # Delete old recorded entry if new entry is a duplicate. + setopt HIST_FIND_NO_DUPS # Do not display a line previously found. + setopt HIST_IGNORE_SPACE # Don't record an entry starting with a space. + setopt HIST_SAVE_NO_DUPS # Don't write duplicate entries in the history file. + setopt HIST_REDUCE_BLANKS # Remove superfluous blanks before recording entry. + setopt HIST_VERIFY # Don't execute immediately upon history expansion. + setopt HIST_BEEP # Beep when accessing nonexistent history. fi diff --git a/services/ci_cd.sh b/services/ci_cd.sh index 7077cdb..cca7ad2 100644 --- a/services/ci_cd.sh +++ b/services/ci_cd.sh @@ -1,30 +1,30 @@ #!/bin/bash function lhs_ci_laravel_replace_aws_credentials_in_env_file() { - local APP_ENV=$1 - local OLD_AWS_ACCESS_KEY_ID=$2 - local NEW_AWS_ACCESS_KEY_ID=$3 - local OLD_AWS_SECRET_ACCESS_KEY=$4 - local NEW_AWS_SECRET_ACCESS_KEY=$5 - cat .env.${APP_ENV} | - sed "s|${OLD_AWS_ACCESS_KEY_ID}|${NEW_AWS_ACCESS_KEY_ID}|g" | - sed "s|${OLD_AWS_SECRET_ACCESS_KEY}|${NEW_AWS_SECRET_ACCESS_KEY}|g" \ - >.env.${APP_ENV}_tmp + local APP_ENV=$1 + local OLD_AWS_ACCESS_KEY_ID=$2 + local NEW_AWS_ACCESS_KEY_ID=$3 + local OLD_AWS_SECRET_ACCESS_KEY=$4 + local NEW_AWS_SECRET_ACCESS_KEY=$5 + cat .env.${APP_ENV} \ + | sed "s|${OLD_AWS_ACCESS_KEY_ID}|${NEW_AWS_ACCESS_KEY_ID}|g" \ + | sed "s|${OLD_AWS_SECRET_ACCESS_KEY}|${NEW_AWS_SECRET_ACCESS_KEY}|g" \ + > .env.${APP_ENV}_tmp } function lhs_ci_laravel_overwrite_aws_credentials_in_env_file() { - local APP_ENV=$1 - rm -rf .env.${APP_ENV} - mv .env.${APP_ENV}_tmp .env.${APP_ENV} + local APP_ENV=$1 + rm -rf .env.${APP_ENV} + mv .env.${APP_ENV}_tmp .env.${APP_ENV} } function lhs_ci_laravel_rm_aws_credentials_in_env_file() { - local APP_ENV=$1 - rm -rf .env.${APP_ENV} + local APP_ENV=$1 + rm -rf .env.${APP_ENV} } function lhs_ci_laravel_delete_aws_credentials_in_env_file() { - local APP_ENV=$1 - rm -rf .env.${APP_ENV} + local APP_ENV=$1 + rm -rf .env.${APP_ENV} } diff --git a/services/console_editor.sh b/services/console_editor.sh deleted file mode 100644 index b1f3023..0000000 --- a/services/console_editor.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# @version 1.0 -# @script cmd_editor.sh -# @description TODO : the tool that is using peco and tree to open project and edit it. -# -## - -function lhs_editor_with_tree() { - local tree_cmd="tree -afr ${1:-}" - local editor_cmd="${2:-vim}" - local file_name=$(eval ${tree_cmd} | peco --on-cancel error | awk -F "โ”€โ”€" '{ print $2 }' | awk -F " " '{print $1}') - - if [[ -n "${file_name}" ]]; then - ${editor_cmd} -c 'set number' -c 'syn on' ${file_name} - fi - -} diff --git a/services/curl.sh b/services/curl.sh index 758a39c..76ee378 100644 --- a/services/curl.sh +++ b/services/curl.sh @@ -2,13 +2,13 @@ function lhs_cmd_curl_get_response_headers_only() { - lhs_curl_url=${1:-'https://devopsmountain.com'} - echo "\ + lhs_curl_url=${1:-'https://devopsmountain.com'} + echo "\ http_endpoint: ${lhs_curl_url} -s hides the progress bar -D - dump headers to stdout indicated by - -o /dev/null send output (HTML) to /dev/null essentially ignoring it " - curl -s -D - -o /dev/null ${lhs_curl_url} + curl -s -D - -o /dev/null ${lhs_curl_url} } diff --git a/services/docker.sh b/services/docker.sh index 30771d0..c1b46c5 100644 --- a/services/docker.sh +++ b/services/docker.sh @@ -6,131 +6,183 @@ # ## -function lhs_docker_install_aws_linux_2_instruction() { - cat <<-__EOF__ - sudo amazon-linux-extras install -y docker - sudo service docker start - sudo usermod -a -G docker ec2-user - sudo chkconfig docker on - sudo yum install -y git - sudo curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-\$(uname -s)-\$(uname -m) -o /usr/local/bin/docker-compose - sudo chmod +x /usr/local/bin/docker-compose - echo 'export PATH="/usr/local/bin:\$PATH"' >> ~/.bash_profile - source ~/.bash_profile - docker-compose version - __EOF__ -} - -function lhs_docker_upgrade_ubuntu_instruction() { - local lhs_docs=$( - cat <<-__EOF__ - https://docs.docker.com/engine/install/ubuntu/ - __EOF__ - ) - echo "$lhs_docs" -} - -function lhs_docker_run_mongodb_client() { - echo "\ - docker run -ti --rm mongo:5.0.10 bash - Running [mongosh endpoint] - - " - docker run -ti --rm mongo:5.0.10 bash -} - -function lhs_docker_run_mysql_client_57() { - - echo "\ - docker run -it --rm -v /tmp/dump:/dump mysql:5.7 /bin/bash - - Running commandline to dump data - mysqldump -u -h -p > /dump/.sql - - " - docker run -it --rm -v /tmp/dump:/dump mysql:5.7 /bin/bash -} - function lhs_docker_build_git_secret_image() { - local image_name="gitsecrets" - docker build -t ${image_name} - <<-EOF - FROM ubuntu:20.04 - RUN apt update && apt install -y git make - RUN git clone https://github.com/awslabs/git-secrets.git - WORKDIR /git-secrets - RUN make install + local image_name="gitsecrets" + docker build -t ${image_name} - <<- EOF + FROM ubuntu:22.04 + + # Install dependencies and clean up in single layer + RUN apt-get update && \ + apt-get install -y git make && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + + # Clone and install git-secrets + RUN git clone https://github.com/awslabs/git-secrets.git && \ + cd git-secrets && \ + make install + + # Configure git-secrets globally RUN git secrets --register-aws --global && \ git secrets --install ~/.git-templates/git-secrets && \ git config --global init.templateDir ~/.git-templates/git-secrets - # Adds a prohibited pattern to the global git config - # Slack - RUN git secrets --add --global "(xoxp|xoxb|xapp)-[0-9]{12}-[0-9]{13}-[a-zA-Z0-9]{24}" - # Github token - RUN git secrets --add --global "(ghp)_[a-zA-Z0-9]{36}" - # Gitlab token - RUN git secrets --add --global "(glpat)-[a-zA-Z0-9\-]{20}" - - # Jenkins token - #RUN git secrets --add --global "[a-zA-Z0-9]{32}" + # Add security patterns for common services + # Slack tokens (xoxp, xoxb, xapp) + RUN git secrets --add --global "(xoxp|xoxb|xapp)-[0-9]{12}-[0-9]{13}-[a-zA-Z0-9]{24}" - # Backlog token - #RUN git secrets --add --global "[a-zA-Z0-9]{64}" + # GitHub tokens (ghp, gho, ghu, ghs, ghr) + RUN git secrets --add --global "(ghp|gho|ghu|ghs|ghr)_[a-zA-Z0-9]{36}" - # AWS account id such as 123456789123 - #RUN git secrets --add --global "^[0-9]{12}$" + # GitLab tokens + RUN git secrets --add --global "(glpat)-[a-zA-Z0-9\-]{20}" - # NewRelic + # NewRelic license keys RUN git secrets --add --global "[0-9a-zA-Z]{36}NRAL" - # Git allow pattern - # RUN git secrets --add --global --allowed '(uuid_1|uuid_2)' - WORKDIR /repository - RUN git config --global --add safe.directory /repository - EOF + # Generic JWT tokens + RUN git secrets --add --global "eyJ[a-zA-Z0-9+/]*\.[a-zA-Z0-9+/]*\.[a-zA-Z0-9+/\-_]*" -} + # Generic API keys and tokens with common prefixes (32+ alphanumeric characters) + RUN git secrets --add --global "(api[_-]?key|apikey|token|secret|access[_-]?token)[=:\"' ]+[a-zA-Z0-9]{32,}" -function lhs_docker_docs_build_image_optimized_instruction() { + # Database connection strings + RUN git secrets --add --global "(mongodb|mysql|postgres)://[^\\s]*:[^\\s]*@" - local lhs_docs=$( - cat <<-__EOF__ - Use minimal base images - Use multistage builds - Use Dockerignore - Double-check the dependencies - Minimize the image layers - __EOF__ - ) + # Private keys - using escaped pattern to avoid shell interpretation + RUN git secrets --add --global "BEGIN.*PRIVATE.*KEY" - echo "${lhs_docs}" -} + # Set working directory and configure safe directory + WORKDIR /repository + RUN git config --global --add safe.directory /repository -function lhs_docker_analyze_docker_image_instruction() { + # Add metadata labels + LABEL description="Git-secrets scanner with pre-configured security patterns" + LABEL version="1.0" + LABEL usage="docker run -v \$(pwd):/repository gitsecrets git secrets --scan" + EOF - local lhs_docs=$( - cat <<-__EOF__ - brew install dive # Install dive to analyze docker image - open "https://github.com/wagoodman/dive" # Open dive document - dive # Analyze docker image - __EOF__ - ) - echo "${lhs_docs}" + echo "โœ… Image '${image_name}' built successfully!" + echo "๐Ÿ“– Usage: docker run -v \$(pwd):/repository ${image_name} git secrets --scan" + echo "๐Ÿ› ๏ธ Install hooks: docker run -v \$(pwd):/repository ${image_name} git secrets --install" } -function lhs_docker_docs_all() { - local_lhs_docs_add_prefix 'lhs_docker_docs_build_image_optimized_instruction' 'image' - local_lhs_docs_add_prefix 'lhs_docker_install_aws_linux_2_instruction' 'install' +# Runs git-secrets scan on the current directory or specified files/directories +# Usage: lhs_docker_scan_secrets [path] [options] +# Examples: +# lhs_docker_scan_secrets # Scan current directory +# lhs_docker_scan_secrets /path/to/project # Scan specific directory +# lhs_docker_scan_secrets --history # Scan git history +# lhs_docker_scan_secrets --cached # Scan staged files +function lhs_docker_scan_secrets() { + local scan_path="${1:-.}" + local scan_options="" + local scan_type="directory" + + # Parse arguments for special scan types + case "$1" in + --history) + scan_type="history" + scan_path="${2:-.}" + ;; + --cached) + scan_options="--cached" + scan_path="${2:-.}" + scan_type="cached" + ;; + --untracked) + scan_options="--untracked" + scan_path="${2:-.}" + scan_type="untracked" + ;; + --recursive) + scan_options="--recursive" + scan_path="${2:-.}" + scan_type="recursive" + ;; + --help) + echo "๐Ÿ” Git-secrets scanner usage:" + echo "" + echo "๐Ÿ“‹ Basic Usage:" + echo " lhs_docker_scan_secrets # Scan current directory" + echo " lhs_docker_scan_secrets /path/to/project # Scan specific path" + echo "" + echo "๐ŸŽฏ Special Scan Types:" + echo " lhs_docker_scan_secrets --history # Scan entire git history" + echo " lhs_docker_scan_secrets --cached # Scan staged files only" + echo " lhs_docker_scan_secrets --untracked # Include untracked files" + echo " lhs_docker_scan_secrets --recursive # Recursive directory scan" + echo "" + echo "โš™๏ธ Prerequisites:" + echo " โ€ข Docker must be installed and running" + echo " โ€ข Git-secrets image must be built (run lhs_docker_build_git_secret_image)" + echo "" + echo "๐Ÿ’ก Tips:" + echo " โ€ข Create .gitallowed file to handle false positives" + return 0 + ;; + esac + + # Check if Docker is available + if ! command -v docker &> /dev/null; then + echo "โŒ Docker is not installed or not in PATH" + echo "๐Ÿ“ฅ Please install Docker first" + return 1 + fi + + # Check if git-secrets image exists + if ! docker image inspect gitsecrets &> /dev/null; then + echo "โŒ Git-secrets Docker image not found" + echo "๐Ÿ”จ Run 'lhs_docker_build_git_secret_image' to build the image first" + return 1 + fi + + # Convert relative path to absolute path for Docker + if [[ "$scan_path" != /* ]]; then + scan_path="$(cd "$scan_path" 2> /dev/null && pwd)" || { + echo "โŒ Path '$scan_path' does not exist" + return 1 + } + fi + + echo "๐Ÿ” Running git-secrets scan..." + echo "๐Ÿ“‚ Target: $scan_path" + echo "๐ŸŽฏ Type: $scan_type" + echo "" + + # Run the appropriate scan command + local exit_code=0 + if [[ "$scan_type" == "history" ]]; then + echo "โณ Scanning git history (this may take a while)..." + docker run -v "$scan_path:/repository" gitsecrets git secrets --scan-history + exit_code=$? + else + echo "โณ Scanning files..." + docker run -v "$scan_path:/repository" gitsecrets git secrets --scan $scan_options + exit_code=$? + fi + + echo "" + + # Interpret results + if [[ $exit_code -eq 0 ]]; then + echo "โœ… No secrets detected!" + echo "๐ŸŽ‰ Repository appears clean of sensitive data" + else + echo "๐Ÿšจ Secrets detected! (Exit code: $exit_code)" + echo "" + echo "๐Ÿ”ง Next steps:" + echo " 1. Review the files listed above" + echo " 2. Remove or secure any real secrets" + echo " 3. Add false positives to .gitallowed file" + echo " 4. Re-run the scan to verify fixes" + echo "" + echo "๐Ÿ’ก Quick fixes:" + echo " โ€ข Create .gitallowed file to handle false positives" + echo " โ€ข Scan again: lhs_docker_scan_secrets" + fi + + return $exit_code } -function lhs_docker_alpine_install_telnet_instruction() { - - local lhs_docs=$( - cat <<-__EOF__ - apk update - apk add busybox-extras - __EOF__ - ) - - echo "$lhs_docs" -} +# End of file diff --git a/services/git.sh b/services/git.sh index 421eead..12e785f 100644 --- a/services/git.sh +++ b/services/git.sh @@ -5,18 +5,18 @@ # @return # function lhs_git_scan_secrets() { - local image_name="gitsecrets" - lhs_docker_build_git_secret_image - echo "\033[31m Scan history \033[0m" - docker run --rm -v $(pwd):/repository:ro ${image_name} git secrets --scan-history - echo "\033[31m Scan recursive \033[0m" - docker run --rm -v $(pwd):/repository:ro ${image_name} git secrets --scan -r /repository + local image_name="gitsecrets" + lhs_docker_build_git_secret_image + echo "\033[31m Scan history \033[0m" + docker run --rm -v "$(pwd)":/repository:ro "${image_name}" git secrets --scan-history + echo "\033[31m Scan recursive \033[0m" + docker run --rm -v "$(pwd)":/repository:ro "${image_name}" git secrets --scan -r /repository } function lhs_git_set_pre_defined_commit_template() { - # https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration - cat <<-__EOF__ >~/.gitmessage.txt + # https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration + cat <<- __EOF__ > ~/.gitmessage.txt [Action] - try to keep under 50 characters # Keep the message short and to the point. @@ -44,7 +44,7 @@ function lhs_git_set_pre_defined_commit_template() { # Multi-line description of commit, feel free to be detailed. (the body should be restricted to 72 characters) - #Further paragraphs come after blank lines. + #Further paragraphs come after blank lines. # - Bullet points are okay, too # - Typically a hyphen or asterisk is used for the bullet, preceded by a single space, with blank lines in between, but conventions vary here @@ -54,16 +54,16 @@ function lhs_git_set_pre_defined_commit_template() { # [Ticket: X] __EOF__ - git config --global commit.template ~/.gitmessage.txt + git config --global commit.template ~/.gitmessage.txt } function lhs_git_commit_suggestions() { - # More instruction - https://www.freecodecamp.org/news/how-to-write-better-git-commit-messages/ - # - https://chiamakaikeanyi.dev/how-to-write-good-git-commit-messages/ - # Set default git commit message - https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration - cat <<-__EOF__ + # More instruction - https://www.freecodecamp.org/news/how-to-write-better-git-commit-messages/ + # - https://chiamakaikeanyi.dev/how-to-write-good-git-commit-messages/ + # Set default git commit message - https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration + cat <<- __EOF__ git commit -m "[Add] - Your add description" git commit -m "[Improvement] - for enhancements" git commit -m "[Update] - Your update description" @@ -93,15 +93,22 @@ function lhs_git_commit_suggestions() { } function lhs_git_commit_suggestions_with_hint() { - local lhs_input=$( - lhs_git_commit_suggestions | peco --query "$LBUFFER" --prompt "Git commit suggestions >" --initial-filter "${LHS_PECO_FILTER_TYPE}" - ) - - # To check it is example. - if [[ $lhs_input = Ex:* ]]; then - BUFFER=$(echo "${lhs_input}" | awk -F "Ex:" '{print $2}') - else - BUFFER=${lhs_input} - fi - CURSOR=$#BUFFER + local lhs_input + + lhs_input=$( + lhs_git_commit_suggestions | peco --query "$LBUFFER" --prompt "Git commit suggestions >" --initial-filter "${LHS_PECO_FILTER_TYPE}" + ) + + # To check it is example. + # shellcheck disable=SC2034 + if [[ $lhs_input = Ex:* ]]; then + BUFFER=$(echo "${lhs_input}" | awk -F "Ex:" '{print $2}') + else + BUFFER=${lhs_input} + fi + + # shellcheck disable=SC2034 + CURSOR=$#BUFFER } + +# End of file diff --git a/services/gitlab.sh b/services/gitlab.sh deleted file mode 100644 index a9bf588..0000000 --- a/services/gitlab.sh +++ /dev/null @@ -1 +0,0 @@ -#!/bin/bash diff --git a/services/jenkins.sh b/services/jenkins.sh deleted file mode 100644 index d661c30..0000000 --- a/services/jenkins.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -function lhs_jenkins_load_helpful_commandlines() { - for script in $(find ${HELPFUL_COMMANDLINES_SOURCE_SCRIPTS:-~/lamhaison-tools/helpful-commandlines} -type f -name '*.sh' | grep -v main.sh); do source $script; done -} - -function lhs_jenkins_create_release_version_file() { - VERSION_FILE=./release.txt - release_time=$(date '+%Y-%m-%d %H:%M:%S') - echo "release_hash: ${GIT_COMMIT}" >${VERSION_FILE} - echo "released_at: ${release_time}" >>${VERSION_FILE} - cat ${VERSION_FILE} -} diff --git a/services/mysql.sh b/services/mysql.sh index 9ee8380..af78d3d 100644 --- a/services/mysql.sh +++ b/services/mysql.sh @@ -1,7 +1,7 @@ #!/bin/bash function lhs_mysql_dump_db { - echo ' + echo ' db_username= db_password= db_address= diff --git a/services/name_convention.sh b/services/name_convention.sh index 6742de9..b5739f7 100644 --- a/services/name_convention.sh +++ b/services/name_convention.sh @@ -1,5 +1,5 @@ #!/bin/bash function lhs_nameConvention_git_branch_name() { - echo "develop staging master" + echo "develop staging master" } diff --git a/services/other.sh b/services/other.sh index 32ab08f..b229627 100644 --- a/services/other.sh +++ b/services/other.sh @@ -1,13 +1,13 @@ #!/bin/bash function lhs_code_commment_instruction() { - cat <<-__EOF__ + cat <<- __EOF__ * For the task will be fixed later. Comment # TODO Later __EOF__ } function lhs_code_function_name_instruction() { - cat <<__EOF__ + cat << __EOF__ get: to get an item. list: to list all items. rm: to remove the item. diff --git a/terraform/terraform.sh b/terraform/terraform.sh index 0fb4bff..2cca4da 100644 --- a/terraform/terraform.sh +++ b/terraform/terraform.sh @@ -1,9 +1,9 @@ #!/bin/bash function lhs_iac_tf_enable_debug_mode() { - export TF_LOG=TRACE + export TF_LOG=TRACE } function lhs_iac_tf_disable_debug_mode() { - unset TF_LOG + unset TF_LOG }