Skip to content

Commit

Permalink
Merge branch 'homebysix_patch'
Browse files Browse the repository at this point in the history
  • Loading branch information
Graham R Pugh committed Mar 6, 2020
2 parents c4a4b1e + 3a852ea commit de24609
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 66 deletions.
2 changes: 1 addition & 1 deletion .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
hooks:
- id: check-added-large-files
args: ['--maxkb=100']
- id: check-ast
- id: check-byte-order-marker
- id: check-case-conflict
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: end-of-file-fixer
- id: fix-encoding-pragma
- id: mixed-line-ending
- id: trailing-whitespace
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ Usage: yaml-plist.py <input-file> [<output-file>]

**Notes:**

1. With `plistyamlplist.py`, if you do not specify an `output-file` value, the script determines if the `input-file` is
a plist or yaml file. If a plist file, the `input-file` name will be appended with `.yaml` for the output file. If a
1. With `plistyamlplist.py`, if you do not specify an `output-file` value, the script determines if the `input-file` is
a plist or yaml file. If a plist file, the `input-file` name will be appended with `.yaml` for the output file. If a
yaml file, the output file name will be the `input-file` name with `.yaml` removed.
2. With `plist_yaml.py`, if you do not specify an `output-file` value, the `input-file` name will be appended with
2. With `plist_yaml.py`, if you do not specify an `output-file` value, the `input-file` name will be appended with
`.yaml` for the output file.
3. With `yaml_plist.py`, if you do not specify an `output-file` value, and the `input-file` name ends with `.yaml`,
3. With `yaml_plist.py`, if you do not specify an `output-file` value, and the `input-file` name ends with `.yaml`,
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`.

Expand Down Expand Up @@ -73,8 +73,8 @@ If you have a folder named `YAML` in your path, and you do not supply a destinat
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
If the folder `/Users/myuser/gitrepo/product` exists, the converted file will be created/overwritten at:

If the folder `/Users/myuser/gitrepo/product` exists, the converted file will be created/overwritten at:

/Users/myuser/gitrepo/product/com.something.plist

Expand Down
40 changes: 22 additions & 18 deletions plistyamlplist.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
If this script is run directly, it takes an input file and an output file from
the command line. It detects if the input file is a YAML or a PLIST file,
"""If this script is run directly, it takes an input file and an output file
from the command line. It detects if the input file is a YAML or a PLIST file,
and converts to the other format:
plistyamlplist.py <input-file> <output-file>
Expand All @@ -19,22 +19,26 @@


def usage():
"""print help"""
"""print help."""
print("Usage: plistyamlplist.py <input-file> <output-file>\n")
print("If <input-file> is a PLIST and <output-file> is omitted,\n"
"<input-file> is converted to <input-file>.yaml\n")
print("If <input-file> ends in .yaml or .yml and <output-file> is omitted,\n"
"<input-file>.yaml is converted to PLIST format with name <input-file>\n")
print(
"If <input-file> is a PLIST and <output-file> is omitted,\n"
"<input-file> is converted to <input-file>.yaml\n"
)
print(
"If <input-file> ends in .yaml or .yml and <output-file> is omitted,\n"
"<input-file>.yaml is converted to PLIST format with name <input-file>\n"
)


def check_if_plist(in_path):
"""rather than restrict by filename, check if the file is a plist by reading
the second line of the file for the PLIST declaration"""
"""rather than restrict by filename, check if the file is a plist by
reading the second line of the file for the PLIST declaration."""
with open(in_path) as fp:
for i, line in enumerate(fp):
if i == 1:
# print line
if line.find('PLIST 1.0') == -1:
if line.find("PLIST 1.0") == -1:
is_plist = False
else:
is_plist = True
Expand All @@ -57,13 +61,13 @@ def check_for_yaml_folder(check_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')
print("Path does not exist : {}".format(out_path))
print("Please create this folder and try again")
exit(1)


def main():
"""get the command line inputs if running this script directly"""
"""get the command line inputs if running this script directly."""
if len(sys.argv) < 2:
usage()
exit(1)
Expand All @@ -72,7 +76,7 @@ def main():
try:
sys.argv[2]
except IndexError:
if in_path.endswith('.yaml') or in_path.endswith('.yml'):
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))
Expand All @@ -91,7 +95,7 @@ def main():
out_path = sys.argv[2]

# auto-determine which direction the conversion should go
if in_path.endswith('.yaml'):
if in_path.endswith(".yaml"):
yaml_plist(in_path, out_path)
else:
if check_if_plist(in_path):
Expand All @@ -100,8 +104,8 @@ def main():
print("\nERROR: Input File is neither PLIST nor YAML format.\n")
usage()
exit(1)
print('Wrote to : {}'.format(out_path))
print("Wrote to : {}".format(out_path))


if __name__ == '__main__':
if __name__ == "__main__":
main()
95 changes: 69 additions & 26 deletions plistyamlplist_lib/plist_yaml.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
If this script is run directly, it takes an input file and an output file from
the command line. The input file must be in PLIST format.
The output file will be in YAML format:
"""If this script is run directly, it takes an input file and an output file
from the command line. The input file must be in PLIST format. The output file
will be in YAML format:
plist_yaml.py <input-file> <output-file>
Expand All @@ -12,49 +12,92 @@
"""

import sys
from collections import OrderedDict

try:
from plistlib import Data # Python 3
from plistlib import load as load_plist
except ImportError:
from plistlib import Data # Python 2
from plistlib import readPlist as load_plist

import yaml
from plistlib import readPlist, Data


def normalize_types(input):
"""
This allows YAML and JSON to store Data fields as strings. However, this
operation is irreversible. Only use if read-only access to the plist is
required.
def represent_ordereddict(dumper, data):
value = []

for item_key, item_value in data.items():
node_key = dumper.represent_data(item_key)
node_value = dumper.represent_data(item_value)

value.append((node_key, node_value))

return yaml.nodes.MappingNode(u"tag:yaml.org,2002:map", value)


def normalize_types(input_data):
"""This allows YAML and JSON to store Data fields as strings.
However, this operation is irreversible. Only use if read-only
access to the plist is required.
"""
if isinstance(input, Data): return input.data
if isinstance(input, list):
if isinstance(input_data, Data):
return input_data.data
if isinstance(input_data, list):
retval = []
for child in input:
for child in input_data:
retval.append(normalize_types(child))
return retval
if isinstance(input, dict):
if isinstance(input_data, dict):
retval = {}
for key, child in input.iteritems():
retval[key] = normalize_types(child)
for key in input_data:
retval[key] = normalize_types(input_data[key])
return retval
return input
return input_data


def sort_autopkg_processes(recipe):
"""If input is an AutoPkg recipe, adjust the processor dictionaries such
that the Arguments key is ordered last.
This usually puts the Processor key first, which makes the process
list more human-readable.
"""
if "Process" in recipe:
process = recipe["Process"]
new_process = []
for processor in process:
if "Arguments" in processor:
processor = OrderedDict(processor)
processor.move_to_end("Arguments")
new_process.append(processor)
recipe["Process"] = new_process
return recipe


def convert(xml):
"""Do the conversion"""
return yaml.dump(xml, width=float('inf'), default_flow_style=False)
"""Do the conversion."""
yaml.add_representer(OrderedDict, represent_ordereddict)
return yaml.dump(xml, width=float("inf"), default_flow_style=False)


def plist_yaml(in_path, out_path):
"""Convert plist to yaml"""
in_file = open(in_path, 'r')
input = readPlist(in_file)
"""Convert plist to yaml."""
with open(in_path, "rb") as in_file:
input_data = load_plist(in_file)

normalized = normalize_types(input)
normalized = normalize_types(input_data)
if sys.version_info.major == 3 and in_path.endswith((".recipe", ".recipe.plist")):
normalized = sort_autopkg_processes(normalized)
output = convert(normalized)

out_file = open(out_path, 'w')
out_file = open(out_path, "w")
out_file.writelines(output)


def main():
"""Get the command line inputs if running this script directly"""
"""Get the command line inputs if running this script directly."""
if len(sys.argv) < 2:
print("Usage: plist_yaml.py <input-file> <output-file>")
sys.exit(1)
Expand All @@ -71,5 +114,5 @@ def main():
plist_yaml(in_path, out_path)


if __name__ == '__main__':
if __name__ == "__main__":
main()
32 changes: 17 additions & 15 deletions plistyamlplist_lib/yaml_plist.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
If this script is run directly, it takes an input file and an output file from
the command lineThe input file must be in YAML format.
The output file will be in PLIST format:
"""If this script is run directly, it takes an input file and an output file
from the command lineThe input file must be in YAML format. The output file
will be in PLIST format:
yaml_plist.py <input-file> <output-file>
Expand All @@ -19,27 +19,29 @@

from plistlib import writePlistToString

import yaml


def convert(yaml):
"""Do the conversion"""
lines = writePlistToString(yaml).splitlines()
lines.append('')
def convert(data):
"""Do the conversion."""
lines = writePlistToString(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')
"""Convert yaml to plist."""
in_file = open(in_path, "r")
out_file = open(out_path, "w")

input = yaml.safe_load(in_file)
output = convert(input)
input_data = yaml.safe_load(in_file)
output = convert(input_data)

out_file.writelines(output)


def main():
"""Get the command line inputs if running this script directly"""
"""Get the command line inputs if running this script directly."""
if len(sys.argv) < 2:
print("Usage: yaml_plist.py <input-file> <output-file>")
sys.exit(1)
Expand All @@ -60,5 +62,5 @@ def main():
yaml_plist(in_path, out_path)


if __name__ == '__main__':
if __name__ == "__main__":
main()

0 comments on commit de24609

Please sign in to comment.