Skip to content

Instantly share code, notes, and snippets.

Created May 11, 2018 13:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joachimesque/49e5d14f089ad9518e72fcb86c3ae562 to your computer and use it in GitHub Desktop.
Save joachimesque/49e5d14f089ad9518e72fcb86c3ae562 to your computer and use it in GitHub Desktop.
WebExtension build script
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# based on
# usage: [-h] [-c] [-w] [-d DIRECTORY]
# Build your extension file.
# optional arguments:
# -h, --help show this help message and exit
# -c, --console Open developer consoles in your browser
# -w, --window Open file browser window with zip selected
# -d DIRECTORY, --directory DIRECTORY
# The webextensions dir if not current dir
from __future__ import unicode_literals
import os
import sys
import json
import zipfile
import argparse
import platform
import webbrowser
import subprocess
def query_yes_no(question, default="yes"):
"""Ask a yes/no question via raw_input() and return their answer.
"question" is a string that is presented to the user.
"default" is the presumed answer if the user just hits <Enter>.
It must be "yes" (the default), "no" or None (meaning
an answer is required of the user).
The "answer" return value is True for "yes" or False for "no".
valid = {"yes": True, "y": True, "ye": True,
"no": False, "n": False}
if default is None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)
choice = input().lower()
if default is not None and choice == '':
return valid[default]
elif choice in valid:
return valid[choice]
sys.stdout.write("Please respond with 'yes' or 'no' "
"(or 'y' or 'n').\n")
def console_open():
# webbrowser.get('opera').open_new_tab('')
def open_file(file, path):
if platform.system() == "Windows":
subprocess.Popen(["explorer", "/select,", file])
elif platform.system() == "Darwin":
subprocess.Popen(["open", "--reveal", file])
subprocess.Popen(["xdg-open", path])
def main():
parser = argparse.ArgumentParser(description='Build your extension file.')
parser.add_argument('-c','--console', dest='console', action='store_true',
help='Open developer consoles in your browser')
parser.add_argument('-w','--window', dest='window', action='store_true',
help='Open file browser window with zip selected')
parser.add_argument('-d','--directory', dest='directory', action='store',
help='The webextensions dir if not current dir')
args = parser.parse_args()
if os.path.exists(os.path.realpath(
self_file = ''
folder = os.path.realpath(
# name = folder
quit("Supplied dir does not exist. Terminating.")
# because __file__ changes if you run like py or ./
self_file = os.path.basename(__file__)
folder = os.path.dirname(os.path.realpath(self_file))
# name = os.path.basename(os.path.normpath(folder))
manifest_path = os.path.join(folder,"manifest.json")
if os.path.isfile(manifest_path):
with open(manifest_path, "r") as manifest_file:
json_data = json.load(manifest_file)
quit("Manifest file `manifest.json` was not found. Terminating.")
version = json_data['version']
output = '{}-{}.zip'.format(folder,version)
files = []
exclude_prefixes = ('__', '.') # exclusion prefixes
for (dirpath, dirnames, filenames) in os.walk(folder):
# exclude all files and dirs starting with exclude_prefixes
filenames = [f for f in filenames if not f[0] == '.' and not f == self_file]
dirnames[:] = [d for d in dirnames if not d.startswith(exclude_prefixes)]
for filename in filenames:
path = os.path.relpath(os.path.join(dirpath, filename))
if path != output and path != self_file:
with zipfile.ZipFile(output, 'w') as output_file:
for file in files:
output_file.write(file, )
print('Built {} files to {}'.format(len(files), output))
if args.console:
elif query_yes_no("Open developer consoles?", "no"):
if args.window:
open_file(output, folder)
elif query_yes_no("Open directory in system window?", "no"):
open_file(output, folder)
if __name__ == '__main__':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment