Skip to content

Commit c6b8a60

Browse files
committed
Close #173: Add blacklisting and whitelisting to project directory
Files can be whitelisted or blacklisted via globs. A file tree on the right hand side shows which files are currently included in the build.
1 parent 4aa74f5 commit c6b8a60

File tree

5 files changed

+352
-99
lines changed

5 files changed

+352
-99
lines changed

command_line.py

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import utils
4444
from utils import zip_files, join_files
4545
from utils import get_data_path, get_data_file_path
46-
from util_classes import Setting
46+
from util_classes import Setting, FileTree
4747

4848
from image_utils.pycns import save_icns
4949
from pepy.pe import PEFile
@@ -69,6 +69,8 @@ def __init__(self, quiet=False):
6969
self.readonly = True
7070
self.update_json = True
7171

72+
self.file_tree = FileTree()
73+
7274
def init(self):
7375
self.logger = config.logger
7476
self.update_nw_versions(None)
@@ -320,6 +322,7 @@ def get_versions(self):
320322
nw_version = self.get_setting('nw_version')
321323

322324
old_versions = set(nw_version.values)
325+
323326
old_versions = old_versions.union(union_versions)
324327
new_versions = set(re.findall(regex, html))
325328

@@ -375,7 +378,7 @@ def download_file_with_error_handling(self):
375378
if os.path.exists(setting.save_file_path(version, location)):
376379
os.remove(setting.save_file_path(version, location))
377380

378-
exc_format = utils.format_exc_info(sys.exc_info)
381+
exc_format = utils.format_exc_info(sys.exc_info())
379382
self.show_error(exc_format)
380383
self.enable_ui_after_error()
381384

@@ -758,8 +761,12 @@ def replace_plist(self, app_path):
758761
plist_dict['CFBundleDisplayName'] = self.project_name()
759762
plist_dict['CFBundleName'] = self.project_name()
760763
version_setting = self.get_setting('version')
761-
plist_dict['CFBundleShortVersionString'] = version_setting.value
762-
plist_dict['CFBundleVersion'] = version_setting.value
764+
if version_setting.value is not None:
765+
plist_dict['CFBundleShortVersionString'] = version_setting.value
766+
plist_dict['CFBundleVersion'] = version_setting.value
767+
else:
768+
plist_dict['CFBundleShortVersionString'] = '0.0.0'
769+
plist_dict['CFBundleVersion'] = '0.0.0'
763770

764771
plistlib.writePlist(plist_dict, plist_path)
765772

@@ -870,6 +877,13 @@ def process_export_setting(self, ex_setting, output_name):
870877
self.process_win_linux_setting(app_loc, output_dir,
871878
ex_setting)
872879

880+
@property
881+
def used_project_files(self):
882+
return self.file_tree.files
883+
884+
@property
885+
def used_project_dirs(self):
886+
return self.file_tree.dirs
873887

874888
def make_output_dirs(self, write_json=True):
875889
"""Create the output directories for the application to be copied"""
@@ -878,6 +892,17 @@ def make_output_dirs(self, write_json=True):
878892

879893
self.progress_text = 'Making new directories...\n'
880894

895+
896+
whitelist_setting = self.get_setting('whitelist')
897+
blacklist_setting = self.get_setting('blacklist')
898+
899+
output_blacklist = os.path.basename(self.output_dir())
900+
901+
self.file_tree.init(self.project_dir(),
902+
blacklist=(blacklist_setting.value.split(',') +
903+
['*'+output_blacklist+'*']),
904+
whitelist=whitelist_setting.value.split(','))
905+
881906
self.copy_files_to_project_folder()
882907

883908
if write_json:
@@ -914,15 +939,28 @@ def get_app_nw_loc(self, temp_dir, output_dir):
914939
"""Copy the temporary app to the output_dir"""
915940
app_file = utils.path_join(temp_dir, self.project_name()+'.nw')
916941

942+
proj_dir = self.project_dir()
943+
917944
if self.uncompressed:
918945
app_nw_folder = utils.path_join(temp_dir,
919946
self.project_name()+'.nwf')
947+
for dir in self.used_project_dirs:
948+
if not os.path.exists(dir):
949+
os.makedirs(dir)
950+
951+
for file in self.used_project_files:
952+
src = utils.path_join(proj_dir, file)
953+
dest = utils.path_join(app_nw_folder, file)
954+
955+
base, _ = os.path.split(dest)
956+
957+
if not os.path.exists(base):
958+
os.makedirs(base)
920959

921-
utils.copytree(self.project_dir(), app_nw_folder,
922-
ignore=shutil.ignore_patterns(output_dir))
960+
utils.copy(src, dest)
923961
return app_nw_folder
924962
else:
925-
zip_files(app_file, self.project_dir(), exclude_paths=[output_dir])
963+
zip_files(app_file, proj_dir, *self.used_project_files)
926964
return app_file
927965

928966
def get_version_tuple(self):
@@ -1455,7 +1493,6 @@ class ArgParser(argparse.ArgumentParser):
14551493
"""Custom argparser that prints help if there is an error"""
14561494
def error(self, message):
14571495
sys.stderr.write('error: {}\n'.format(message))
1458-
self.print_help()
14591496
sys.exit(2)
14601497

14611498
def get_arguments(command_base):
@@ -1520,8 +1557,9 @@ def generate_setting_args(command_base, parser):
15201557
if setting_name == 'name':
15211558
kwargs.update({'default': command_base.project_name})
15221559
else:
1523-
kwargs.update({'required': setting.required,
1524-
'default': setting.default_value})
1560+
kwargs.update({'required': setting.required})
1561+
if setting.default_value is not None:
1562+
kwargs.update({'default': setting.default_value})
15251563
action = 'store'
15261564
option_name = setting_name.replace('_', '-')
15271565

files/settings.cfg

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ linux_64_dir_prefix = 'nwjs-v{}-linux-x64'
128128
default_value=''
129129
type='string'
130130
description='Type "%(" to see a list of options to reference. Name your output folder.\n Include slashes to make sub-directories.'
131+
[[[blacklist]]]
132+
display_name='Blacklist'
133+
default_value=''
134+
type='string'
135+
description='Glob-style blacklist files/directories. Each line is a new pattern. Ex: *.jpeg, .git, *file[s].txt'
136+
[[[whitelist]]]
137+
display_name='Whitelist'
138+
default_value=''
139+
type='string'
140+
description='Glob-style whitelist files/directories. Each line is a new pattern. Ex: *.jpeg, .git, *file[s].txt.\nWhitelist trumps blacklist.'
131141

132142
[[window_settings]]
133143
[[[id]]]
@@ -238,6 +248,7 @@ linux_64_dir_prefix = 'nwjs-v{}-linux-x64'
238248
[[download_settings]]
239249
[[[nw_version]]]
240250
display_name='NW.js version'
251+
required=True
241252
default_value=None
242253
values=[]
243254
type='list'

main.py

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,13 @@ def load_project(self, directory, readonly=False):
979979
self.set_window_icon()
980980
self.open_export_button.setEnabled(True)
981981

982-
self.tree_browser.init(directory, ['.*'])
982+
blacklist_setting = self.get_setting('blacklist')
983+
984+
output_blacklist = os.path.basename(self.output_dir())
985+
986+
self.tree_browser.init(directory,
987+
blacklist=(blacklist_setting.value.split('\n') +
988+
['*'+output_blacklist+'*']))
983989

984990
self.update_json = True
985991

@@ -1152,6 +1158,7 @@ def create_export_settings(self):
11521158
ex_setting_order = self.settings['order']['export_setting_order']
11531159

11541160
vlayout = self.create_layout(ex_setting_order, cols=1)
1161+
vlayout.setContentsMargins(0, 10, 0, 0)
11551162

11561163
output_name_layout = self.create_output_name_pattern_line()
11571164

@@ -1162,18 +1169,15 @@ def create_export_settings(self):
11621169
hlayout = QtGui.QHBoxLayout()
11631170

11641171
platform_group = QtGui.QGroupBox('Platforms')
1172+
platform_group.setContentsMargins(0, 10, 0, 0)
11651173
playout = QtGui.QVBoxLayout()
11661174
playout.addLayout(vlayout)
11671175
platform_group.setLayout(playout)
11681176

11691177
hlayout.addWidget(platform_group)
11701178

1171-
tree_layout = self.create_blacklist_layout()
1172-
1173-
tree_group = QtGui.QGroupBox('Files')
1174-
tree_group.setLayout(tree_layout)
1175-
1176-
hlayout.addWidget(tree_group)
1179+
tree_layout = self.create_blacklist_layout(hlayout)
1180+
tree_layout.setContentsMargins(0, 10, 0, 0)
11771181

11781182
vbox = QtGui.QVBoxLayout()
11791183
vbox.addLayout(hlayout)
@@ -1184,15 +1188,85 @@ def create_export_settings(self):
11841188
group_box.setLayout(vbox)
11851189
return group_box
11861190

1187-
def create_blacklist_layout(self):
1188-
blacklist_layout = QtGui.QVBoxLayout()
1191+
def create_blacklist_layout(self, blacklist_layout):
11891192

11901193
self.tree_browser = TreeBrowser()
1194+
self.tree_browser.setContentsMargins(0, 0, 0, 0)
1195+
1196+
self.blacklist_text = QtGui.QPlainTextEdit()
1197+
self.whitelist_text = QtGui.QPlainTextEdit()
1198+
1199+
hlayout = QtGui.QHBoxLayout()
1200+
1201+
blacklayout = QtGui.QVBoxLayout()
1202+
whitelayout = QtGui.QHBoxLayout()
11911203

1204+
blacklayout.addWidget(self.blacklist_text)
1205+
whitelayout.addWidget(self.whitelist_text)
1206+
1207+
whitelist_setting = self.get_setting('whitelist')
1208+
blacklist_setting = self.get_setting('blacklist')
1209+
1210+
self.blacklist_text.setStatusTip(blacklist_setting.description)
1211+
self.whitelist_text.setStatusTip(whitelist_setting.description)
1212+
1213+
self.blacklist_text.setObjectName(blacklist_setting.name)
1214+
self.whitelist_text.setObjectName(whitelist_setting.name)
1215+
1216+
blackgroup = QtGui.QGroupBox(blacklist_setting.display_name)
1217+
whitegroup = QtGui.QGroupBox(whitelist_setting.display_name)
1218+
1219+
blackgroup.setLayout(blacklayout)
1220+
whitegroup.setLayout(whitelayout)
1221+
1222+
blacklist_layout.addWidget(blackgroup)
1223+
blacklist_layout.addWidget(whitegroup)
11921224
blacklist_layout.addWidget(self.tree_browser)
11931225

1226+
self.blacklist_text.textChanged.connect(
1227+
self.call_with_object('setting_changed',
1228+
self.blacklist_text,
1229+
blacklist_setting)
1230+
)
1231+
1232+
self.whitelist_text.textChanged.connect(
1233+
self.call_with_object('setting_changed',
1234+
self.whitelist_text,
1235+
whitelist_setting)
1236+
)
1237+
1238+
self.blacklist_text.textChanged.connect(
1239+
self.call_with_object('blacklist_changed',
1240+
self.blacklist_text,
1241+
blacklist_setting)
1242+
)
1243+
1244+
self.whitelist_text.textChanged.connect(
1245+
self.call_with_object('whitelist_changed',
1246+
self.whitelist_text,
1247+
whitelist_setting)
1248+
)
1249+
11941250
return blacklist_layout
11951251

1252+
def blacklist_changed(self, text, blacklist_setting):
1253+
new_val = text.toPlainText()
1254+
output_blacklist = os.path.basename(self.output_dir())
1255+
self.tree_browser.refresh(blacklist=(new_val.split('\n') +
1256+
['*'+output_blacklist+'*']))
1257+
1258+
def whitelist_changed(self, text, whitelist_setting):
1259+
new_val = text.toPlainText()
1260+
self.tree_browser.refresh(whitelist=new_val.split('\n'))
1261+
1262+
@property
1263+
def used_project_files(self):
1264+
return self.tree_browser.files
1265+
1266+
@property
1267+
def used_project_dirs(self):
1268+
return self.tree_browser.dirs
1269+
11961270
def create_output_name_pattern_line(self):
11971271
output_name_layout = QtGui.QHBoxLayout()
11981272

@@ -1432,7 +1506,10 @@ def reset_settings(self):
14321506
old_val = setting.default_value
14331507

14341508
setting.value = old_val.replace('\\', '\\\\')
1435-
widget.setText(old_val)
1509+
if hasattr(widget, 'setText'):
1510+
widget.setText(old_val)
1511+
elif hasattr(widget, 'setPlainText'):
1512+
widget.setPlainText(old_val)
14361513
elif setting.type == 'strings':
14371514
old_val = []
14381515
if setting.default_value is not None:
@@ -1494,7 +1571,11 @@ def setting_changed(self, obj, setting, *args):
14941571
setting.type == 'file' or
14951572
setting.type == 'folder' or
14961573
setting.type == 'int'):
1497-
setting.value = args[0]
1574+
if args:
1575+
setting.value = args[0]
1576+
else:
1577+
setting.value = obj.toPlainText()
1578+
14981579
if not setting.value:
14991580
setting.value = setting.default_value
15001581
elif setting.type == 'strings':
@@ -1646,7 +1727,10 @@ def load_package_json(self, json_path=None):
16461727
setting.type == 'folder' or
16471728
setting.type == 'int'):
16481729
val_str = self.convert_val_to_str(setting.value)
1649-
setting_field.setText(setting.filter_name(val_str))
1730+
if hasattr(setting_field, 'setText'):
1731+
setting_field.setText(setting.filter_name(val_str))
1732+
elif hasattr(setting_field, 'setPlainText'):
1733+
setting_field.setPlainText(setting.filter_name(val_str))
16501734
if setting.type == 'strings':
16511735
vals = [self.convert_val_to_str(v) for v in setting.value]
16521736
setting_field.setText(','.join(vals))

0 commit comments

Comments
 (0)