Package: java-manifest
java-manifest-pyEncode/decode Java'sMETA-INF/MANIFEST.MFin Python.InstallationTo install the latest release on PyPI, run:$pipinstalljava-manifestUsageA MANIFEST is represented by a list of dictionaries, where each dictionary
corresponds to an empty-line delimited section of the MANIFEST and each
dictionary hasstrkeys and eitherstrorboolvalues.java_manifest.loadstakes a string containing MANIFEST-formatted data and
returns a list of dictionaries, where each dictionary is a section in the
MANIFEST.java_manifest.loaddoes the same, using anytyping.TextIOreadable object.>>>importjava_manifest>>>manifest_str="""... Name: README-Example-1... Long-Line: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...... Name: README-Example-2... Foo: Bar... """>>>manifest=java_manifest.loads(manifest_str)>>>print(manifest)[{'Name':'README-Example-1','Long-Line':'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'},{'Name':'README-Example-2','Foo':'Bar'}]Similarly,java_manifest.dumpsreturns a string of MANIFEST-formatted data
from a list of dictionaries, where each dictionary is a section in the
MANIFEST.java_manifest.dumpdoes the same, writing into anytyping.TextIOwritable object.>>>importjava_manifest>>>manifest=[...{..."Name":"README-Example",..."Some-Str":"Some random string",...},...]>>>manifest_str=java_manifest.dumps(manifest)>>>print(manifest_str)Name:README-ExampleSome-Str:Somerandomstring<BLANKLINE>There is also afrom_jarfunction that finds theMETA-INF/MANIFEST.MFfile
within the jar andjava_manifest.loads that.>>>importjava_manifest>>>manifest=java_manifest.from_jar("test_files/simple.jar")Custom Encoders/DecodersBecause Java's manifest file format doesn't deal with structured values within
a section, specific uses of the format create ad-hoc encoding/decoding rules
that can convert some structured data into a basic string so it can be encoded
into a manifest and vice versa. Theencoderanddecoderarguments for
dumping and loading respectively are responsible for handling this. An encoder
and decoder both take in a key-value pair. However, an encoder receives
potentially structured data as the value and returns plain string, while a
decode receives string values and returns potentially structured data.As we have already see, the default encoder and decoder does no transformation
and prevents you from attempting to dump non-string data.>>>importjava_manifest>>>print(java_manifest.dumps([{"foo":"bar"}]))foo:bar>>>print(java_manifest.dumps([{"int":1}]))Traceback(mostrecentcalllast):...ValueError:key'int'hastype<class'int'> value, expected strYou can however describe more custom encoders that support for example lists of
strings.>>>defencode(key,val):...ifisinstance(val,list):...return",".join(val)...returnval>>>print(java_manifest.dumps([{"foo":"bar","names":["alice","bob","charlie"]}],encoder=encode))foo:barnames:alice,bob,charlie<BLANKLINE>Similarly for custom decoders.>>>importjava_manifest>>>defdecode(key,val):...# In reality you'd probably want to target only specific keys, to avoid...# messing up random strings containing commas. This is just an example....vals=val.split(",")...iflen(vals)==1:...returnval...else:...returnvals>>>manifest=java_manifest.loads("foo: bar\r\nnames: alice,bob,charlie",decoder=decode)>>>print(manifest)[{'foo':'bar','names':['alice','bob','charlie']}]