diff --git a/CHANGELOG.md b/CHANGELOG.md index bed051f..63dbb08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,15 +4,22 @@ All notable changes to this project will be documented in this file. This projec ## [unreleased] +## [v0.3] - 2020-09-14 - v0.3 + +- Added the ability to convert an entire directory of `.yaml` files at once using the syntax: + + ``` + plistyamlplist /path/to/YAML/\*.yaml + ``` ## [v0.2] - 2020-03-06 - v0.2 - Merged in changes from @homebysix. - ## v0.1 - 2020-03-06 - v0.1 - Initial Release (though the tool has been around for some time). -[unreleased]: https://github.com/grahampugh/plist-yaml-plist/compare/v0.2...HEAD +[unreleased]: https://github.com/grahampugh/plist-yaml-plist/compare/v0.3...HEAD +[v0.3]: https://github.com/grahampugh/plist-yaml-plist/compare/v0.2...v0.3 [v0.2]: https://github.com/grahampugh/plist-yaml-plist/compare/v0.1...v0.2 diff --git a/README.md b/README.md index fe98044..4efad12 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -Convert plist <=> yaml -====================== +# Convert plist <=> yaml This utility is designed to convert Apple `plist` files to `yaml`, or `yaml` files to `plist`. I/O is from regular files. -# Prerequisites +## Prerequisites The python `yaml` module is required, which is not installed by default on Macs. You can install it with `pip`, which you may also need to install first. @@ -12,7 +11,7 @@ sudo python -m ensurepip pip install pyyaml ``` -# Usage +## Usage A single command can be used to convert from plist to yaml or from yaml to plist. This depends on the file suffices being predictable: @@ -21,6 +20,8 @@ plistyamlplist -h Usage: ./plistyamlplist.py [] ``` +You can supply the input-file as a glob (`*.yaml`) to convert an entire directory or subset of yaml files at once. This currently only work for converting from yaml to plist. + Otherwise, each file can be used individually: ```bash @@ -42,48 +43,53 @@ Usage: yaml-plist.py [] the output file name will be the `input-file` name with `.yaml` removed. 4. With `plist_yaml.py`, you may have to first convert a binary plist to text format using `plutil`. -# Examples +## Examples To convert a plist file to yaml: -``` -$ plutil -convert xml1 ~/Library/Preferences/com.something.plist -$ ./plistyamlplist.py ~/Library/Preferences/com.something.plist ~/Downloads/com.something.yaml +```bash +plutil -convert xml1 ~/Library/Preferences/com.something.plist +./plistyamlplist.py ~/Library/Preferences/com.something.plist ~/Downloads/com.something.yaml ``` -``` -$ ./plistyamlplist.py ~/Library/Preferences/com.something.plist +```bash +./plistyamlplist.py ~/Library/Preferences/com.something.plist # this will output to `~/Library/Preferences/com.something.plist.yaml' ``` To convert a yaml file to a plist file: -``` -$ ./plistyamlplist.py ~/Downloads/com.something.yaml ~/Downloads/com.something.plist +```bash +./plistyamlplist.py ~/Downloads/com.something.yaml ~/Downloads/com.something.plist ``` -``` +```bash $ ./plistyamlplist.py ~/Downloads/com.something.plist.yaml # this will output to `~/Downloads/com.something.plist' ``` ## YAML folder -If you have a folder named `YAML` in your path, and you do not supply a destination, the script +If you have a folder named `YAML` in your path, and you do not supply a destination, the script will determine if a corresponding folder exists in the path without 'YAML'. For example, consider the following file: - /Users/myuser/gitrepo/YAML/product/com.something.plist.yaml +```bash +/Users/myuser/gitrepo/YAML/product/com.something.plist.yaml +``` If the folder `/Users/myuser/gitrepo/product` exists, the converted file will be created/overwritten at: - /Users/myuser/gitrepo/product/com.something.plist +```bash +/Users/myuser/gitrepo/product/com.something.plist +``` If the above folder does not exist, you will be prompted to create it. - + If there is no `YAML` folder in the path, the converted file will be placed in the same folder. -# Credits +## Credits + +Elements of these scripts come from: -Elements of these scripts come from: -* [chaimleib/ppl](https://github.com/chaimleib/ppl) -* [asciidoctor/sublimetext-asciidoc](https://github.com/asciidoctor/sublimetext-asciidoc) +- [chaimleib/ppl](https://github.com/chaimleib/ppl) +- [asciidoctor/sublimetext-asciidoc](https://github.com/asciidoctor/sublimetext-asciidoc) diff --git a/pkg/plistyamlplist/build-info.plist b/pkg/plistyamlplist/build-info.plist index 4556010..a44453c 100644 --- a/pkg/plistyamlplist/build-info.plist +++ b/pkg/plistyamlplist/build-info.plist @@ -17,6 +17,6 @@ suppress_bundle_relocation version - 0.2 + 0.3 diff --git a/plistyamlplist.py b/plistyamlplist.py index 7316ab6..ac571b2 100755 --- a/plistyamlplist.py +++ b/plistyamlplist.py @@ -12,7 +12,9 @@ """ import sys -import os.path +import os +import glob + from plistyamlplist_lib.plist_yaml import plist_yaml from plistyamlplist_lib.yaml_plist import yaml_plist @@ -53,12 +55,12 @@ def check_for_yaml_folder(check_path): e.g. /path/to/YAML/folder/subfolder/my.plist.yaml ==> /path/to/folder/subfolder/my.plist Note there is no reverse option at this time""" check_abspath = os.path.abspath(check_path) - if 'YAML' in check_abspath: - print('YAML folder exists : {}'.format(check_abspath)) - top_path, base_path = check_abspath.split('YAML/') + if "YAML" in check_abspath: + print("YAML folder exists : {}".format(check_abspath)) + top_path, base_path = check_abspath.split("YAML/") out_path = os.path.dirname(os.path.join(top_path, base_path)) if os.path.exists(out_path): - print('Path exists : {}'.format(out_path)) + print("Path exists : {}".format(out_path)) return out_path else: print("Path does not exist : {}".format(out_path)) @@ -66,6 +68,26 @@ def check_for_yaml_folder(check_path): exit(1) +def get_out_path(in_path): + """determine the out_path when none given""" + if in_path.endswith(".yaml") or in_path.endswith(".yml"): + out_dir = check_for_yaml_folder(in_path) + if out_dir: + filename, _ = os.path.splitext(os.path.basename(in_path)) + out_path = os.path.join(out_dir, filename) + else: + filename, _ = os.path.splitext(os.path.abspath(in_path)) + out_path = filename + else: + if check_if_plist(in_path): + out_path = "{}.yaml".format(in_path) + else: + print("\nERROR: File is neither PLIST nor YAML format.\n") + usage() + exit(1) + return out_path + + def main(): """get the command line inputs if running this script directly.""" if len(sys.argv) < 2: @@ -73,38 +95,37 @@ def main(): exit(1) in_path = sys.argv[1] - try: - sys.argv[2] - except IndexError: - if in_path.endswith(".yaml") or in_path.endswith(".yml"): - out_dir = check_for_yaml_folder(in_path) - if out_dir: - filename, file_extension = os.path.splitext(os.path.basename(in_path)) - out_path = os.path.join(out_dir, filename) - else: - filename, file_extension = os.path.splitext(os.path.abspath(in_path)) - out_path = filename - else: - if check_if_plist(in_path): - out_path = "{}.yaml".format(in_path) - else: - print("\nERROR: File is neither PLIST nor YAML format.\n") - usage() - exit(1) - else: - out_path = sys.argv[2] # auto-determine which direction the conversion should go if in_path.endswith(".yaml"): - yaml_plist(in_path, out_path) + # allow for converting whole folders if a glob is provided + _, glob_files = os.path.split(in_path) + if "*" in glob_files: + glob_files = glob.glob(in_path) + for glob_file in glob_files: + out_path = get_out_path(glob_file) + yaml_plist(glob_file, out_path) + else: + try: + sys.argv[2] + except IndexError: + out_path = get_out_path(in_path) + else: + out_path = sys.argv[2] + yaml_plist(in_path, out_path) else: if check_if_plist(in_path): + try: + sys.argv[2] + except IndexError: + out_path = get_out_path(in_path) + else: + out_path = sys.argv[2] plist_yaml(in_path, out_path) else: print("\nERROR: Input File is neither PLIST nor YAML format.\n") usage() exit(1) - print("Wrote to : {}".format(out_path)) if __name__ == "__main__": diff --git a/plistyamlplist_lib/plist_yaml.py b/plistyamlplist_lib/plist_yaml.py index dc63b38..4f0796f 100755 --- a/plistyamlplist_lib/plist_yaml.py +++ b/plistyamlplist_lib/plist_yaml.py @@ -94,6 +94,7 @@ def plist_yaml(in_path, out_path): out_file = open(out_path, "w") out_file.writelines(output) + print("Wrote to : {}\n".format(out_path)) def main(): diff --git a/plistyamlplist_lib/yaml_plist.py b/plistyamlplist_lib/yaml_plist.py index d944c9b..8868ee1 100755 --- a/plistyamlplist_lib/yaml_plist.py +++ b/plistyamlplist_lib/yaml_plist.py @@ -17,27 +17,38 @@ import yaml import os.path -from plistlib import writePlistToString - +try: # python 3 + from plistlib import dumps as write_plist +except ImportError: # python 2 + from plistlib import writePlistToString as write_plist import yaml def convert(data): """Do the conversion.""" - lines = writePlistToString(data).splitlines() + lines = write_plist(data).splitlines() lines.append("") return "\n".join(lines) def yaml_plist(in_path, out_path): """Convert yaml to plist.""" - in_file = open(in_path, "r") - out_file = open(out_path, "w") + try: + in_file = open(in_path, "r") + except IOError: + print("ERROR: {} not found".format(in_path)) + return + try: + out_file = open(out_path, "w") + except IOError: + print("ERROR: could not create {} ".format(out_path)) + return input_data = yaml.safe_load(in_file) output = convert(input_data) out_file.writelines(output) + print("Wrote to : {}\n".format(out_path)) def main(): @@ -50,8 +61,8 @@ def main(): try: sys.argv[2] except Exception as e: - if in_path.endswith('.yaml'): - filename, file_extension = os.path.splitext(in_path) + if in_path.endswith(".yaml"): + filename, _ = os.path.splitext(in_path) out_path = filename else: print("Usage: yaml_plist.py ")