4
4
# Copyright (c) Jupyter Development Team.
5
5
# Distributed under the terms of the Modified BSD License.
6
6
7
+ """
8
+ This file originates from the 'jupyter-packaging' package, and
9
+ contains a set of useful utilities for including npm packages
10
+ within a Python package.
11
+ """
12
+
7
13
import os
8
14
from os .path import join as pjoin
9
15
import functools
10
16
import pipes
11
17
import sys
18
+ from glob import glob
19
+ from subprocess import check_call
12
20
13
21
from setuptools import Command
14
22
from setuptools .command .build_py import build_py
15
23
from setuptools .command .sdist import sdist
16
24
from setuptools .command .develop import develop
17
25
from setuptools .command .bdist_egg import bdist_egg
18
26
from distutils import log
19
- from subprocess import check_call
20
27
21
28
try :
22
29
from wheel .bdist_wheel import bdist_wheel
@@ -36,10 +43,10 @@ def list2cmdline(cmd_list):
36
43
# Top Level Variables
37
44
# ---------------------------------------------------------------------------
38
45
39
-
40
- here = os .path .abspath (os .path .dirname (sys .argv [0 ]))
46
+ here = os .path .dirname (__file__ )
41
47
is_repo = os .path .exists (pjoin (here , '.git' ))
42
48
node_modules = pjoin (here , 'node_modules' )
49
+
43
50
npm_path = ':' .join ([
44
51
pjoin (here , 'node_modules' , '.bin' ),
45
52
os .environ .get ('PATH' , os .defpath ),
@@ -57,17 +64,21 @@ def list2cmdline(cmd_list):
57
64
# ---------------------------------------------------------------------------
58
65
59
66
60
- def get_data_files ( top ):
61
- """Get data files"""
67
+ def expand_data_files ( data_file_patterns ):
68
+ """Expand data file patterns to a valid data_files spec.
62
69
70
+ Parameters
71
+ -----------
72
+ data_file_patterns: list(tuple)
73
+ A list of (directory, glob patterns) for the data file locations.
74
+ The globs themselves do not recurse.
75
+ """
63
76
data_files = []
64
- ntrim = len (here + os .path .sep )
65
-
66
- for (d , dirs , filenames ) in os .walk (top ):
67
- data_files .append ((
68
- d [ntrim :],
69
- [pjoin (d , f ) for f in filenames ]
70
- ))
77
+ for (directory , patterns ) in data_file_patterns :
78
+ files = []
79
+ for p in patterns :
80
+ files .extend ([os .path .relpath (f , here ) for f in glob (p )])
81
+ data_files .append ((directory , files ))
71
82
return data_files
72
83
73
84
@@ -91,20 +102,17 @@ def update_package_data(distribution):
91
102
build_py .finalize_options ()
92
103
93
104
94
- def create_cmdclass (wrappers = None , data_dirs = None ):
105
+ def create_cmdclass (wrappers = None ):
95
106
"""Create a command class with the given optional wrappers.
96
107
97
108
Parameters
98
109
----------
99
110
wrappers: list(str), optional
100
111
The cmdclass names to run before running other commands
101
- data_dirs: list(str), optional.
102
- The directories containing static data.
103
112
"""
104
113
egg = bdist_egg if 'bdist_egg' in sys .argv else bdist_egg_disabled
105
114
wrappers = wrappers or []
106
- data_dirs = data_dirs or []
107
- wrapper = functools .partial (wrap_command , wrappers , data_dirs )
115
+ wrapper = functools .partial (wrap_command , wrappers )
108
116
cmdclass = dict (
109
117
build_py = wrapper (build_py , strict = is_repo ),
110
118
sdist = wrapper (sdist , strict = True ),
@@ -225,6 +233,8 @@ def mtime(path):
225
233
def install_npm (path = None , build_dir = None , source_dir = None , build_cmd = 'build' , force = False ):
226
234
"""Return a Command for managing an npm installation.
227
235
236
+ Note: The command is skipped if the `--skip-npm` flag is used.
237
+
228
238
Parameters
229
239
----------
230
240
path: str, optional
@@ -266,6 +276,26 @@ def run(self):
266
276
return NPM
267
277
268
278
279
+ def ensure_targets (targets ):
280
+ """Return a Command that checks that certain files exist.
281
+
282
+ Raises a ValueError if any of the files are missing.
283
+
284
+ Note: The check is skipped if the `--skip-npm` flag is used.
285
+ """
286
+
287
+ class TargetsCheck (BaseCommand ):
288
+ def run (self ):
289
+ if skip_npm :
290
+ log .info ('Skipping target checks' )
291
+ return
292
+ missing = [t for t in targets if not os .path .exists (t )]
293
+ if missing :
294
+ raise ValueError (('missing files: %s' % missing ))
295
+
296
+ return TargetsCheck
297
+
298
+
269
299
# `shutils.which` function copied verbatim from the Python-3.3 source.
270
300
def which (cmd , mode = os .F_OK | os .X_OK , path = None ):
271
301
"""Given a command, mode, and a PATH string, return the path which
@@ -325,7 +355,7 @@ def _access_check(fn, mode):
325
355
# ---------------------------------------------------------------------------
326
356
327
357
328
- def wrap_command (cmds , data_dirs , cls , strict = True ):
358
+ def wrap_command (cmds , cls , strict = True ):
329
359
"""Wrap a setup command
330
360
331
361
Parameters
@@ -348,13 +378,7 @@ def run(self):
348
378
pass
349
379
350
380
result = cls .run (self )
351
- if data_dirs :
352
- data_files = self .distribution .data_files if self .distribution .data_files else []
353
- for dname in data_dirs :
354
- data_files .extend (get_data_files (dname ))
355
- # update data-files in case this created new files
356
- self .distribution .data_files = data_files
357
- # also update package data
381
+ # update package data
358
382
update_package_data (self .distribution )
359
383
return result
360
384
return WrappedCommand
0 commit comments