So lately I’ve been doing quite a bit of Java related stuff. I’ve learned a lot. Mostly about how much better C# is, to be honest. But this isn’t about that.
Most Java work get’s packaged into a Jar file. a Java .jar file is really just a .zip file with a .jar extension- so points to Sun Microsystems for coming up with a package format that isn’t something completely new. I found myself having a bit of an annoying time of it, however- from what I can tell there is no “package this stuff into a jar” option in Eclipse. Since the zip format is so widely workable, I decided to create a quick script to package all the appropriate files into a .jar. This saves me selecting everything in the appropriate .bin folder,unselecting the hidden history folder created by my text editor and anything else I don’t want included, etc.
I’m aiming for simplicity here. A script in the bin folder is good enough for me. I encountered quite a few problems creating the script and ended up giving up on it for a while, but I got back to it today and decided to get it working. Here is the script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#!/usr/bin/env python import sys,os,zipfile def zipdir(path,rootfolder, zip): for root, dirs, files in os.walk(path,topdown=True): print(root,dirs,files) dirs[:] = [d for d in dirs if not (d.startswith(".") or d.startswith("_"))] for dir in dirs: zipdir(os.path.join(root,dir),os.path.join(rootfolder,dir),zip) for file in files: if not (file.lower().endswith(("jar","zip")) or file.startswith(".") or file.startswith("_") or file==scriptfile()): print("adding file:" + file) #print(os.path.join(dirs[0],file)) zip.write(os.path.join(root, file),os.path.join(rootfolder,file)) else: print "Skipping file:" + file break def scriptfile(): dname,fname = os.path.split(os.path.abspath(sys.argv[0])) return fname if __name__ == '__main__': print("main file:" + __file__) zip = zipfile.ZipFile('packaged.jar', 'w') usefolder = os.path.dirname(os.path.realpath(sys.argv[0])) zipdir(usefolder,"", zip) zip.close() |
Python is quite a powerful language. I particularly like the use of tuples directly in the language; the os.walk() function is a “generator”; each iteration the root variable is set to the root of the search, dirs is filled with all the directories in the current iterating folder, and files is filled with the files. I change the dirs value here and filter out those that start with “.” (which could be, say, a git repo) as well as filtering out those starting with an underscore. The cool thing is that since I specified topdown=True in the call to os.Walk, I can remove directories and os.walk will not go into those directories, so I don’t need additional checks to make sure we aren’t in one of the excluded folders. Then the function calls itself for each directory, and finally it adds all the files in the currently walked folder to the zipfile. It performs similar checks to avoid adding undesired files; it doesn’t add files that start with a period, underscore, or are the same name as the scriptfile itself (which could cause issues, arguably, but with Java I’m unlikely to have a file called “prepare.py” anywhere in the tree that I want to be included). Then it breaks. Works quite well; the zip is created with only the files I want and everybody is happy. I was considering adding extra functionality to it, but decided that it’s possible to over-think it; I just want something simple, and I don’t need- for example- special handling of .gitignore folders to actually exclude files that are specified from the package. Not yet, anyway.
Naturally this script can really be run anywhere; just paste it in a folder and run it, and you’ve got a zip with everything in that folder compressed. could be useful for compressing source trees. I thought I’d share it here because I found it useful.
Have something to say about this post? Comment!
One thought on “Filling your Jars with Python”
thx