Aug 17, 2015
Add initial code
|
|
|
11 |
|
|
12 |
v = sys.version_info |
|
13 |
if v[:2] < (3,3): |
|
14 |
error = "ERROR: Jupyter Hub requires Python version 3.3 or above." |
|
15 |
print(error, file=sys.stderr) |
|
16 |
sys.exit(1) |
|
17 |
|
|
18 |
def mtime(path): |
|
19 |
"""shorthand for mtime""" |
|
20 |
return os.stat(path).st_mtime |
|
21 |
|
|
22 |
|
|
23 |
if os.name in ('nt', 'dos'): |
|
24 |
error = "ERROR: Windows is not supported" |
|
25 |
print(error, file=sys.stderr) |
|
26 |
|
|
27 |
# At least we're on the python version we need, move on. |
|
28 |
|
|
29 |
from distutils.core import setup |
|
30 |
|
|
31 |
pjoin = os.path.join |
|
32 |
here = os.path.abspath(os.path.dirname(__file__)) |
|
33 |
|
|
34 |
from distutils.cmd import Command |
|
35 |
from distutils.command.build_py import build_py |
|
36 |
from distutils.command.sdist import sdist |
|
37 |
|
|
38 |
npm_path = ':'.join([ |
|
39 |
pjoin(here, 'node_modules', '.bin'), |
|
40 |
os.environ.get("PATH", os.defpath), |
|
41 |
]) |
|
42 |
|
|
43 |
here = os.path.abspath(os.path.dirname(__file__)) |
|
44 |
share = pjoin(here, 'share') |
|
45 |
static = pjoin(share, 'static') |
|
46 |
|
|
47 |
class BaseCommand(Command): |
|
48 |
"""Dumb empty command because Command needs subclasses to override too much""" |
|
49 |
user_options = [] |
|
50 |
|
|
51 |
def initialize_options(self): |
|
52 |
pass |
|
53 |
|
|
54 |
def finalize_options(self): |
|
55 |
pass |
|
56 |
|
|
57 |
def get_inputs(self): |
|
58 |
return [] |
|
59 |
|
|
60 |
def get_outputs(self): |
|
61 |
return [] |
|
62 |
|
|
63 |
class Bower(BaseCommand): |
|
64 |
description = "fetch static client-side components with bower" |
|
65 |
|
|
66 |
user_options = [] |
|
67 |
bower_dir = pjoin(static, 'components') |
|
68 |
node_modules = pjoin(here, 'node_modules') |
|
69 |
|
|
70 |
def should_run(self): |
|
71 |
if not os.path.exists(self.bower_dir): |
|
72 |
return True |
|
73 |
return mtime(self.bower_dir) < mtime(pjoin(here, 'bower.json')) |
|
74 |
|
|
75 |
def should_run_npm(self): |
|
76 |
if not shutil.which('npm'): |
|
77 |
print("npm unavailable", file=sys.stderr) |
|
78 |
return False |
|
79 |
if not os.path.exists(self.node_modules): |
|
80 |
return True |
|
81 |
return mtime(self.node_modules) < mtime(pjoin(here, 'package.json')) |
|
82 |
|
|
83 |
def run(self): |
|
84 |
if not self.should_run(): |
|
85 |
print("bower dependencies up to date") |
|
86 |
return |
|
87 |
|
|
88 |
if self.should_run_npm(): |
|
89 |
print("installing build dependencies with npm") |
|
90 |
check_call(['npm', 'install'], cwd=here) |
|
91 |
os.utime(self.node_modules) |
|
92 |
|
|
93 |
env = os.environ.copy() |
|
94 |
env['PATH'] = npm_path |
|
95 |
|
|
96 |
try: |
|
97 |
check_call( |
|
98 |
['bower', 'install', '--allow-root', '--config.interactive=false'], |
|
99 |
cwd=here, |
|
100 |
env=env, |
|
101 |
) |
|
102 |
except OSError as e: |
|
103 |
print("Failed to run bower: %s" % e, file=sys.stderr) |
|
104 |
print("You can install js dependencies with `npm install`", file=sys.stderr) |
|
105 |
raise |
|
106 |
os.utime(self.bower_dir) |
|
107 |
# update data-files in case this created new files |
|
108 |
self.distribution.data_files = get_data_files() |
|
109 |
|
|
110 |
|
|
111 |
class CSS(BaseCommand): |
|
112 |
description = "compile CSS from LESS" |
|
113 |
|
|
114 |
def should_run(self): |
|
115 |
"""Does less need to run?""" |
|
116 |
# from IPython.html.tasks.py |
|
117 |
|
|
118 |
css_targets = [pjoin(static, 'css', 'style.min.css')] |
|
119 |
css_maps = [t + '.map' for t in css_targets] |
|
120 |
targets = css_targets + css_maps |
|
121 |
if not all(os.path.exists(t) for t in targets): |
|
122 |
# some generated files don't exist |
|
123 |
return True |
|
124 |
earliest_target = sorted(mtime(t) for t in targets)[0] |
|
125 |
|
|
126 |
# check if any .less files are newer than the generated targets |
|
127 |
for (dirpath, dirnames, filenames) in os.walk(static): |
|
128 |
for f in filenames: |
|
129 |
if f.endswith('.less'): |
|
130 |
path = pjoin(static, dirpath, f) |
|
131 |
timestamp = mtime(path) |
|
132 |
if timestamp > earliest_target: |
|
133 |
return True |
|
134 |
|
|
135 |
return False |
|
136 |
|
|
137 |
def run(self): |
|
138 |
if not self.should_run(): |
|
139 |
print("CSS up-to-date") |
|
140 |
return |
|
141 |
|
|
142 |
self.run_command('js') |
|
143 |
|
|
144 |
style_less = pjoin(static, 'less', 'style.less') |
|
145 |
style_css = pjoin(static, 'css', 'style.min.css') |
|
146 |
sourcemap = style_css + '.map' |
|
147 |
|
|
148 |
env = os.environ.copy() |
|
149 |
env['PATH'] = npm_path |
|
150 |
try: |
|
151 |
check_call([ |
|
152 |
'lessc', '--clean-css', |
|
153 |
'--source-map-basepath={}'.format(static), |
|
154 |
'--source-map={}'.format(sourcemap), |
|
155 |
'--source-map-rootpath=../', |
|
156 |
style_less, style_css, |
|
157 |
], cwd=here, env=env) |
|
158 |
except OSError as e: |
|
159 |
print("Failed to run lessc: %s" % e, file=sys.stderr) |
|
160 |
print("You can install js dependencies with `npm install`", file=sys.stderr) |
|
161 |
raise |
|
162 |
# update data-files in case this created new files |
|
163 |
self.distribution.data_files = get_data_files() |
|
164 |
|
|
165 |
def get_data_files(): |
|
166 |
"""Get data files in share/jupyter""" |
|
167 |
|
|
168 |
data_files = [] |
|
169 |
ntrim = len(here) + 1 |
|
170 |
|
|
171 |
for (d, dirs, filenames) in os.walk(static): |
|
172 |
data_files.append(( |
|
173 |
d[ntrim:], |
|
174 |
[ pjoin(d, f) for f in filenames ] |
|
175 |
)) |
|
176 |
return data_files |
|
177 |
|
|
178 |
|
|
179 |
setup_args = dict( |
|
180 |
name = 'everware', |
|
181 |
packages = ['everware'], |
Aug 17, 2015
Add initial code
|
|
|
183 |
version = '0.0.0', |
|
184 |
description = """Everware""", |
|
185 |
long_description = "", |
|
186 |
author = "", |
|
187 |
author_email = "", |
|
188 |
url = "", |
|
189 |
license = "BSD", |
|
190 |
platforms = "Linux, Mac OS X", |
|
191 |
keywords = ['Interactive', 'Interpreter', 'Shell', 'Web'], |
|
192 |
classifiers = [ |
|
193 |
'Intended Audience :: Developers', |
|
194 |
'Intended Audience :: System Administrators', |
|
195 |
'Intended Audience :: Science/Research', |
|
196 |
'License :: OSI Approved :: BSD License', |
|
197 |
'Programming Language :: Python', |
|
198 |
'Programming Language :: Python :: 3', |
|
199 |
], |
|
200 |
) |
|
201 |
|
|
202 |
setup_args['cmdclass'] = {'js': Bower, 'css': CSS} |
|
203 |
|
|
204 |
# setuptools requirements |
|
205 |
if 'setuptools' in sys.modules: |
|
206 |
setup_args['install_requires'] = install_requires = [] |
|
207 |
with open('requirements.txt') as f: |
|
208 |
for line in f.readlines(): |
|
209 |
req = line.strip() |
|
210 |
if not req or req.startswith(('-e', '#')): |
|
211 |
continue |
|
212 |
install_requires.append(req) |
|
213 |
|
|
214 |
|
|
215 |
def main(): |
|
216 |
setup(**setup_args) |
|
217 |
|
|
218 |
if __name__ == '__main__': |
|
219 |
main() |