mirror of https://github.com/gorhill/uBlock.git
Building extension files
Adds possibility to build extension files (Chrome and Safari) from command line. To run from the project directory: python tools/build.py [meta] If the optional `meta` argument is set, then only the manifest and language files are uptated. Without that everything is being built (extension files too) into the `dist/build/version_number` folder. For Chrome there will be two files, a crx, and a .zip file which includes the key.pem private key (so this must not be shared, it's just a bit help for publishing it to the Chrome Web Store). Beside the extension files, update-files are generated too (for self hosting - Safari needs it).
This commit is contained in:
parent
4bf6664d6b
commit
0d9d285608
|
@ -1,29 +1,29 @@
|
||||||
{
|
{
|
||||||
"name": "µBlock",
|
"name": "µBlock",
|
||||||
"clean_name": "ublock",
|
"clean_name": "uBlock",
|
||||||
"url": "https://github.com/gorhill/uBlock",
|
"url": "https://github.com/gorhill/uBlock",
|
||||||
"author": "Raymond Hill",
|
"author": "Raymond Hill",
|
||||||
"author_email": "rhill@raymondhill.net",
|
"author_email": "rhill@raymondhill.net",
|
||||||
"version": "0.7.0.9",
|
"version": "0.7.0.10",
|
||||||
"def_lang": "en",
|
"def_lang": "en",
|
||||||
"vendors": {
|
"vendors": {
|
||||||
"crx": {
|
"crx": {
|
||||||
"app_id": "cjpalhdlnbpafiamejdnhcphjbkeiagm",
|
"app_id": "cjpalhdlnbpafiamejdnhcphjbkeiagm",
|
||||||
"manifest": "manifest.json",
|
"manifest": "manifest.json",
|
||||||
"locales": "_locales",
|
"locales": "_locales",
|
||||||
"file_ext": ".crx",
|
"file_ext": ".crx",
|
||||||
"cert_key": "../meta/crx/key.pem"
|
"private_key": "./meta/crx/key.pem"
|
||||||
},
|
},
|
||||||
"safariextz": {
|
"safariextz": {
|
||||||
"app_id": "net.gorhill.uBlock",
|
"app_id": "net.gorhill.uBlock",
|
||||||
"manifest": {
|
"manifest": {
|
||||||
"Info": "Info.plist",
|
"Info": "Info.plist",
|
||||||
"Settings": "Settings.plist"
|
"Settings": "Settings.plist"
|
||||||
},
|
},
|
||||||
"file_ext": ".safariextz",
|
"file_ext": ".safariextz",
|
||||||
"developer_identifier": "",
|
"developer_identifier": "",
|
||||||
"cert_dir": "../meta/safariextz/certs/",
|
"cert_dir": "./meta/safariextz/certs/",
|
||||||
"cert_key": "../meta/safariextz/certs/key.pem"
|
"private_key": "./meta/safariextz/key.pem"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<gupdate xmlns="http://www.google.com/update2/response" protocol="2.0">
|
<gupdate xmlns="http://www.google.com/update2/response" protocol="2.0">
|
||||||
<app appid="{app_id}">
|
<app appid="{app_id}">
|
||||||
<updatecheck codebase="{url}{name}.crx" version="{version}"/>
|
<updatecheck codebase="{url}/{name}.crx" version="{version}"/>
|
||||||
</app>
|
</app>
|
||||||
</gupdate>
|
</gupdate>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>{build_number}</string>
|
<string>{build_number}</string>
|
||||||
<key>URL</key>
|
<key>URL</key>
|
||||||
<string>{url}{name}.safariextz</string>
|
<string>{url}/{name}.safariextz</string>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.7.0.9</string>
|
<string>0.7.0.10</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1455425</string>
|
<string>1456132</string>
|
||||||
<key>Chrome</key>
|
<key>Chrome</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>Database Quota</key>
|
<key>Database Quota</key>
|
||||||
|
|
|
@ -8,7 +8,7 @@ div > p:last-child {
|
||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
width: 48em;
|
width: 48em;
|
||||||
height: 40em;
|
height: 40em;
|
||||||
white-space: nowrap;
|
white-space: pre;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
#whitelist.bad {
|
#whitelist.bad {
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
|
|
||||||
uDom.onLoad(function() {
|
uDom.onLoad(function() {
|
||||||
uDom('[data-i18n]').forEach(function(elem) {
|
uDom('[data-i18n]').forEach(function(elem) {
|
||||||
elem.html(vAPI.i18n.getMessage(elem.attr('data-i18n')));
|
elem.html(vAPI.i18n(elem.attr('data-i18n')));
|
||||||
});
|
});
|
||||||
uDom('[title]').forEach(function(elem) {
|
uDom('[title]').forEach(function(elem) {
|
||||||
var title = vAPI.i18n.getMessage(elem.attr('title'));
|
var title = vAPI.i18n(elem.attr('title'));
|
||||||
if ( title ) {
|
if ( title ) {
|
||||||
elem.attr('title', title);
|
elem.attr('title', title);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ uDom.onLoad(function() {
|
||||||
uDom('[data-i18n-tip]').forEach(function(elem) {
|
uDom('[data-i18n-tip]').forEach(function(elem) {
|
||||||
elem.attr(
|
elem.attr(
|
||||||
'data-tip',
|
'data-tip',
|
||||||
vAPI.i18n.getMessage(elem.attr('data-i18n-tip')).replace(/<br>/g, '')
|
vAPI.i18n(elem.attr('data-i18n-tip')).replace(/<br>/g, '')
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,6 @@ self.vAPI = self.vAPI || {};
|
||||||
|
|
||||||
vAPI.app = {
|
vAPI.app = {
|
||||||
/**/name: 'µBlock',
|
/**/name: 'µBlock',
|
||||||
/**/version: '0.7.0.9',
|
/**/version: '0.7.0.10',
|
||||||
/**/url: 'https://github.com/gorhill/uBlock',
|
/**/url: 'https://github.com/gorhill/uBlock',
|
||||||
};
|
};
|
|
@ -1,3 +1,4 @@
|
||||||
|
// » header
|
||||||
/* global SafariBrowserTab, Services, XPCOMUtils */
|
/* global SafariBrowserTab, Services, XPCOMUtils */
|
||||||
// for background page only
|
// for background page only
|
||||||
|
|
||||||
|
@ -5,8 +6,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
self.vAPI = self.vAPI || {};
|
self.vAPI = self.vAPI || {};
|
||||||
|
// «
|
||||||
|
|
||||||
if (self.chrome) {
|
if (self.chrome) {
|
||||||
|
// » crx
|
||||||
var chrome = self.chrome;
|
var chrome = self.chrome;
|
||||||
|
|
||||||
vAPI.chrome = true;
|
vAPI.chrome = true;
|
||||||
|
@ -272,7 +275,9 @@ if (self.chrome) {
|
||||||
chrome.contextMenus.remove(this.menuId);
|
chrome.contextMenus.remove(this.menuId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// «
|
||||||
} else if (self.safari) {
|
} else if (self.safari) {
|
||||||
|
// » safariextz
|
||||||
vAPI.safari = true;
|
vAPI.safari = true;
|
||||||
|
|
||||||
// addContentScriptFromURL allows whitelisting,
|
// addContentScriptFromURL allows whitelisting,
|
||||||
|
@ -888,9 +893,13 @@ if (self.chrome) {
|
||||||
this.onContextMenuCommand = null;
|
this.onContextMenuCommand = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// «
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// » footer
|
||||||
|
|
||||||
if (!self.chrome) {
|
if (!self.chrome) {
|
||||||
self.chrome = { runtime: { lastError: null } };
|
self.chrome = { runtime: { lastError: null } };
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
// «
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// » header
|
||||||
/* global addMessageListener, removeMessageListener, sendAsyncMessage */
|
/* global addMessageListener, removeMessageListener, sendAsyncMessage */
|
||||||
// for non background pages
|
// for non background pages
|
||||||
|
|
||||||
|
@ -51,8 +52,10 @@ var messagingConnector = function(response) {
|
||||||
var uniqueId = function() {
|
var uniqueId = function() {
|
||||||
return parseInt(Math.random() * 1e10, 10).toString(36);
|
return parseInt(Math.random() * 1e10, 10).toString(36);
|
||||||
};
|
};
|
||||||
|
// «
|
||||||
|
|
||||||
if (self.chrome) {
|
if (self.chrome) {
|
||||||
|
// » crx
|
||||||
vAPI.chrome = true;
|
vAPI.chrome = true;
|
||||||
vAPI.messaging = {
|
vAPI.messaging = {
|
||||||
port: null,
|
port: null,
|
||||||
|
@ -60,15 +63,14 @@ if (self.chrome) {
|
||||||
listeners: {},
|
listeners: {},
|
||||||
requestId: 0,
|
requestId: 0,
|
||||||
connectorId: uniqueId(),
|
connectorId: uniqueId(),
|
||||||
connector: messagingConnector,
|
|
||||||
setup: function() {
|
setup: function() {
|
||||||
this.port = chrome.runtime.connect({name: this.connectorId});
|
this.port = chrome.runtime.connect({name: this.connectorId});
|
||||||
this.port.onMessage.addListener(this.connector);
|
this.port.onMessage.addListener(messagingConnector);
|
||||||
},
|
},
|
||||||
close: function() {
|
close: function() {
|
||||||
if (this.port) {
|
if (this.port) {
|
||||||
this.port.disconnect();
|
this.port.disconnect();
|
||||||
this.port.onMessage.removeListener(this.connector);
|
this.port.onMessage.removeListener(messagingConnector);
|
||||||
this.port = this.channels = this.listeners = this.connectorId = null;
|
this.port = this.channels = this.listeners = this.connectorId = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -105,7 +107,9 @@ if (self.chrome) {
|
||||||
return this.channels[channelName];
|
return this.channels[channelName];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// «
|
||||||
} else if (self.safari) {
|
} else if (self.safari) {
|
||||||
|
// » safariextz
|
||||||
vAPI.safari = true;
|
vAPI.safari = true;
|
||||||
|
|
||||||
// relevant?
|
// relevant?
|
||||||
|
@ -115,7 +119,6 @@ if (self.chrome) {
|
||||||
listeners: {},
|
listeners: {},
|
||||||
requestId: 0,
|
requestId: 0,
|
||||||
connectorId: uniqueId(),
|
connectorId: uniqueId(),
|
||||||
connector: messagingConnector,
|
|
||||||
setup: function() {
|
setup: function() {
|
||||||
this._connector = function(msg) {
|
this._connector = function(msg) {
|
||||||
// messages from the background script are sent to every frame,
|
// messages from the background script are sent to every frame,
|
||||||
|
@ -123,7 +126,7 @@ if (self.chrome) {
|
||||||
// what is meant for the current context
|
// what is meant for the current context
|
||||||
if (msg.name === vAPI.messaging.connectorId
|
if (msg.name === vAPI.messaging.connectorId
|
||||||
|| msg.name === 'broadcast') {
|
|| msg.name === 'broadcast') {
|
||||||
vAPI.messaging.connector(msg.message);
|
messagingConnector(msg.message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
safari.self.addEventListener('message', this._connector, false);
|
safari.self.addEventListener('message', this._connector, false);
|
||||||
|
@ -174,7 +177,7 @@ if (self.chrome) {
|
||||||
target: {
|
target: {
|
||||||
page: {
|
page: {
|
||||||
dispatchMessage: function(name, msg) {
|
dispatchMessage: function(name, msg) {
|
||||||
vAPI.messaging.connector(msg);
|
messagingConnector(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,6 +374,8 @@ if (self.chrome) {
|
||||||
url: window.location.href,
|
url: window.location.href,
|
||||||
type: 'main_frame'
|
type: 'main_frame'
|
||||||
});
|
});
|
||||||
|
// «
|
||||||
}
|
}
|
||||||
|
// » footer
|
||||||
})();
|
})();
|
||||||
|
// «
|
|
@ -1,3 +1,4 @@
|
||||||
|
// » header
|
||||||
// could be used for background and other extension pages
|
// could be used for background and other extension pages
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
@ -37,8 +38,10 @@ vAPI.download = function(details) {
|
||||||
messager.close();
|
messager.close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// «
|
||||||
|
|
||||||
if (self.chrome) {
|
if (self.chrome) {
|
||||||
|
// » crx
|
||||||
var chrome = self.chrome;
|
var chrome = self.chrome;
|
||||||
|
|
||||||
vAPI.getURL = function(path) {
|
vAPI.getURL = function(path) {
|
||||||
|
@ -50,7 +53,9 @@ if (self.chrome) {
|
||||||
};
|
};
|
||||||
|
|
||||||
setScriptDirection(vAPI.i18n('@@ui_locale'));
|
setScriptDirection(vAPI.i18n('@@ui_locale'));
|
||||||
|
// «
|
||||||
} else if (self.safari) {
|
} else if (self.safari) {
|
||||||
|
// » safariextz
|
||||||
vAPI.getURL = function(path) {
|
vAPI.getURL = function(path) {
|
||||||
return safari.extension.baseURI + path;
|
return safari.extension.baseURI + path;
|
||||||
};
|
};
|
||||||
|
@ -119,6 +124,8 @@ if (self.chrome) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// «
|
||||||
}
|
}
|
||||||
|
// » footer
|
||||||
})();
|
})();
|
||||||
|
// «
|
|
@ -58,10 +58,6 @@ exports.restart = function() {
|
||||||
if (vAPI.chrome) {
|
if (vAPI.chrome) {
|
||||||
chrome.runtime.reload();
|
chrome.runtime.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO? for cross-browser solution:
|
|
||||||
// window.location.reload();
|
|
||||||
// plus close all extension tabs
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"_": "en", "ar": 1, "cs": 1, "da": 1, "de": 1, "el": 1, "en": 1, "es": 1, "et": 1, "fi": 1, "fr": 1, "he": 1, "hr": 1, "hu": 1, "id": 1, "it": 1, "ja": 1, "nb": 1, "nl": 1, "pl": 1, "pt-BR": 1, "pt-PT": 1, "ro": 1, "ru": 1, "sv": 1, "tr": 1, "uk": 1, "vi": 1, "zh-CN": 1}
|
{"_": "en", "ar": 1, "cs": 1, "da": 1, "de": 1, "el": 1, "en": 1, "es": 1, "et": 1, "fi": 1, "fr": 1, "he": 1, "hi": 1, "hr": 1, "hu": 1, "id": 1, "it": 1, "ja": 1, "mr": 1, "nb": 1, "nl": 1, "pl": 1, "pt-BR": 1, "pt-PT": 1, "ro": 1, "ru": 1, "sv": 1, "tr": 1, "uk": 1, "vi": 1, "zh-CN": 1}
|
|
@ -58,4 +58,4 @@
|
||||||
"default_title": "µBlock",
|
"default_title": "µBlock",
|
||||||
"default_popup": "popup.html"
|
"default_popup": "popup.html"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,263 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
import glob
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
from time import strftime
|
||||||
|
from datetime import datetime
|
||||||
|
from shutil import which as iscmd, rmtree as rmt, copytree, copy, move
|
||||||
|
from collections import OrderedDict
|
||||||
|
from xml.sax.saxutils import escape
|
||||||
|
|
||||||
|
osp = os.path
|
||||||
|
pj = osp.join
|
||||||
|
|
||||||
|
os.chdir(pj(osp.split(osp.abspath(__file__))[0], '..'))
|
||||||
|
|
||||||
|
|
||||||
|
def rmtree(path):
|
||||||
|
if osp.exists(path):
|
||||||
|
rmt(path)
|
||||||
|
|
||||||
|
|
||||||
|
def mkdirs(path):
|
||||||
|
try:
|
||||||
|
os.makedirs(path)
|
||||||
|
finally:
|
||||||
|
return osp.exists(path)
|
||||||
|
|
||||||
|
|
||||||
|
def readfile(path, mode='rt'):
|
||||||
|
with open(path, mode) as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
|
||||||
|
src_dir = osp.abspath(pj('src'))
|
||||||
|
meta_dir = osp.abspath(pj('meta'))
|
||||||
|
tmp_dir = osp.abspath(pj('tmp'))
|
||||||
|
|
||||||
|
with open(pj(meta_dir, 'config.json'), encoding='utf-8') as f:
|
||||||
|
config = json.load(f)
|
||||||
|
|
||||||
|
vendors = config['vendors']
|
||||||
|
del config['vendors']
|
||||||
|
|
||||||
|
tmp = datetime.now() - datetime(year=datetime.today().year, month=1, day=1)
|
||||||
|
config['build_number'] = strftime('%y' + str(int(tmp.total_seconds() * 65535 / 31536000)).zfill(5))
|
||||||
|
|
||||||
|
descriptions = OrderedDict({})
|
||||||
|
source_locale_dir = pj('src', '_locales')
|
||||||
|
|
||||||
|
build_tmp = pj(tmp_dir, config['clean_name'])
|
||||||
|
build_dir = osp.abspath(pj('dist', 'build', config['version']))
|
||||||
|
|
||||||
|
|
||||||
|
# fill 'descriptions'
|
||||||
|
for alpha2 in os.listdir(source_locale_dir):
|
||||||
|
with open(pj(source_locale_dir, alpha2, 'messages.json'), encoding='utf-8') as f:
|
||||||
|
string_data = json.load(f, object_pairs_hook=OrderedDict)
|
||||||
|
|
||||||
|
descriptions[alpha2] = string_data['extShortDesc']['message']
|
||||||
|
|
||||||
|
|
||||||
|
# only needed for Safari
|
||||||
|
with open(pj(src_dir, 'locales.json'), 'wt', encoding='utf-8', newline='\n') as f:
|
||||||
|
tmp = {
|
||||||
|
'_': config['def_lang']
|
||||||
|
}
|
||||||
|
|
||||||
|
for alpha2 in descriptions:
|
||||||
|
tmp[alpha2] = 1
|
||||||
|
|
||||||
|
json.dump(tmp, f, sort_keys=True, ensure_ascii=False)
|
||||||
|
|
||||||
|
|
||||||
|
with open(pj(src_dir, 'js', 'vapi-appinfo.js'), 'r+t', encoding='utf-8', newline='\n') as f:
|
||||||
|
tmp = f.read()
|
||||||
|
f.seek(0)
|
||||||
|
|
||||||
|
f.write(re.sub(
|
||||||
|
r'/\*\*/([^:]+:).+',
|
||||||
|
lambda m: '/**/' + m.group(1) + " '" + config[m.group(1)[:-1]] + "',",
|
||||||
|
tmp
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
with open(pj(src_dir, vendors['crx']['manifest']), 'wt', encoding='utf-8', newline='\n') as f:
|
||||||
|
cf_content = readfile(pj(meta_dir, 'crx', vendors['crx']['manifest']))
|
||||||
|
|
||||||
|
f.write(
|
||||||
|
re.sub(r"\{(?=\W)|(?<=\W)\}", r'\g<0>\g<0>', cf_content).format(**config)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
with open(pj(src_dir, vendors['safariextz']['manifest']['Info']), 'wt', encoding='utf-8', newline='\n') as f:
|
||||||
|
config['app_id'] = vendors['safariextz']['app_id']
|
||||||
|
config['description'] = descriptions[config['def_lang']]
|
||||||
|
cf_content = readfile(pj(meta_dir, 'safariextz', vendors['safariextz']['manifest']['Info']))
|
||||||
|
f.write(cf_content.format(**config))
|
||||||
|
|
||||||
|
copy(pj(meta_dir, 'safariextz', vendors['safariextz']['manifest']['Settings']), pj(src_dir, vendors['safariextz']['manifest']['Settings']))
|
||||||
|
|
||||||
|
|
||||||
|
if 'meta' in sys.argv:
|
||||||
|
raise SystemExit('Metadata generated.')
|
||||||
|
|
||||||
|
|
||||||
|
rmtree(tmp_dir)
|
||||||
|
mkdirs(tmp_dir)
|
||||||
|
|
||||||
|
rmtree(build_dir)
|
||||||
|
mkdirs(build_dir)
|
||||||
|
|
||||||
|
# create update meta
|
||||||
|
for vendor, ext in {'crx': 'xml', 'safariextz': 'plist'}.items():
|
||||||
|
with open(pj(build_dir, 'update_' + vendor + '.' + ext), 'wt', encoding='utf-8', newline='\n') as f:
|
||||||
|
if vendor == 'safariextz':
|
||||||
|
config['developer_identifier'] = vendors[vendor]['developer_identifier']
|
||||||
|
|
||||||
|
config['app_id'] = vendors[vendor]['app_id']
|
||||||
|
cf_content = readfile(pj(meta_dir, vendor, 'update_' + vendor + '.' + ext))
|
||||||
|
f.write(cf_content.format(**config))
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
# separate vendor specific code
|
||||||
|
for vapijsfile in [pj(src_dir, 'js', 'vapi-' + jsfile + '.js') for jsfile in ['background', 'common', 'client']]:
|
||||||
|
vapijs = readfile(vapijsfile)
|
||||||
|
|
||||||
|
# "» name" is the start marker, "«" is the end marker
|
||||||
|
js_parts = re.findall(r'»\s*(\w+)\n([^«]+)//', vapijs)
|
||||||
|
|
||||||
|
if not js_parts:
|
||||||
|
continue
|
||||||
|
|
||||||
|
js_header = js_parts.pop(0)[1]
|
||||||
|
js_footer = js_parts.pop()[1]
|
||||||
|
|
||||||
|
for js in js_parts:
|
||||||
|
with open(pj(tmp_dir, js[0] + '_' + osp.basename(vapijsfile)), 'wt', encoding='utf-8', newline='\n') as f:
|
||||||
|
f.write(js_header)
|
||||||
|
f.write(re.sub(r'^ ', '', js[1], flags=re.M))
|
||||||
|
f.write(js_footer)
|
||||||
|
|
||||||
|
|
||||||
|
def move_vendor_specific_js(vendor):
|
||||||
|
for file in ['background', 'common', 'client']:
|
||||||
|
move(pj(tmp_dir, vendor + '_vapi-' + file + '.js'), pj(build_tmp, 'js', 'vapi-' + file + '.js'))
|
||||||
|
|
||||||
|
|
||||||
|
def copy_vendor_files(files):
|
||||||
|
for file in files:
|
||||||
|
path = pj(src_dir, file)
|
||||||
|
|
||||||
|
if osp.isdir(path):
|
||||||
|
copytree(path, pj(build_tmp, file), copy_function=copy)
|
||||||
|
else:
|
||||||
|
copy(path, pj(build_tmp, file))
|
||||||
|
|
||||||
|
|
||||||
|
def remove_vendor_files(files):
|
||||||
|
for file in files:
|
||||||
|
path = pj(build_tmp, file)
|
||||||
|
|
||||||
|
if osp.isdir(path):
|
||||||
|
rmtree(path)
|
||||||
|
else:
|
||||||
|
os.remove(path)
|
||||||
|
|
||||||
|
|
||||||
|
def norm_cygdrive(path):
|
||||||
|
return '/cygdrive/' + path[0] + path[2:].replace('\\', '/') if path[1] == ':' else path
|
||||||
|
|
||||||
|
|
||||||
|
mkdirs(build_tmp)
|
||||||
|
|
||||||
|
for file in glob.iglob(pj(src_dir, '*')):
|
||||||
|
basename = osp.basename(file)
|
||||||
|
|
||||||
|
if osp.isfile(file) and (file.endswith('.html') or basename == 'icon.png'):
|
||||||
|
copy(file, pj(build_tmp, basename))
|
||||||
|
elif osp.isdir(file) and basename not in ['_locales', 'locale']:
|
||||||
|
copytree(file, pj(build_tmp, basename), copy_function=copy)
|
||||||
|
|
||||||
|
os.remove(pj(build_tmp, 'js', 'sitepatch-safari.js'))
|
||||||
|
|
||||||
|
|
||||||
|
package_name = config['clean_name'] + '-' + config['version']
|
||||||
|
|
||||||
|
|
||||||
|
# Chrome
|
||||||
|
if not iscmd('7z'):
|
||||||
|
print('Cannot build for Chrome: `7z` command not found.')
|
||||||
|
else:
|
||||||
|
vendor_files = ['_locales', 'manifest.json']
|
||||||
|
|
||||||
|
move_vendor_specific_js('crx')
|
||||||
|
copy_vendor_files(vendor_files)
|
||||||
|
|
||||||
|
package = pj(build_dir, package_name + '.zip')
|
||||||
|
subprocess.call('7z a -r -tzip -mx=8 "' + norm_cygdrive(package) + '" "' + norm_cygdrive(pj(build_tmp, '*')) + '"', stdout=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
if osp.exists(vendors['crx']['private_key']):
|
||||||
|
if not iscmd('openssl'):
|
||||||
|
print('Cannot build for Chrome: `openssl` command not found.')
|
||||||
|
else:
|
||||||
|
# Convert the PEM key to DER (and extract the public form) for inclusion in the CRX header
|
||||||
|
derkey = subprocess.Popen([
|
||||||
|
'openssl', 'rsa', '-pubout',
|
||||||
|
'-inform', 'PEM',
|
||||||
|
'-outform', 'DER',
|
||||||
|
'-in', norm_cygdrive(vendors['crx']['private_key'])
|
||||||
|
], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.read()
|
||||||
|
# Sign the zip file with the private key in PEM format
|
||||||
|
signature = subprocess.Popen([
|
||||||
|
'openssl', 'sha1',
|
||||||
|
'-sign', norm_cygdrive(vendors['crx']['private_key']),
|
||||||
|
norm_cygdrive(package)
|
||||||
|
], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.read()
|
||||||
|
out = open(package.replace('.zip', vendors['crx']['file_ext']), "wb")
|
||||||
|
# Extension file magic number
|
||||||
|
out.write(bytes("Cr24\x02\x00\x00\x00", 'UTF-8') + len(derkey).to_bytes(4, 'little') + len(signature).to_bytes(4, 'little'))
|
||||||
|
out.write(derkey)
|
||||||
|
out.write(signature)
|
||||||
|
out.write(readfile(package, 'rb'))
|
||||||
|
out.close()
|
||||||
|
|
||||||
|
subprocess.call('7z a ' + norm_cygdrive(package) + ' ' + norm_cygdrive(osp.abspath(vendors['crx']['private_key'])), stdout=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
remove_vendor_files(vendor_files)
|
||||||
|
|
||||||
|
|
||||||
|
# Safari
|
||||||
|
if not iscmd('xar'):
|
||||||
|
print('Cannot build for Safari: `xar` command not found.')
|
||||||
|
elif osp.exists(vendors['safariextz']['cert_dir']):
|
||||||
|
vendor_files = ['_locales', 'Info.plist', 'Settings.plist', pj('js', 'sitepatch-safari.js')]
|
||||||
|
|
||||||
|
move_vendor_specific_js('safariextz')
|
||||||
|
copy_vendor_files(vendor_files)
|
||||||
|
|
||||||
|
build_tmp = move(build_tmp, pj(tmp_dir, config['clean_name'] + '.safariextension'))
|
||||||
|
|
||||||
|
# xar accepts only unix style directory separators
|
||||||
|
package = pj(build_dir, package_name + vendors['safariextz']['file_ext']).replace('\\', '/');
|
||||||
|
subprocess.call('xar -czf "' + package + '" --compression-args=9 --distribution --directory="' + osp.basename(tmp_dir) + '" ' + config['clean_name'] + '.safariextension', stderr=subprocess.DEVNULL)
|
||||||
|
subprocess.call('xar --sign -f "' + package + '" --digestinfo-to-sign sfr_digest.dat --sig-size 256 ' + ' '.join('--cert-loc="' + vendors['safariextz']['cert_dir'] + 'cert0{0}"'.format(i) for i in range(3)), stderr=subprocess.DEVNULL)
|
||||||
|
subprocess.call('openssl rsautl -sign -inkey ' + vendors['safariextz']['private_key'] + ' -in sfr_digest.dat -out sfr_sig.dat', stderr=subprocess.DEVNULL)
|
||||||
|
subprocess.call('xar --inject-sig sfr_sig.dat -f "' + package + '"', stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
os.remove('sfr_sig.dat')
|
||||||
|
os.remove('sfr_digest.dat')
|
||||||
|
|
||||||
|
build_tmp = move(build_tmp, pj(tmp_dir, config['clean_name']))
|
||||||
|
|
||||||
|
remove_vendor_files(vendor_files)
|
||||||
|
|
||||||
|
|
||||||
|
rmtree(tmp_dir)
|
||||||
|
|
||||||
|
print("Files ready @ " + build_dir)
|
|
@ -1,85 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
from time import strftime
|
|
||||||
from datetime import datetime
|
|
||||||
from shutil import rmtree as rmt, copy
|
|
||||||
from collections import OrderedDict
|
|
||||||
from xml.sax.saxutils import escape
|
|
||||||
|
|
||||||
osp = os.path
|
|
||||||
pj = osp.join
|
|
||||||
|
|
||||||
os.chdir('..')
|
|
||||||
|
|
||||||
|
|
||||||
def rmtree(path):
|
|
||||||
if osp.exists(path):
|
|
||||||
rmt(path)
|
|
||||||
|
|
||||||
|
|
||||||
def mkdirs(path):
|
|
||||||
try:
|
|
||||||
os.makedirs(path)
|
|
||||||
finally:
|
|
||||||
return osp.exists(path)
|
|
||||||
|
|
||||||
|
|
||||||
src_dir = pj('src')
|
|
||||||
meta_dir = pj('meta')
|
|
||||||
|
|
||||||
with open(pj(meta_dir, 'config.json'), encoding='utf-8') as f:
|
|
||||||
config = json.load(f)
|
|
||||||
|
|
||||||
vendors = config['vendors']
|
|
||||||
del config['vendors']
|
|
||||||
|
|
||||||
tmp = datetime.now() - datetime(year=datetime.today().year, month=1, day=1)
|
|
||||||
config['build_number'] = strftime('%y' + str(int(tmp.total_seconds() * 65535 / 31536000)).zfill(5))
|
|
||||||
|
|
||||||
descriptions = OrderedDict({})
|
|
||||||
|
|
||||||
|
|
||||||
with open(pj(src_dir, 'js', 'vapi-appinfo.js'), 'r+t', encoding='utf-8', newline='\n') as f:
|
|
||||||
tmp = f.read()
|
|
||||||
f.seek(0)
|
|
||||||
|
|
||||||
f.write(re.sub(
|
|
||||||
r'/\*\*/([^:]+:).+',
|
|
||||||
lambda m: '/**/' + m.group(1) + " '" + config[m.group(1)[:-1]] + "',",
|
|
||||||
tmp
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
with open(pj(src_dir, vendors['crx']['manifest']), 'wt', encoding='utf-8', newline='\n') as f:
|
|
||||||
with open(pj(meta_dir, 'crx', vendors['crx']['manifest']), 'r') as cf:
|
|
||||||
cf_content = cf.read()
|
|
||||||
|
|
||||||
f.write(
|
|
||||||
re.sub(r"\{(?=\W)|(?<=\W)\}", r'\g<0>\g<0>', cf_content).format(**config)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
with open(pj(src_dir, 'locales.json'), 'wt', encoding='utf-8', newline='\n') as f:
|
|
||||||
tmp = {
|
|
||||||
'_': config['def_lang']
|
|
||||||
}
|
|
||||||
|
|
||||||
for alpha2 in descriptions:
|
|
||||||
tmp[alpha2] = 1
|
|
||||||
|
|
||||||
json.dump(tmp, f, sort_keys=True, ensure_ascii=False)
|
|
||||||
|
|
||||||
|
|
||||||
with open(pj(src_dir, vendors['safariextz']['manifest']['Info']), 'wt', encoding='utf-8', newline='\n') as f:
|
|
||||||
config['app_id'] = vendors['safariextz']['app_id']
|
|
||||||
config['description'] = descriptions[config['def_lang']]
|
|
||||||
|
|
||||||
with open(pj(meta_dir, 'safariextz', vendors['safariextz']['manifest']['Info']), 'r') as cf:
|
|
||||||
cf_content = cf.read()
|
|
||||||
|
|
||||||
f.write(cf_content.format(**config))
|
|
||||||
|
|
||||||
copy(pj(meta_dir, 'safariextz', vendors['safariextz']['manifest']['Settings']), pj(src_dir, vendors['safariextz']['manifest']['Settings']))
|
|
|
@ -5,61 +5,61 @@
|
||||||
echo "*** uBlock: Importing from Crowdin archive"
|
echo "*** uBlock: Importing from Crowdin archive"
|
||||||
rm -r ~/Downloads/crowdin
|
rm -r ~/Downloads/crowdin
|
||||||
unzip -q ~/Downloads/ublock.zip -d ~/Downloads/crowdin
|
unzip -q ~/Downloads/ublock.zip -d ~/Downloads/crowdin
|
||||||
cp ~/Downloads/crowdin/ar/messages.json ../src/_locales/ar/messages.json
|
cp ~/Downloads/crowdin/ar/messages.json ./_locales/ar/messages.json
|
||||||
cp ~/Downloads/crowdin/cs/messages.json ../src/_locales/cs/messages.json
|
cp ~/Downloads/crowdin/cs/messages.json ./_locales/cs/messages.json
|
||||||
cp ~/Downloads/crowdin/da/messages.json ../src/_locales/da/messages.json
|
cp ~/Downloads/crowdin/da/messages.json ./_locales/da/messages.json
|
||||||
cp ~/Downloads/crowdin/el/messages.json ../src/_locales/el/messages.json
|
cp ~/Downloads/crowdin/el/messages.json ./_locales/el/messages.json
|
||||||
cp ~/Downloads/crowdin/es-ES/messages.json ../src/_locales/es/messages.json
|
cp ~/Downloads/crowdin/es-ES/messages.json ./_locales/es/messages.json
|
||||||
cp ~/Downloads/crowdin/et/messages.json ../src/_locales/et/messages.json
|
cp ~/Downloads/crowdin/et/messages.json ./_locales/et/messages.json
|
||||||
cp ~/Downloads/crowdin/fi/messages.json ../src/_locales/fi/messages.json
|
cp ~/Downloads/crowdin/fi/messages.json ./_locales/fi/messages.json
|
||||||
cp ~/Downloads/crowdin/he/messages.json ../src/_locales/he/messages.json
|
cp ~/Downloads/crowdin/he/messages.json ./_locales/he/messages.json
|
||||||
cp ~/Downloads/crowdin/hi/messages.json ../src/_locales/hi/messages.json
|
cp ~/Downloads/crowdin/hi/messages.json ./_locales/hi/messages.json
|
||||||
cp ~/Downloads/crowdin/hr/messages.json ../src/_locales/hr/messages.json
|
cp ~/Downloads/crowdin/hr/messages.json ./_locales/hr/messages.json
|
||||||
cp ~/Downloads/crowdin/hu/messages.json ../src/_locales/hu/messages.json
|
cp ~/Downloads/crowdin/hu/messages.json ./_locales/hu/messages.json
|
||||||
cp ~/Downloads/crowdin/id/messages.json ../src/_locales/id/messages.json
|
cp ~/Downloads/crowdin/id/messages.json ./_locales/id/messages.json
|
||||||
cp ~/Downloads/crowdin/it/messages.json ../src/_locales/it/messages.json
|
cp ~/Downloads/crowdin/it/messages.json ./_locales/it/messages.json
|
||||||
cp ~/Downloads/crowdin/ja/messages.json ../src/_locales/ja/messages.json
|
cp ~/Downloads/crowdin/ja/messages.json ./_locales/ja/messages.json
|
||||||
cp ~/Downloads/crowdin/mr/messages.json ../src/_locales/mr/messages.json
|
cp ~/Downloads/crowdin/mr/messages.json ./_locales/mr/messages.json
|
||||||
cp ~/Downloads/crowdin/no/messages.json ../src/_locales/nb/messages.json
|
cp ~/Downloads/crowdin/no/messages.json ./_locales/nb/messages.json
|
||||||
cp ~/Downloads/crowdin/nl/messages.json ../src/_locales/nl/messages.json
|
cp ~/Downloads/crowdin/nl/messages.json ./_locales/nl/messages.json
|
||||||
cp ~/Downloads/crowdin/pl/messages.json ../src/_locales/pl/messages.json
|
cp ~/Downloads/crowdin/pl/messages.json ./_locales/pl/messages.json
|
||||||
cp ~/Downloads/crowdin/pt-BR/messages.json ../src/_locales/pt_BR/messages.json
|
cp ~/Downloads/crowdin/pt-BR/messages.json ./_locales/pt_BR/messages.json
|
||||||
cp ~/Downloads/crowdin/pt-PT/messages.json ../src/_locales/pt_PT/messages.json
|
cp ~/Downloads/crowdin/pt-PT/messages.json ./_locales/pt_PT/messages.json
|
||||||
cp ~/Downloads/crowdin/ro/messages.json ../src/_locales/ro/messages.json
|
cp ~/Downloads/crowdin/ro/messages.json ./_locales/ro/messages.json
|
||||||
cp ~/Downloads/crowdin/ru/messages.json ../src/_locales/ru/messages.json
|
cp ~/Downloads/crowdin/ru/messages.json ./_locales/ru/messages.json
|
||||||
cp ~/Downloads/crowdin/sv-SE/messages.json ../src/_locales/sv/messages.json
|
cp ~/Downloads/crowdin/sv-SE/messages.json ./_locales/sv/messages.json
|
||||||
cp ~/Downloads/crowdin/tr/messages.json ../src/_locales/tr/messages.json
|
cp ~/Downloads/crowdin/tr/messages.json ./_locales/tr/messages.json
|
||||||
cp ~/Downloads/crowdin/uk/messages.json ../src/_locales/uk/messages.json
|
cp ~/Downloads/crowdin/uk/messages.json ./_locales/uk/messages.json
|
||||||
cp ~/Downloads/crowdin/vi/messages.json ../src/_locales/vi/messages.json
|
cp ~/Downloads/crowdin/vi/messages.json ./_locales/vi/messages.json
|
||||||
cp ~/Downloads/crowdin/zh-CN/messages.json ../src/_locales/zh_CN/messages.json
|
cp ~/Downloads/crowdin/zh-CN/messages.json ./_locales/zh_CN/messages.json
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
||||||
cp ~/Downloads/crowdin/ar/description.txt ../dist/description/description-ar.txt
|
cp ~/Downloads/crowdin/ar/description.txt ./dist/description/description-ar.txt
|
||||||
cp ~/Downloads/crowdin/cs/description.txt ../dist/description/description-cs.txt
|
cp ~/Downloads/crowdin/cs/description.txt ./dist/description/description-cs.txt
|
||||||
cp ~/Downloads/crowdin/da/description.txt ../dist/description/description-da.txt
|
cp ~/Downloads/crowdin/da/description.txt ./dist/description/description-da.txt
|
||||||
#cp ~/Downloads/crowdin/el/description.txt ../dist/description/description-el.txt
|
#cp ~/Downloads/crowdin/el/description.txt ./dist/description/description-el.txt
|
||||||
cp ~/Downloads/crowdin/es-ES/description.txt ../dist/description/description-es.txt
|
cp ~/Downloads/crowdin/es-ES/description.txt ./dist/description/description-es.txt
|
||||||
cp ~/Downloads/crowdin/et/description.txt ../dist/description/description-et.txt
|
cp ~/Downloads/crowdin/et/description.txt ./dist/description/description-et.txt
|
||||||
cp ~/Downloads/crowdin/fi/description.txt ../dist/description/description-fi.txt
|
cp ~/Downloads/crowdin/fi/description.txt ./dist/description/description-fi.txt
|
||||||
cp ~/Downloads/crowdin/he/description.txt ../dist/description/description-he.txt
|
cp ~/Downloads/crowdin/he/description.txt ./dist/description/description-he.txt
|
||||||
cp ~/Downloads/crowdin/hr/description.txt ../dist/description/description-hr.txt
|
cp ~/Downloads/crowdin/hr/description.txt ./dist/description/description-hr.txt
|
||||||
cp ~/Downloads/crowdin/hu/description.txt ../dist/description/description-hu.txt
|
cp ~/Downloads/crowdin/hu/description.txt ./dist/description/description-hu.txt
|
||||||
cp ~/Downloads/crowdin/id/description.txt ../dist/description/description-id.txt
|
cp ~/Downloads/crowdin/id/description.txt ./dist/description/description-id.txt
|
||||||
cp ~/Downloads/crowdin/it/description.txt ../dist/description/description-it.txt
|
cp ~/Downloads/crowdin/it/description.txt ./dist/description/description-it.txt
|
||||||
#cp ~/Downloads/crowdin/ja/description.txt ../dist/description/description-ja.txt
|
#cp ~/Downloads/crowdin/ja/description.txt ./dist/description/description-ja.txt
|
||||||
cp ~/Downloads/crowdin/no/description.txt ../dist/description/description-no.txt
|
cp ~/Downloads/crowdin/no/description.txt ./dist/description/description-no.txt
|
||||||
cp ~/Downloads/crowdin/nl/description.txt ../dist/description/description-nl.txt
|
cp ~/Downloads/crowdin/nl/description.txt ./dist/description/description-nl.txt
|
||||||
cp ~/Downloads/crowdin/pl/description.txt ../dist/description/description-pl.txt
|
cp ~/Downloads/crowdin/pl/description.txt ./dist/description/description-pl.txt
|
||||||
cp ~/Downloads/crowdin/pt-BR/description.txt ../dist/description/description-pt_BR.txt
|
cp ~/Downloads/crowdin/pt-BR/description.txt ./dist/description/description-pt_BR.txt
|
||||||
cp ~/Downloads/crowdin/pt-PT/description.txt ../dist/description/description-pt_PT.txt
|
cp ~/Downloads/crowdin/pt-PT/description.txt ./dist/description/description-pt_PT.txt
|
||||||
cp ~/Downloads/crowdin/ro/description.txt ../dist/description/description-ro.txt
|
cp ~/Downloads/crowdin/ro/description.txt ./dist/description/description-ro.txt
|
||||||
cp ~/Downloads/crowdin/ru/description.txt ../dist/description/description-ru.txt
|
cp ~/Downloads/crowdin/ru/description.txt ./dist/description/description-ru.txt
|
||||||
cp ~/Downloads/crowdin/sv-SE/description.txt ../dist/description/description-sv.txt
|
cp ~/Downloads/crowdin/sv-SE/description.txt ./dist/description/description-sv.txt
|
||||||
cp ~/Downloads/crowdin/tr/description.txt ../dist/description/description-tr.txt
|
cp ~/Downloads/crowdin/tr/description.txt ./dist/description/description-tr.txt
|
||||||
cp ~/Downloads/crowdin/uk/description.txt ../dist/description/description-uk.txt
|
cp ~/Downloads/crowdin/uk/description.txt ./dist/description/description-uk.txt
|
||||||
#cp ~/Downloads/crowdin/vi/description.txt ../dist/description/description-vi.txt
|
#cp ~/Downloads/crowdin/vi/description.txt ./dist/description/description-vi.txt
|
||||||
cp ~/Downloads/crowdin/zh-CN/description.txt ../dist/description/description-zh_CN.txt
|
cp ~/Downloads/crowdin/zh-CN/description.txt ./dist/description/description-zh_CN.txt
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
|
|
||||||
echo "*** uBlock: Creating web store package"
|
echo "*** uBlock: Creating web store package"
|
||||||
echo "*** uBlock: Copying files"
|
echo "*** uBlock: Copying files"
|
||||||
cp -R assets ../dist/ublock/
|
cp -R assets dist/ublock/
|
||||||
rm ../dist/ublock/assets/*.sh
|
rm dist/ublock/assets/*.sh
|
||||||
cp -R css ../dist/ublock/
|
cp -R css dist/ublock/
|
||||||
cp -R img ../dist/ublock/
|
cp -R img dist/ublock/
|
||||||
cp -R js ../dist/ublock/
|
cp -R js dist/ublock/
|
||||||
cp -R lib ../dist/ublock/
|
cp -R lib dist/ublock/
|
||||||
cp -R _locales ../dist/ublock/
|
cp -R _locales dist/ublock/
|
||||||
cp *.html ../dist/ublock/
|
cp *.html dist/ublock/
|
||||||
cp *.txt ../dist/ublock/
|
cp *.txt dist/ublock/
|
||||||
cp manifest.json ../dist/ublock/
|
cp manifest.json dist/ublock/
|
||||||
echo "*** uBlock: Package done."
|
echo "*** uBlock: Package done."
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
# This script assumes a linux environment
|
# This script assumes a linux environment
|
||||||
|
|
||||||
echo "*** uBlock: Cleaning."
|
echo "*** uBlock: Cleaning."
|
||||||
rm -R ../dist/ublock/*
|
rm -R dist/ublock/*
|
||||||
echo "*** uBlock: Cleaned."
|
echo "*** uBlock: Cleaned."
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
|
|
||||||
echo "*** uBlock: Creating web store package"
|
echo "*** uBlock: Creating web store package"
|
||||||
echo "*** uBlock: Copying files"
|
echo "*** uBlock: Copying files"
|
||||||
cp -R css ../dist/ublock/
|
cp -R css dist/ublock/
|
||||||
cp -R img ../dist/ublock/
|
cp -R img dist/ublock/
|
||||||
cp -R js ../dist/ublock/
|
cp -R js dist/ublock/
|
||||||
cp -R lib ../dist/ublock/
|
cp -R lib dist/ublock/
|
||||||
cp -R _locales ../dist/ublock/
|
cp -R _locales dist/ublock/
|
||||||
cp *.html ../dist/ublock/
|
cp *.html dist/ublock/
|
||||||
cp *.txt ../dist/ublock/
|
cp *.txt dist/ublock/
|
||||||
cp manifest.json ../dist/ublock/
|
cp manifest.json dist/ublock/
|
||||||
echo "*** uBlock: Package done."
|
echo "*** uBlock: Package done."
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
echo "*** uBlock: Creating Opera web store package"
|
echo "*** uBlock: Creating Opera web store package"
|
||||||
./make-chrome.sh
|
./make-chrome.sh
|
||||||
rm -r ../dist/ublock/_locales/el
|
rm -r dist/ublock/_locales/el
|
||||||
rm -r ../dist/ublock/_locales/ja
|
rm -r dist/ublock/_locales/ja
|
||||||
rm -r ../dist/ublock/_locales/vi
|
rm -r dist/ublock/_locales/vi
|
||||||
echo "*** uBlock: Opera package done."
|
echo "*** uBlock: Opera package done."
|
||||||
|
|
Loading…
Reference in New Issue