Skip to content

Commit

Permalink
Add glob ability to convert whole directories from yaml to plist
Browse files Browse the repository at this point in the history
  • Loading branch information
Graham R Pugh committed Sep 14, 2020
1 parent 09dca7e commit 690847f
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 58 deletions.
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
48 changes: 27 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.

Expand All @@ -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:

Expand All @@ -21,6 +20,8 @@ plistyamlplist -h
Usage: ./plistyamlplist.py <input-file> [<output-file>]
```

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
Expand All @@ -42,48 +43,53 @@ Usage: yaml-plist.py <input-file> [<output-file>]
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)
2 changes: 1 addition & 1 deletion pkg/plistyamlplist/build-info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
<key>suppress_bundle_relocation</key>
<true/>
<key>version</key>
<string>0.2</string>
<string>0.3</string>
</dict>
</plist>
75 changes: 48 additions & 27 deletions plistyamlplist.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -53,58 +55,77 @@ 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))
print("Please create this folder and try again")
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:
usage()
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__":
Expand Down
1 change: 1 addition & 0 deletions plistyamlplist_lib/plist_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down
25 changes: 18 additions & 7 deletions plistyamlplist_lib/yaml_plist.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand All @@ -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 <input-file> <output-file>")
Expand Down

0 comments on commit 690847f

Please sign in to comment.