{"id":13588287,"url":"https://github.com/ABridoux/scout","last_synced_at":"2025-04-08T03:33:28.428Z","repository":{"id":43064041,"uuid":"247371657","full_name":"ABridoux/scout","owner":"ABridoux","description":"Reading and writing in JSON, Plist, YAML and XML data made simple when the data format is not known at build time. Swift library and command-line tool.","archived":false,"fork":false,"pushed_at":"2024-06-18T13:40:08.000Z","size":4964,"stargazers_count":130,"open_issues_count":10,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-29T20:33:27.454Z","etag":null,"topics":["bash-script","command-line","json","macos","plist","swift","swift-package","xml","yaml"],"latest_commit_sha":null,"homepage":"https://www.woodys-findings.com/scout","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ABridoux.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2020-03-14T23:52:14.000Z","updated_at":"2024-10-13T13:16:27.000Z","dependencies_parsed_at":"2022-09-09T00:00:59.277Z","dependency_job_id":"47d72c4f-7183-473a-91b6-71381c51fc1e","html_url":"https://github.com/ABridoux/scout","commit_stats":{"total_commits":289,"total_committers":6,"mean_commits":"48.166666666666664","dds":0.5882352941176471,"last_synced_commit":"2eedecf909c779fe09310cd1971b9ba6503cb64c"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ABridoux%2Fscout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ABridoux%2Fscout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ABridoux%2Fscout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ABridoux%2Fscout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ABridoux","download_url":"https://codeload.github.com/ABridoux/scout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223300739,"owners_count":17122679,"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":["bash-script","command-line","json","macos","plist","swift","swift-package","xml","yaml"],"created_at":"2024-08-01T15:06:37.124Z","updated_at":"2024-11-06T07:31:18.462Z","avatar_url":"https://github.com/ABridoux.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"\u003cp  align=\"center\"\u003e\n\u003cimg src=\"Resources/scout-logo.png\" height=512px\" /\u003e\n\u003cbr\u003e\nSwift package\u003cbr\u003e\n    \u003ca href=\"#\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Swift-5.6-orange\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://swift.org/package-manager\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/swiftpm-compatible-brightgreen.svg?style=flat\" alt=\"Swift Package Manager\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/ABridoux/scout\"\u003e\n        \u003cimg src=\"https://codecov.io/gh/ABridoux/scout/branch/master/graph/badge.svg\" /\u003e\n    \u003c/a\u003e\n    \u003cbr/\u003e\nInstall\u003cbr\u003e\n    \u003ca href=\"#\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/platforms-mac+linux-brightgreen.svg?style=flat\" alt=\"Mac + Linux\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/ABridoux/scout/releases\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/cli-tool-informational\"\u003e\n    \u003c/a\u003e\n     \u003ca href=\"https://github.com/ABridoux/scout/releases\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/install-pkg%2Bzip-blue\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"#\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/downloads/ABridoux/scout/total\"\u003e\n    \u003c/a\u003e\n    \u003cbr/\u003e\n\u003c/p\u003e\n\n# Scout \u003ca href=\"https://github.com/ABridoux/scout/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/Abridoux/scout?color=lightgrey\u0026label=latest\"/\u003e\u003c/a\u003e\n\nThis library aims to make specific formats data values reading and writing simple when the data format is not known at build time.\nIt was inspired by [SwiftyJson](https://github.com/SwiftyJSON/SwiftyJSON) and all the projects that followed, while trying to cover more ground, like Xml or Plist. It unifies writing and reading for those different formats. Getting a value in a Json format would be the same as getting a value in a Xml format.\n\nSupported formats:\n- JSON\n- Plist\n- YAML\n- XML\n\n#### Minimum requirements\n- Swift: 5.6+\n- macOS: 10.13+\n- iOS: 10.0+\n- tvOS: 10.0+\n- watchOS: 4.0+\n\n## Summary\n- [Why](#why)\n- [Features](#features)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Special thanks](#special-thanks)\n- [Contributing](#contributing)\n\n### Wiki\n\nThe **Swift** wiki can be found on the [Github pages](https://abridoux.github.io/scout/documentation/scout).\nThe **command-line** wiki can be found on [Woody's Findings](https://www.woodys-findings.com/scout/wiki-command-line/home) .\n\n### News\n- Checkout what's new in **Scout** 4.0.0 [here](https://www.woodys-findings.com/scout/news-4.0.0).\n- Checkout what’s new in **Scout** 3.0.0 [here](https://www.woodys-findings.com/scout/news-3.0.0).\n\n## Why?\n\nWith the Foundation libraries to encode/decode Json and Plist, one could ask: why would someone need Scout? Simple answer: there are still cases where you do not know the data format. Sometimes, you will just want to read a single value from a Plist file, and you do not want to create the the `struct` to decode this file. Or you simply cannot know the data format at build time.\n\n### Context\nI have been working with many Mac admins recently, and many had to deal with Json, Plist and Xml data. While some were using a format-specific library like [jq](https://stedolan.github.io/jq/) to parse Json, others were using **awk**.  Each approach is valid, though it comes with some tradeoffs.\n\n#### Using a format-specific library\nYou can use a library for each format. But I am not aware today of a library that unifies all of them. So, what you learned with [jq](https://stedolan.github.io/jq/) cannot be reused to parse Plist data. You would have to learn to use **PlistBuddy** or the **defaults** command. With Scout, you can parse the same way Json, Plist and Xml data.\n\n#### Using a generic text-processing tool\nDon't get me wrong, **awk** is a wonderful tool. It can do so many things. But it is not that easy to learn. And you have to find a way to parse each different format. **Scout** is [really easy to use](https://www.woodys-findings.com/scout/wiki-command-line/examples).\n\n\u003cbr\u003e\n\n## Features\n- CRUD functions for JSON, Plist, XML and YAML data format\n    - Read, Set, Delete or Add a value at a specific path in the data\n    - Subscript dictionary with a dot \".\"\n    - Subscript arrays with an index between brackets [index]. Negative indexes allowed.\n    - Set a key name\n    - Force a type\n    - Dictionary and array count\n    - Dictionary keys\n    - XML attributes reading\n    - Delete array or dictionary when deleting all its values \n    - Array slicing for *read* and *delete* commands \n    - Dictionary filtering for *read* and *delete* commands \n- List paths in the data to iterate over the values\n- Stream or file input\n- Find best match in case of a typo\n- Data formats conversion (e.g. JSON -\u003e Plist, YAML -\u003e XML)\n- CSV export for arrays and dictionaries of arrays \n- CSV import with precise data structure shaping\n- Export to a Zsh array or associative array\n- Syntax highlighting\n- Folding at a depth level\n- Auto-completion for commands \n\n### Insights\n\nThe wiki ([Swift](https://abridoux.github.io/scout/documentation/scout) | [Command-line](https://www.woodys-findings.com/scout/wiki-command-line/home)) gives more details to use those features. Also, the [Playground](Playground) folder offers several commands to play with a *People* file in several formats. The same commands can be found on this [page](https://www.woodys-findings.com/scout/wiki-command-line/examples).\n\n#### CRUD functions for JSON, Plist and XML data format\n- add a value (Create)\n- read a value (Read)\n- set a value (Update)\n- delete a value (Delete)\n\nSubscript dictionary with a dot \".\" like \"dictionary.key\"\n\nSubscript arrays with an index between brackets [index] like \"array[index]\".\nNegative indexes allowed.\n\n##### Set key name\nSet a key name rather than its value.\n\n##### Try to force a type\nPrevent the automatic inferring of a type and try to force one when setting or adding a value.\n\n##### Dictionary and array count\nGet a dictionary or an array count with the `[#]` symbol\n\n##### Dictionary keys list\nGet a dictionary keys list with the `{#}` symbol.\n\n##### Delete arrays or dictionaries when left empty\nWith the *delete* command, it is possible to specify that a dictionary or an array should be deleted when all its keys are also being deleted.\n\n##### Array slicing\nSpecify a slice of an array to read it or to delete it with `[lower:upper]` syntax. Omitting lower bound ~ 0, omitting upper bound ~ last index. Works with negative indexes like `[-4:-3]` to specify a slice from the last 5th to the last 3rd element. With negative slice, omitting the upper bound ~ last index like `[-3:]` to get the last 4 elements of the array.\n\n##### Dictionary filtering\nSpecify a regular expression between sharp signs '#' to filter the keys of a dictionary, like `people.#h.*#` to target all the keys starting with \"h\" in the dictionary 'people'. A key is a valid match when it is entirely validated by the regular expression.\n\n#### List paths\nIt's possible to list the paths in the data to iterate over the values. The paths can be retrieved as an array in a shell script to be used in a loop.\nThis list can be filtered to target only single or group values, specific keys or values, or paths starting from a base.\n\nYou can [learn more](https://www.woodys-findings.com/scout/wiki-command-line/list-paths) about this feature. Also, [scripting recipes](https://www.woodys-findings.com/scout/wiki-command-line/scripting-recipes) are provided with use cases using this feature.\n\n#### Stream or file input\nSet the input as a file with the input option `-i | --input` or as the last process/command output with a pipe:\n```bash\nscout \"path.to.value\" -i File.yml -f yaml\n# is the same as\ncat File | scout \"path.to.value\" -f yaml\n```\n\n#### Find best match in case of a typo\nScout uses the Jaro-Winkler distance to indicate which key is the closest to an unresolved key.\n\n#### Syntax highlighting\nScout will highlight the output when reading or outputting (with the verbose flag) a dictionary or an array value. This is done with the [Lux](https://github.com/ABridoux/lux) library. You can try it with the following command.\n\n```bash\ncurl --silent \"https://api.github.com/repos/ABridoux/scout/releases/latest\" | scout\n```\n\n![](Resources/syntax-highlight.png)\n\nAnother example with one of the playground files and the following command:\n\n```bash\nscout read -i People.plist -f plist \"people.Robert.age=2\"\n```\n\nWhen dealing with large files (although it is not recommended to output large files in the terminal), highlighting the output might bring to slowdowns. It's possible to deactivate the colorisation with the flag `--no-color` or `--nc`. This is automatic when writing the output in a file or when the program output is piped.\n\n#### Data formats conversion\nThe library offer a conversion feature from a supported format to another one like Plist -\u003e JSON or YAML -\u003e XML. Read or modify the data and export it to another format.\n[Learn more](https://www.woodys-findings.com/scout/wiki-command-line/conversion)\n\n#### CSV export\nExport data when dealing with arrays or a dictionary of arrays.\n\n#### CSV import\nConvert CSV input to one of the available formats. When the CSV has named headers, specify how the data structure should be built (array, dictionary) using paths.\n\n#### Zsh arrays\nExport a 1-dimension array to a Zsh array with the `-e array` option and to an associative array with the `-e dictionary` option.\n\n##### Customise colors\nYou can specify your own colors set as explained [here](https://www.woodys-findings.com/scout/wiki-command-line/highlighting). Also, some presets for the macOS terminal default styles can be found in the [Highlight presets folder](Highlight-presets)\n\n#### Folding\nFold arrays or dictionaries at a certain depth level to make the data more readable\n\n#### Auto-completion of commands\nWhen auto-completion is enabled on the shell, use `scout install-completion-script`, then the `source` command if needed to get auto-completion for scout commands.\n\n\u003cbr\u003e\n\n## Installation\n\n### Command Line\n\n#### Homebrew\nUse the following command.\n\n```bash\nbrew install ABridoux/formulae/scout\n```\nIt will **download the notarized executable** from the [latest release](https://github.com/ABridoux/scout/releases/latest/download/scout.zip).\n\n\n#### Download\n\nYou can download the [latest version of the executable](https://github.com/ABridoux/scout/releases/latest/download/scout.zip) from the [releases](https://github.com/ABridoux/scout/releases). Note that the **executable is notarized**. Also, a [scout package](https://github.com/ABridoux/scout/releases/latest/download/scout.pkg) is provided.\n\nAfter having unzipped the file, you can install it if you want to.\n\n```bash\n$ install scout /usr/local/bin/\n```\n\nHere is a command which downloads the latest version of the program and install it in */usr/local/bin*. \nRun it to download and install the latest version of the program. It erases the current version you may have. The last line is optional and installs the script to auto-complete the commands.\n\n```bash\ncurl -LO https://github.com/ABridoux/scout/releases/latest/download/scout.zip \u0026\u0026 \\\nunzip scout.zip \u0026\u0026 \\\nrm scout.zip \u0026\u0026 \\\ninstall scout /usr/local/bin \u0026\u0026 \\\nrm scout\n```\n\n##### Note\n- To find all scout versions, please browse the [releases](https://github.com/ABridoux/scout/releases) page.\n- When deploying a package (with a MDM for example), it might be useful to add the version to the name. To get scout latest version: simply run `scout --version` (`scout version` version \u003c 2.0.0)  to get your **installed scout version**, or ` curl --silent \"https://api.github.com/repos/ABridoux/scout/releases/latest\" | scout tag_name` to get the latest version **available on the Github repository**.\n\n#### Auto-completion\nYou can run `scout install-completion-script` to install the script to auto-complete commands depending on your shell. After this command, you might want to run the `source` command for the changes to be effective.\n\nBash: `source ~/.bashrc` \u003cbr /\u003e\nZsh: `source ~/.zshrc`\n\n### Swift package\n\nStart by importing the package in your file *Packages.swift*.\n```swift\nlet package = Package (\n    ...\n    dependencies: [\n        .package(url: \"https://github.com/ABridoux/scout\", from: \"3.0.0\")\n    ],\n    ...\n)\n```\nYou can then `import Scout` in a file.\n\n\u003cbr\u003e\n\n## Usage\n\n### Playground\nYou can find and try examples with one file *People* using the different available formats in the [Playground folder](Playground). The folder contains a *Commands.md* file so that you can see how to use the same commands with the different formats.\n\n## Special thanks\nFirst of all, many thanks to all contributors of this library. Their help is truly appreciated.\n\nTo parse and edit XML data, as the standard library does not offer a simple way to do it, **Scout** uses the wonderful library of Marko Tadić: [AEXML](https://github.com/tadija/AEXML). He has done an amazing work. And if several XML parsing and writing libraries exist today, I would definitely recommend his. Marko, you might never read those lines, but thank you!\nThe same goes for the [Yams](https://github.com/jpsim/Yams) and its contributors. Thank you for this project.\n\nThanks also to the team at Apple behind the [ArgumentParser](https://github.com/apple/swift-argument-parser) library. They have done an incredible work to make command line tools in Swift easy to implement.\n\nFinally, thanks to [Thijs Xhaflaire](https://github.com/txhaflaire/) and [Armin Briegel](https://github.com/scriptingosx) for their ideas and helpful feedback.\n\n### References\nFont used for the logo: Ver Army by [Damien Gosset](http://sweeep.fr/cv/index.php?c=fonts).\n\n\u003cbr\u003e\n\n## Contributing\nScout is open-source and under a [MIT license](License). If you want to make a change or to add a new feature, please [open an issue](https://github.com/ABridoux/scout/issues) or [a pull request](https://github.com/ABridoux/scout/pull/new). You can learn more about contributing on this [wiki page](https://github.com/ABridoux/scout/wiki/%5B81%5D-Contributing).\nAlso, feel free to [report a bug, an error or even a typo](https://github.com/ABridoux/scout/issues).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FABridoux%2Fscout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FABridoux%2Fscout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FABridoux%2Fscout/lists"}