Skip to content

Commit 506b224

Browse files
authored
Merge pull request #10 from vidartf/fix-data-spec
Update data file spec
2 parents 76cf60d + 6455d62 commit 506b224

File tree

3 files changed

+68
-23
lines changed

3 files changed

+68
-23
lines changed

{{cookiecutter.github_project_name}}/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,5 @@ $RECYCLE.BIN/
149149
# -------------
150150
**/coverage/
151151

152+
# Packed lab extensions
153+
{{ cookiecutter.python_package_name }}/labextension

{{cookiecutter.github_project_name}}/setup.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
version = get_version(pjoin(name, '_version.py'))
2929

3030
nb_path = pjoin(HERE, name, 'nbextension', 'static')
31-
lab_path = pjoin(HERE, name, 'labextension', '*.tgz')
31+
lab_path = pjoin(HERE, name, 'labextension')
3232

3333
# Representative files that should exist after a successful build
3434
jstargets = [
@@ -45,9 +45,9 @@
4545

4646
data_files_spec = [
4747
('share/jupyter/nbextensions/{{ cookiecutter.npm_package_name }}',
48-
pjoin(nb_path, '*.js*')),
49-
('share/jupyter/lab/extensions', lab_path),
50-
('etc/jupyter/nbconfig/notebook.d/' , '{{ cookiecutter.npm_package_name }}.json')
48+
nb_path, '*.js*'),
49+
('share/jupyter/lab/extensions', lab_path, '*.tgz'),
50+
('etc/jupyter/nbconfig/notebook.d/' , HERE, '{{ cookiecutter.npm_package_name }}.json')
5151
]
5252

5353

@@ -68,7 +68,7 @@
6868
packages = find_packages(),
6969
author = '{{ cookiecutter.author_name }}',
7070
author_email = '{{ cookiecutter.author_email }}',
71-
url = 'https://github.com/{{ cookiecutter.github_organization_name }}/{{ cookiecutter.python_package_name }}',
71+
url = 'https://github.com/{{ cookiecutter.github_organization_name }}/{{ cookiecutter.github_project_name }}',
7272
license = 'BSD',
7373
platforms = "Linux, Mac OS X, Windows",
7474
keywords = ['Jupyter', 'Widgets', 'IPython'],

{{cookiecutter.github_project_name}}/setupbase.py

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
contains a set of useful utilities for including npm packages
1010
within a Python package.
1111
"""
12+
from collections import defaultdict
1213
from os.path import join as pjoin
1314
import io
1415
import os
@@ -146,8 +147,9 @@ def create_cmdclass(prerelease_cmd=None, package_data_spec=None,
146147
A dictionary whose keys are the dotted package names and
147148
whose values are a list of glob patterns.
148149
data_files_spec: list, optional
149-
A list of (path, patterns) tuples where the path is the
150-
`data_files` install path and the patterns are glob patterns.
150+
A list of (path, dname, pattern) tuples where the path is the
151+
`data_files` install path, dname is the source directory, and the
152+
pattern is a glob pattern.
151153
152154
Notes
153155
-----
@@ -159,9 +161,12 @@ def create_cmdclass(prerelease_cmd=None, package_data_spec=None,
159161
name.
160162
e.g. `dict(foo=['./bar/*', './baz/**'])`
161163
162-
The data files glob patterns should be absolute paths or relative paths
163-
from the root directory of the repository.
164-
e.g. `('share/foo/bar', ['pkgname/bizz/*', 'pkgname/baz/**'])`
164+
The data files directories should be absolute paths or relative paths
165+
from the root directory of the repository. Data files are specified
166+
differently from `package_data` because we need a separate path entry
167+
for each nested folder in `data_files`, and this makes it easier to
168+
parse.
169+
e.g. `('share/foo/bar', 'pkgname/bizz, '*')`
165170
"""
166171
wrapped = [prerelease_cmd] if prerelease_cmd else []
167172
if package_data_spec or data_files_spec:
@@ -467,10 +472,10 @@ def run(self):
467472
raise
468473
else:
469474
pass
470-
471-
result = cls.run(self)
472475
# update package data
473476
update_package_data(self.distribution)
477+
478+
result = cls.run(self)
474479
return result
475480
return WrappedCommand
476481

@@ -483,20 +488,58 @@ class FileHandler(BaseCommand):
483488
def run(self):
484489
package_data = self.distribution.package_data
485490
package_spec = package_data_spec or dict()
486-
data_spec = data_files_spec or []
487491

488492
for (key, patterns) in package_spec.items():
489493
package_data[key] = _get_package_data(key, patterns)
490494

491-
data_files = self.distribution.data_files or []
492-
for (path, patterns) in data_spec:
493-
data_files.append((path, _get_files(patterns)))
494-
495-
self.distribution.data_files = data_files
495+
self.distribution.data_files = _get_data_files(
496+
data_files_spec, self.distribution.data_files
497+
)
496498

497499
return FileHandler
498500

499501

502+
def _get_data_files(data_specs, existing):
503+
"""Expand data file specs into valid data files metadata.
504+
505+
Parameters
506+
----------
507+
data_specs: list of tuples
508+
See [createcmdclass] for description.
509+
existing: list of tuples
510+
The existing distrubution data_files metadata.
511+
512+
Returns
513+
-------
514+
A valid list of data_files items.
515+
"""
516+
# Extract the existing data files into a staging object.
517+
file_data = defaultdict(list)
518+
for (path, files) in existing or []:
519+
file_data[path] = files
520+
521+
# Extract the files and assign them to the proper data
522+
# files path.
523+
for (path, dname, pattern) in data_specs or []:
524+
dname = dname.replace(os.sep, '/')
525+
offset = len(dname) + 1
526+
527+
files = _get_files(pjoin(dname, pattern))
528+
for fname in files:
529+
# Normalize the path.
530+
root = os.path.dirname(fname)
531+
full_path = '/'.join([path, root[offset:]])
532+
if full_path.endswith('/'):
533+
full_path = full_path[:-1]
534+
file_data[full_path].append(fname)
535+
536+
# Construct the data files spec.
537+
data_files = []
538+
for (path, files) in file_data.items():
539+
data_files.append((path, files))
540+
return data_files
541+
542+
500543
def _get_files(file_patterns, top=HERE):
501544
"""Expand file patterns to a list of paths.
502545
@@ -631,7 +674,7 @@ def _translate_glob_part(pat):
631674
res = []
632675
while i < n:
633676
c = pat[i]
634-
i = i+1
677+
i = i + 1
635678
if c == '*':
636679
# Match anything but path separators:
637680
res.append('[^%s]*' % SEPARATORS)
@@ -640,16 +683,16 @@ def _translate_glob_part(pat):
640683
elif c == '[':
641684
j = i
642685
if j < n and pat[j] == '!':
643-
j = j+1
686+
j = j + 1
644687
if j < n and pat[j] == ']':
645-
j = j+1
688+
j = j + 1
646689
while j < n and pat[j] != ']':
647-
j = j+1
690+
j = j + 1
648691
if j >= n:
649692
res.append('\\[')
650693
else:
651694
stuff = pat[i:j].replace('\\', '\\\\')
652-
i = j+1
695+
i = j + 1
653696
if stuff[0] == '!':
654697
stuff = '^' + stuff[1:]
655698
elif stuff[0] == '^':

0 commit comments

Comments
 (0)