{"id":18030867,"url":"https://github.com/atc0005/elbow","last_synced_at":"2026-02-27T22:02:34.707Z","repository":{"id":35237404,"uuid":"202958330","full_name":"atc0005/elbow","owner":"atc0005","description":"Elbow, Elbow grease.","archived":false,"fork":false,"pushed_at":"2025-03-03T23:56:12.000Z","size":5883,"stargazers_count":0,"open_issues_count":32,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-04T00:27:46.972Z","etag":null,"topics":["command-line","file","go","golang","prune"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atc0005.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-18T04:08:44.000Z","updated_at":"2025-03-03T23:52:07.000Z","dependencies_parsed_at":"2023-11-17T12:30:49.768Z","dependency_job_id":"0c735cfe-f9a3-4215-8ca7-015c358cf8ef","html_url":"https://github.com/atc0005/elbow","commit_stats":null,"previous_names":[],"tags_count":70,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atc0005%2Felbow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atc0005%2Felbow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atc0005%2Felbow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atc0005%2Felbow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atc0005","download_url":"https://codeload.github.com/atc0005/elbow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247250174,"owners_count":20908318,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-line","file","go","golang","prune"],"created_at":"2024-10-30T09:15:25.209Z","updated_at":"2026-02-27T22:02:29.667Z","avatar_url":"https://github.com/atc0005.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# elbow\n\nElbow, Elbow grease.\n\n[![Latest Release](https://img.shields.io/github/release/atc0005/elbow.svg?style=flat-square)](https://github.com/atc0005/elbow/releases/latest)\n[![Go Reference](https://pkg.go.dev/badge/github.com/atc0005/elbow.svg)](https://pkg.go.dev/github.com/atc0005/elbow)\n[![go.mod Go version](https://img.shields.io/github/go-mod/go-version/atc0005/elbow)](https://github.com/atc0005/elbow)\n[![Lint and Build](https://github.com/atc0005/elbow/actions/workflows/lint-and-build.yml/badge.svg)](https://github.com/atc0005/elbow/actions/workflows/lint-and-build.yml)\n[![Project Analysis](https://github.com/atc0005/elbow/actions/workflows/project-analysis.yml/badge.svg)](https://github.com/atc0005/elbow/actions/workflows/project-analysis.yml)\n\n- [elbow](#elbow)\n  - [Project home](#project-home)\n  - [Purpose](#purpose)\n  - [Gotchas](#gotchas)\n  - [Features](#features)\n  - [Changelog](#changelog)\n  - [Requirements](#requirements)\n    - [Building source code](#building-source-code)\n    - [Running](#running)\n  - [Installation](#installation)\n    - [From source](#from-source)\n    - [Using release binaries](#using-release-binaries)\n  - [Setup test environment](#setup-test-environment)\n  - [Configuration Options](#configuration-options)\n    - [Precedence](#precedence)\n    - [Command-line Arguments](#command-line-arguments)\n    - [Environment Variables](#environment-variables)\n    - [Configuration File](#configuration-file)\n  - [Examples](#examples)\n    - [Overview](#overview)\n    - [Log output](#log-output)\n      - [Text format](#text-format)\n        - [Screenshots](#screenshots)\n          - [Original implementation](#original-implementation)\n          - [Multiple paths](#multiple-paths)\n      - [JSON format](#json-format)\n    - [Help Output](#help-output)\n    - [Prune `.war` files from each branch recursively, keep newest 2](#prune-war-files-from-each-branch-recursively-keep-newest-2)\n    - [Keep oldest 1, debug logging, ignore errors, use syslog](#keep-oldest-1-debug-logging-ignore-errors-use-syslog)\n    - [Log to a file in JSON format](#log-to-a-file-in-json-format)\n  - [License](#license)\n  - [References](#references)\n    - [Flag packages](#flag-packages)\n    - [Configuration object](#configuration-object)\n    - [Sorting files](#sorting-files)\n    - [Path/File Existence](#pathfile-existence)\n    - [Slice management](#slice-management)\n\n## Project home\n\nSee [our GitHub repo][repo-url] for the latest code, to file an issue or\nsubmit improvements for review and potential inclusion into the project.\n\n## Purpose\n\nPrune content matching specific patterns, either in a single directory or\nrecursively through a directory tree. The primary goal is to use this\napplication from a cron job to perform routine pruning of generated files that\nwould otherwise completely clog a filesystem.\n\n## Gotchas\n\n- File extensions are *case-sensitive*\n- File name patterns are *case-sensitive*\n- File name patterns, much like shell globs, may match more than intended.\n  - Test carefully and do not provide the `--remove` flag until you have\n    tested and are ready to actually prune the content.\n\n## Features\n\n- Supports multiple (merged) sources for supplying configuration settings\n  - Environment variables\n  - TOML format configuration file\n  - Command-line flags (with detailed help output)\n  - Note: See the [Precedence](#precedence) list for how multiple\n    configuration sources are processed\n- Match on specified file patterns\n- Flat (single-level) or recursive search\n- Process one or many paths\n- Age-based threshold for matches (e.g., match files X days old or older)\n- Keep a specified number of older or newer matches\n- Limit search to specified list of file extensions\n- Toggle file removal (read-only by default)\n- Extensive, leveled-logging\n  - (Optional) Syslog logging (not supported on Windows)\n  - (Optional) Logging to a file (if enabled, mutes console output)\n  - Text or JSON log formats\n- (Optional) Ignore errors encountered when removing files\n\nWorth noting: This project uses Go modules (vs classic `GOPATH` setup)\n\n## Changelog\n\nSee the [`CHANGELOG.md`](CHANGELOG.md) file for the changes associated with\neach release of this application. Changes that have been merged to `master`,\nbut not yet an official release may also be noted in the file under the\n`Unreleased` section. A helpful link to the Git commit history since the last\nofficial release is also provided for further review.\n\n## Requirements\n\nThe following is a loose guideline. Other combinations of Go and operating\nsystems for building and running tools from this repo may work, but have not\nbeen tested.\n\n### Building source code\n\n- Go\n  - see this project's `go.mod` file for *preferred* version\n  - this project tests against [officially supported Go\n    releases][go-supported-releases]\n    - the most recent stable release (aka, \"stable\")\n    - the prior, but still supported release (aka, \"oldstable\")\n- GCC\n  - if building with custom options (as the provided `Makefile` does)\n- `make`\n  - if using the provided `Makefile`\n\n### Running\n\n- Windows 10\n- Ubuntu Linux 18.04+\n- Red Hat Enterprise Linux 7+\n\n## Installation\n\n### From source\n\n1. [Download][go-docs-download] Go\n1. [Install][go-docs-install] Go\n   - NOTE: Pay special attention to the remarks about `$HOME/.profile`\n1. Clone the repo\n   1. `cd /tmp`\n   1. `git clone https://github.com/atc0005/elbow`\n   1. `cd elbow`\n1. Install dependencies (optional)\n   - for Ubuntu Linux\n     - `sudo apt-get install make gcc`\n   - for CentOS Linux\n     1. `sudo yum install make gcc`\n1. Build\n   - for current operating system\n     - `go build -mod=vendor ./cmd/elbow/`\n       - *forces build to use bundled dependencies in top-level `vendor`\n         folder*\n   - for all supported platforms (where `make` is installed)\n      - `make all`\n   - for Windows\n      - `make windows`\n   - for Linux\n     - `make linux`\n1. Copy the applicable binary to whatever systems needs to run it\n   - if using `Makefile`: look in `/tmp/release_assets/elbow/`\n   - if using `go build`: look in `/tmp/elbow/`\n\n**NOTE**: Depending on which `Makefile` recipe you use the generated binary\nmay be compressed and have an `xz` extension. If so, you should decompress the\nbinary first before deploying it (e.g., `xz -d elbow-linux-amd64.xz`).\n\n### Using release binaries\n\n1. Download the [latest\n   release](https://github.com/atc0005/elbow/releases/latest) binaries\n1. Decompress binaries\n   - e.g., `xz -d elbow-linux-amd64.xz`\n1. Deploy\n   - Place `elbow` in a location of your choice\n     - e.g., `/usr/local/bin/`\n\n**NOTE**:\n\nDEB and RPM packages are provided as an alternative to manually deploying\nbinaries.\n\n## Setup test environment\n\n1. Launch container, VM or WSL instance\n1. Clone the repo\n   1. `cd /tmp`\n   1. `git clone https://github.com/atc0005/elbow`\n   1. `cd elbow`\n1. Create test files\n   - in subdirectories of `/tmp/elbow`\n     - `make testenv`\n   - in a custom location (e.g., in `$HOME`)\n     - `mkdir -vp $HOME/tmp/elbow`\n     - `make testenv TESTENVBASEDIR=\"$HOME/tmp/elbow\"`\n\nSee the [Examples](#examples) or the [Configuration\nOptions](#configuration-options) sections for examples of running `elbow`\nagainst these newly created test files.\n\n## Configuration Options\n\n### Precedence\n\n**Note: This behavior is subject to change based on feedback.**\n\nThe priority order is (mostly):\n\n1. Command line flags (highest priority)\n1. Environment variables\n1. Environment variables loaded from `.env` files\n   - **Not supported yet**\n1. Configuration file\n1. Default settings (lowest priority)\n\nConfiguration sources lower in the list are loaded first, with configuration\nsources above loaded sequentially (if enabled) after. Settings are *merged*,\nwith settings specifically defined in sources with higher precedence\noverriding values set by configuration sources with lower precedence.\n\nFor example, if the configuration file defines `/tmp/elbow/path1` as the path\nto process, an environment variable defines `/tmp/elbow/path2` and the\ncommand-line flag for that setting specifies `/tmp/elbow/path3`, the\ncommand-line flag will win and `/tmp/elbow/path3` will be used.\n\nThe intent of this behavior is to provide a *feathered* layering of\nconfiguration settings; if a configuration file provides all settings that you\nwant other than one, you can use the configuration file for the other settings\nand specify the settings that you wish to override via environment variable or\ncommand-line flag.\n\n**Note: This behavior is subject to change based on feedback.**\n\n### Command-line Arguments\n\nAside from the built-in `-h`, short flag names are currently not supported.\n\n| Long             | Required | Default        | Repeat | Possible                                                                                                | Description                                                                                                                                                    |\n| ---------------- | -------- | -------------- | ------ | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `keep`           | No       | `0`            | No     | `0+`                                                                                                    | Keep specified number of matching files.                                                                                                                       |\n| `paths`          | Yes      | N/A            | No     | *one or more valid directory paths*                                                                     | List of comma or space-separated paths to process.                                                                                                             |\n| `pattern`        | No       | *empty string* | No     | *valid file name characters*                                                                            | Substring pattern to compare filenames against. Wildcards are not supported.                                                                                   |\n| `extensions`     | No       | *empty list*   | No     | *valid file extensions*                                                                                 | Limit search to specified file extension. Specify as space separated list to match multiple required extensions. Comparisons are performed case-insensitively. |\n| `recurse`        | No       | `false`        | No     | `true`, `false`                                                                                         | Perform recursive search into subdirectories.                                                                                                                  |\n| `keep-old`       | No       | `false`        | No     | `true`, `false`                                                                                         | Keep oldest files instead of newer.                                                                                                                            |\n| `age`            | No       | `0`            | No     | `0+`                                                                                                    | Limit search to files that are the specified number of days old or older.                                                                                      |\n| `remove`         | Maybe    | `false`        | No     | `true`, `false`                                                                                         | Remove matched files. The default behavior is to only note what matching files *would* be removed.                                                             |\n| `ignore-errors`  | No       | `false`        | No     | `true`, `false`                                                                                         | Ignore errors encountered during file removal.                                                                                                                 |\n| `log-format`     | No       | `text`         | No     | `text`, `json`                                                                                          | Log formatter used by logging package.                                                                                                                         |\n| `log-file`       | No       | *empty string* | No     | *writable directory path*                                                                               | Optional log file used to hold logged messages. If set, log messages are not displayed on the console.                                                         |\n| `console-output` | No       | `stdout`       | No     | `stdout`, `stderr`                                                                                      | Specify how log messages are logged to the console.                                                                                                            |\n| `log-level`      | No       | `info`         | No     | `emergency`, `alert`, `critical`, `panic`, `fatal`, `error`, `warn`, `info`, `notice`, `debug`, `trace` | Maximum log level at which messages will be logged. Log messages below this threshold will be discarded.                                                       |\n| `use-syslog`     | No       | `false`        | No     | `true`, `false`                                                                                         | Log messages to syslog in addition to other ouputs. Not supported on Windows.                                                                                  |\n| `config-file`    | No       | *empty string* | No     | *valid path to config file*                                                                             | Full path to optional TOML-formatted configuration file. See `config.example.toml` for a starter template.                                                     |\n\n### Environment Variables\n\nIf set, environment variables override settings provided by a configuration\nfile. If used, command-line arguments override the equivalent environment\nvariables listed below. See the [Command-line\nArguments](#command-line-arguments) table for more information.\n\n| Flag Name        | Environment Variable Name | Notes                        | Example                                                                             |\n| ---------------- | ------------------------- | ---------------------------- | ----------------------------------------------------------------------------------- |\n| `keep`           | `ELBOW_KEEP`              |                              | `ELBOW_KEEP=1`                                                                      |\n| `paths`          | `ELBOW_PATHS`             |                              | `ELBOW_PATHS=\"/tmp/elbow/path1\"`, `ELBOW_PATHS=\"/tmp/elbow/path1,/tmp/elbow/path2\"` |\n| `pattern`        | `ELBOW_FILE_PATTERN`      |                              | `ELBOW_FILE_PATTERN=\"reach-masterdev-\"`                                             |\n| `extensions`     | `ELBOW_EXTENSIONS`        | *Comma-separated, no spaces* | `ELBOW_EXTENSIONS=\".war,.tmp\"`                                                      |\n| `recurse`        | `ELBOW_RECURSE`           |                              | `ELBOW_RECURSE=\"true\"`                                                              |\n| `keep-old`       | `ELBOW_KEEP_OLD`          |                              | `ELBOW_KEEP_OLD=\"true\"`                                                             |\n| `age`            | `ELBOW_FILE_AGE`          |                              | `ELBOW_FILE_AGE=120`                                                                |\n| `remove`         | `ELBOW_REMOVE`            |                              | `ELBOW_REMOVE=\"false\"`                                                              |\n| `ignore-errors`  | `ELBOW_IGNORE_ERRORS`     |                              | `ELBOW_IGNORE_ERRORS=\"true\"`                                                        |\n| `log-format`     | `ELBOW_LOG_FORMAT`        |                              | `ELBOW_LOG_FORMAT=\"json\"`                                                           |\n| `log-file`       | `ELBOW_LOG_FILE`          |                              | `ELBOW_LOG_FILE=\"/tmp/testing-masterqa-build-removals.txt\"`                         |\n| `console-output` | `ELBOW_CONSOLE_OUTPUT`    |                              | `ELBOW_CONSOLE_OUTPUT=\"stdout\"`                                                     |\n| `log-level`      | `ELBOW_LOG_LEVEL`         |                              | `ELBOW_LOG_LEVEL=\"debug\"`                                                           |\n| `use-syslog`     | `ELBOW_USE_SYSLOG`        |                              | `ELBOW_USE_SYSLOG=\"true\"`                                                           |\n| `config-file`    | `ELBOW_CONFIG_FILE`       |                              | `ELBOW_CONFIG_FILE=\"/usr/local/elbow/config.toml\"`                                  |\n\n### Configuration File\n\nConfiguration file settings have the lowest priority and are overridden by\nsettings specified in other configuration sources, except for default values.\nSee the [Command-line Arguments](#command-line-arguments) table for more\ninformation, including the available values for the listed configuration\nsettings.\n\n| Flag Name        | Config file Setting Name | Section Name   | Notes                                                                    |\n| ---------------- | ------------------------ | -------------- | ------------------------------------------------------------------------ |\n| `pattern`        | `pattern`                | `filehandling` |                                                                          |\n| `extensions`     | `file_extensions`        | `filehandling` |                                                                          |\n| `age`            | `file_age`               | `filehandling` |                                                                          |\n| `keep`           | `files_to_keep`          | `filehandling` |                                                                          |\n| `keep-old`       | `keep_oldest`            | `filehandling` |                                                                          |\n| `remove`         | `remove`                 | `filehandling` |                                                                          |\n| `ignore-errors`  | `ignore_errors`          | `filehandling` |                                                                          |\n| `paths`          | `paths`                  | `search`       | [Multi-line array](https://github.com/toml-lang/toml#user-content-array) |\n| `recurse`        | `recursive_search`       | `search`       |                                                                          |\n| `log-level`      | `log_level`              | `logging`      |                                                                          |\n| `log-format`     | `log_format`             | `logging`      |                                                                          |\n| `log-file`       | `log_file_path`          | `logging`      |                                                                          |\n| `console-output` | `console_output`         | `logging`      |                                                                          |\n| `use-syslog`     | `use_syslog`             | `logging`      |                                                                          |\n\nSee the [`config.example.toml`](config.example.toml) file for an example of\nhow to use these settings.\n\n## Examples\n\n### Overview\n\nThe following steps illustrate a rough, overall idea of what `elbow` is\nintended to do. The steps illustrate building and running the application from\nwithin an Ubuntu Linux Subsystem for Windows (WSL) instance. The `t` volume is\npresent on the Windows host.\n\nThe file extension used in the examples below is for `WAR` files that are\ngenerated on a build system that our group used to maintain. The idea is that\n`elbow` could be run as a cron job to help ensure that only X copies (the most\nrecent in our case) for each of three branches remain on the build box.\n\nThere are better approaches to managing build artifacts (e.g., containers);\nthis tool seeks to solve in a simple, \"low tech\" way.\n\nThe particular repo that the build system processed has three branches:\n\n| Branch Name | Type of build |\n| ----------- | ------------- |\n| `master`    | Production    |\n| `masterqa`  | Q/A           |\n| `masterdev` | Development   |\n\nWe had little control over the name of these branches.\n\n### Log output\n\n#### Text format\n\n```ShellSession\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --pattern \"reach-master\" --keep 1 --recurse --keep-old --ignore-errors --log-level info --use-syslog --log-format text\n```\n\n```ShellSession\nINFO[0000] Syslog logging requested, attempting to enable it  use_syslog=true\nERRO[0000] Failed to enable syslog logging: unable to connect to syslog socket: Unix syslog delivery error  use_syslog=true\nWARN[0000] Proceeding without syslog logging             use_syslog=true\nINFO[0000] Starting evaluation of paths list             extensions=\"[]\" file_age=0 file_pattern=reach-master paths=\"[/tmp/elbow/path1 /tmp/elbow/path2]\"\nINFO[0000] Beginning processing of path \"/tmp/elbow/path1\" (1 of 2)  ignore_errors=true iteration=1 total_paths=2\nINFO[0000] 183 files eligible for removal (910.0 MiB)    extensions=\"[]\" file_age=0 file_pattern=reach-master iteration=1 path=/tmp/elbow/path1 total_file_size=954204160\nINFO[0000] 1 files to keep as requested                  iteration=1 keep_oldest=true\nINFO[0000] Ignoring file removal errors: true\nINFO[0000] File removal not enabled, not removing files\nINFO[0000] 0 files successfully removed (0 B)\nINFO[0000] 0 files failed to remove (0 B)\nINFO[0000] Ending processing of path \"/tmp/elbow/path1\" (1 of 2)  ignore_errors=true iteration=1 total_paths=2\nINFO[0000] Beginning processing of path \"/tmp/elbow/path2\" (2 of 2)  ignore_errors=true iteration=2 total_paths=2\nINFO[0000] 183 files eligible for removal (954.0 KiB)    extensions=\"[]\" file_age=0 file_pattern=reach-master iteration=2 path=/tmp/elbow/path2 total_file_size=976896\nINFO[0000] 1 files to keep as requested                  iteration=2 keep_oldest=true\nINFO[0000] Ignoring file removal errors: true\nINFO[0000] File removal not enabled, not removing files\nINFO[0000] 0 files successfully removed (0 B)\nINFO[0000] 0 files failed to remove (0 B)\nINFO[0000] Ending processing of path \"/tmp/elbow/path2\" (2 of 2)  ignore_errors=true iteration=2 total_paths=2\nINFO[0000] Elbow successfully completed.                 eligible_remove=366 eligible_size=\"910.9 MiB\" failed_removed=0 failed_size=\"0 B\" success_removed=0 success_size=\"0 B\"\n```\n\nWhere supported, the output is colored.\n\n##### Screenshots\n\n###### Original implementation\n\nFrom just before the v0.2.0 milestone was completed and the [`v0.2.0`\ntag](https://github.com/atc0005/elbow/releases/tag/v0.2.0) created:\n\n![Colored text output example screenshot][screenshot-v0.2.0]\n\n###### Multiple paths\n\nWhile working on support for multiple paths per [issue\n32](https://github.com/atc0005/elbow/issues/32):\n\n![Colored text output example screenshot][screenshot-issue32]\n\n#### JSON format\n\n```ShellSession\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --pattern \"reach-master\" --keep 1 --recurse --keep-old --ignore-errors --log-level info --use-syslog --log-format json\n```\n\n```json\n{\"level\":\"info\",\"msg\":\"Syslog logging requested, attempting to enable it\",\"time\":\"2019-11-12T06:51:50-06:00\",\"use_syslog\":true}\n{\"level\":\"error\",\"msg\":\"Failed to enable syslog logging: unable to connect to syslog socket: Unix syslog delivery error\",\"time\":\"2019-11-12T06:51:50-06:00\",\"use_syslog\":true}\n{\"level\":\"warning\",\"msg\":\"Proceeding without syslog logging\",\"time\":\"2019-11-12T06:51:50-06:00\",\"use_syslog\":true}\n{\"extensions\":null,\"file_age\":0,\"file_pattern\":\"reach-master\",\"level\":\"info\",\"msg\":\"Starting evaluation of paths list\",\"paths\":[\"/tmp/elbow/path1\",\"/tmp/elbow/path2\"],\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"ignore_errors\":true,\"iteration\":1,\"level\":\"info\",\"msg\":\"Beginning processing of path \\\"/tmp/elbow/path1\\\" (1 of 2)\",\"time\":\"2019-11-12T06:51:50-06:00\",\"total_paths\":2}\n{\"extensions\":null,\"file_age\":0,\"file_pattern\":\"reach-master\",\"iteration\":1,\"level\":\"info\",\"msg\":\"183 files eligible for removal (910.0 MiB)\",\"path\":\"/tmp/elbow/path1\",\"time\":\"2019-11-12T06:51:50-06:00\",\"total_file_size\":954204160}\n{\"iteration\":1,\"keep_oldest\":true,\"level\":\"info\",\"msg\":\"1 files to keep as requested\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"level\":\"info\",\"msg\":\"Ignoring file removal errors: true\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"level\":\"info\",\"msg\":\"File removal not enabled, not removing files\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"level\":\"info\",\"msg\":\"0 files successfully removed (0 B)\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"level\":\"info\",\"msg\":\"0 files failed to remove (0 B)\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"ignore_errors\":true,\"iteration\":1,\"level\":\"info\",\"msg\":\"Ending processing of path \\\"/tmp/elbow/path1\\\" (1 of 2)\",\"time\":\"2019-11-12T06:51:50-06:00\",\"total_paths\":2}\n{\"ignore_errors\":true,\"iteration\":2,\"level\":\"info\",\"msg\":\"Beginning processing of path \\\"/tmp/elbow/path2\\\" (2 of 2)\",\"time\":\"2019-11-12T06:51:50-06:00\",\"total_paths\":2}\n{\"extensions\":null,\"file_age\":0,\"file_pattern\":\"reach-master\",\"iteration\":2,\"level\":\"info\",\"msg\":\"183 files eligible for removal (954.0 KiB)\",\"path\":\"/tmp/elbow/path2\",\"time\":\"2019-11-12T06:51:50-06:00\",\"total_file_size\":976896}\n{\"iteration\":2,\"keep_oldest\":true,\"level\":\"info\",\"msg\":\"1 files to keep as requested\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"level\":\"info\",\"msg\":\"Ignoring file removal errors: true\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"level\":\"info\",\"msg\":\"File removal not enabled, not removing files\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"level\":\"info\",\"msg\":\"0 files successfully removed (0 B)\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"level\":\"info\",\"msg\":\"0 files failed to remove (0 B)\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n{\"ignore_errors\":true,\"iteration\":2,\"level\":\"info\",\"msg\":\"Ending processing of path \\\"/tmp/elbow/path2\\\" (2 of 2)\",\"time\":\"2019-11-12T06:51:50-06:00\",\"total_paths\":2}\n{\"eligible_remove\":366,\"eligible_size\":\"910.9 MiB\",\"failed_removed\":0,\"failed_size\":\"0 B\",\"level\":\"info\",\"msg\":\"Elbow successfully completed.\",\"success_removed\":0,\"success_size\":\"0 B\",\"time\":\"2019-11-12T06:51:50-06:00\"}\n```\n\n### Help Output\n\n```ShellSession\n$ ./elbow --help\nElbow prunes content matching specific patterns, either in a single directory or recursively through a directory tree.\n\nELBOW x.y.z\nhttps://github.com/atc0005/elbow\n\nUsage: elbow [--pattern PATTERN] [--extensions EXTENSIONS] [--age AGE] [--keep KEEP] [--keep-old] [--remove] [--ignore-errors] [--log-level LOG-LEVEL] [--log-format LOG-FORMAT] [--log-file LOG-FILE] [--console-output CONSOLE-OUTPUT] [--use-syslog] [--paths PATHS] [--recurse] [--config-file CONFIG-FILE]\n\nOptions:\n  --pattern PATTERN      Substring pattern to compare filenames against. Wildcards are not supported.\n  --extensions EXTENSIONS\n                         Limit search to specified file extensions. Specify as space separated list to match multiple required extensions. Comparisons are performed case-insensitively.\n  --age AGE              Limit search to files that are the specified number of days old or older.\n  --keep KEEP            Keep specified number of matching files per provided path. [default: -1]\n  --keep-old             Keep oldest files instead of newer per provided path.\n  --remove               Remove matched files per provided path.\n  --ignore-errors        Ignore errors encountered during file removal.\n  --log-level LOG-LEVEL\n                         Maximum log level at which messages will be logged. Log messages below this threshold will be discarded. [default: info]\n  --log-format LOG-FORMAT\n                         Log formatter used by logging package. [default: text]\n  --log-file LOG-FILE    Optional log file used to hold logged messages. If set, log messages are not displayed on the console.\n  --console-output CONSOLE-OUTPUT\n                         Specify how log messages are logged to the console. [default: stdout]\n  --use-syslog           Log messages to syslog in addition to other outputs. Not supported on Windows.\n  --paths PATHS          List of comma or space-separated paths to process.\n  --recurse              Perform recursive search into subdirectories per provided path.\n  --config-file CONFIG-FILE\n                         Full path to optional TOML-formatted configuration file. See config.example.toml for a starter template.\n  --help, -h             display this help and exit\n  --version              display version and exit\n```\n\n### Prune `.war` files from each branch recursively, keep newest 2\n\nNote: Leave off `--remove` to display what *would* be removed.\n\n```ShellSession\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --extensions \".war\" --pattern \"reach-master-\" --keep 2 --recurse --remove\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --extensions \".war\" --pattern \"reach-masterqa-\" --keep 2 --recurse --remove\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --extensions \".war\" --pattern \"reach-masterdev-\" --keep 2 --recurse --remove\n```\n\n### Keep oldest 1, debug logging, ignore errors, use syslog\n\nNote: Leave off `--remove` to display what *would* be removed.\n\n```ShellSession\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --pattern \"reach-master-\" --keep 1 --recurse --keep-old --ignore-errors --log-level debug --use-syslog\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --pattern \"reach-masterqa-\" --keep 1 --recurse --keep-old --ignore-errors --log-level debug --use-syslog\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --pattern \"reach-masterdev-\" --keep 1 --recurse --keep-old --ignore-errors --log-level debug --use-syslog\n```\n\n### Log to a file in JSON format\n\n- These examples attempt to create a log file in the current directory.\n- The default logging format is `text` unless overridden; here we specify `json`.\n- We attempt to enable syslog logging. This currently fails gracefully on Windows.\n- We ignore file removal errors and proceed to the next matching file.\n\n```ShellSession\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --pattern \"reach-master-\" --keep 1 --recurse --keep-old --ignore-errors --log-level debug --log-format json --use-syslog --log-file testing-master-build-removals.txt\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --pattern \"reach-masterqa-\" --keep 1 --recurse --keep-old --ignore-errors --log-level debug --use-syslog --log-format json --log-file testing-masterqa-build-removals.txt\n./elbow --paths \"/tmp/elbow/path1\" \"/tmp/elbow/path2\" --pattern \"reach-masterdev-\" --keep 1 --recurse --keep-old --ignore-errors --log-level debug --use-syslog --log-format json --log-file testing-masterdev-build-removals.txt\n```\n\n## License\n\nTaken directly from the `LICENSE` and `NOTICE.txt` files:\n\n```License\nCopyright 2019-Present Adam Chalkley\n\nhttps://github.com/atc0005/elbow/blob/master/LICENSE\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\nthis file except in compliance with the License. You may obtain a copy of the\nLicense at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed\nunder the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\nCONDITIONS OF ANY KIND, either express or implied. See the License for the\nspecific language governing permissions and limitations under the License.\n```\n\n## References\n\n### Flag packages\n\nThe following list of packages were either used or seriously considered at\nsome point during the development of this project.\n\n- \u003chttps://github.com/jessevdk/go-flags#example\u003e\n- \u003chttps://github.com/sirupsen/logrus\u003e\n- \u003chttps://github.com/integrii/flaggy\u003e\n\n### Configuration object\n\n- \u003chttps://github.com/go-sql-driver/mysql/blob/877a9775f06853f611fb2d4e817d92479242d1cd/dsn.go#L67\u003e\n- \u003chttps://github.com/aws/aws-sdk-go/blob/10878ad0389c5b3069815112ce888b191c8cd325/aws/config.go#L251\u003e\n- \u003chttps://github.com/aws/aws-sdk-go/blob/master/aws/config.go\u003e\n- \u003chttps://github.com/aws/aws-sdk-go/blob/10878ad0389c5b3069815112ce888b191c8cd325/awstesting/integration/performance/s3GetObject/config.go#L25\u003e\n- \u003chttps://github.com/aws/aws-sdk-go/blob/10878ad0389c5b3069815112ce888b191c8cd325/awstesting/integration/performance/s3GetObject/main.go#L25\u003e\n\n### Sorting files\n\n- \u003chttps://stackoverflow.com/questions/46746862/list-files-in-a-directory-sorted-by-creation-time\u003e\n\n### Path/File Existence\n\n- \u003chttps://gist.github.com/mattes/d13e273314c3b3ade33f\u003e\n\n### Slice management\n\n- \u003chttps://yourbasic.org/golang/delete-element-slice/\u003e\n- \u003chttps://stackoverflow.com/questions/37334119/how-to-delete-an-element-from-a-slice-in-golang\u003e\n- \u003chttps://github.com/golang/go/wiki/SliceTricks\u003e\n\n\u003c!-- Footnotes here  --\u003e\n\n[repo-url]: \u003chttps://github.com/atc0005/check-elbow\u003e  \"This project's GitHub repo\"\n\n[go-docs-download]: \u003chttps://golang.org/dl\u003e  \"Download Go\"\n\n[go-docs-install]: \u003chttps://golang.org/doc/install\u003e  \"Install Go\"\n\n[go-supported-releases]: \u003chttps://go.dev/doc/devel/release#policy\u003e \"Go Release Policy\"\n\n[screenshot-v0.2.0]: media/elbow_example_text_log_format_2019-09-26.png \"Colored text output example screenshot\"\n[screenshot-issue32]: media/elbow_example_text_log_format_2019-10-22.png \"Colored text output example screenshot\"\n\n\u003c!-- []: PLACEHOLDER \"DESCRIPTION_HERE\" --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatc0005%2Felbow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatc0005%2Felbow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatc0005%2Felbow/lists"}