mirror of https://github.com/amol-/dukpy.git
Experimental minimal installer for js modules from npmjs.org
This commit is contained in:
parent
ebf52caf6e
commit
42ccb3ac9d
|
@ -2,4 +2,5 @@ from .evaljs import evaljs, JSInterpreter
|
|||
from ._dukpy import JSRuntimeError
|
||||
from .coffee import coffee_compile
|
||||
from .babel import babel_compile, jsx_compile
|
||||
from .tsc import typescript_compile
|
||||
from .tsc import typescript_compile
|
||||
from .install import install_jspackage
|
|
@ -95,7 +95,8 @@ class JSInterpreter(object):
|
|||
var m = call_python('dukpy.lookup_module', id);
|
||||
if (!m)
|
||||
throw new Error('cannot find module: ' + id);
|
||||
return m;
|
||||
module.filename = m[0];
|
||||
return m[1];
|
||||
};
|
||||
""")
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import print_function
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import tarfile
|
||||
import tempfile
|
||||
import shutil
|
||||
from contextlib import closing
|
||||
from io import BytesIO
|
||||
|
||||
try:
|
||||
from urllib.request import urlopen
|
||||
except ImportError:
|
||||
from urllib2 import urlopen
|
||||
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
try:
|
||||
package_name = args[0]
|
||||
version = args[1]
|
||||
except:
|
||||
print('Usage: dukpy-install package_name version')
|
||||
print('')
|
||||
print('Downloads a specific package version from npmjs.org. Note this is'
|
||||
'a very basic script that does not support dependencies.')
|
||||
return 1
|
||||
|
||||
install_jspackage(package_name, version, './node_modules')
|
||||
|
||||
|
||||
def install_jspackage(package_name, version, modulesdir):
|
||||
"""Installs a JavaScript package downloaded from npmjs.org.
|
||||
|
||||
For example to install React::
|
||||
|
||||
install_jspackage('react', '0.14.8', './node_modules')
|
||||
"""
|
||||
url = 'http://registry.npmjs.org/{}'
|
||||
with closing(urlopen(url.format(package_name))) as data:
|
||||
package_info = json.loads(data.read())
|
||||
package_versions = package_info['versions']
|
||||
version_info = package_versions.get(version)
|
||||
if version_info is None:
|
||||
print('Version {} not found, available versions are {}'.format(
|
||||
version, ', '.join(sorted(package_versions.keys()))
|
||||
))
|
||||
return 2
|
||||
|
||||
try:
|
||||
download_url = version_info['dist']['tarball']
|
||||
except KeyError:
|
||||
print('Unable to detect a supported download url for package')
|
||||
return 3
|
||||
|
||||
tarball = BytesIO()
|
||||
print('Downloading {}'.format(download_url))
|
||||
with closing(urlopen(download_url)) as data:
|
||||
chunk = data.read(1024)
|
||||
while chunk:
|
||||
print('.', end='')
|
||||
tarball.write(chunk)
|
||||
chunk = data.read(1024)
|
||||
print('')
|
||||
|
||||
tarball.seek(0)
|
||||
print('Extracting... ')
|
||||
with tarfile.open(fileobj=tarball) as tb:
|
||||
dest = os.path.join(modulesdir, version_info['name'])
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
try:
|
||||
tb.extractall(tmpdir)
|
||||
shutil.move(os.path.join(tmpdir, 'package'),
|
||||
os.path.abspath(dest))
|
||||
finally:
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
print('Installed in {}'.format(dest))
|
||||
|
|
@ -40,7 +40,7 @@ class JSModuleLoader(object):
|
|||
path = self.lookup(module_name)
|
||||
if path:
|
||||
with open(path, 'rb') as f:
|
||||
return f.read().decode('utf-8')
|
||||
return path, f.read().decode('utf-8')
|
||||
|
||||
def _lookup(self, module_path):
|
||||
# Module is a plain .js file
|
||||
|
|
7
setup.py
7
setup.py
|
@ -40,5 +40,10 @@ setup(
|
|||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: JavaScript',
|
||||
]
|
||||
],
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'dukpy-install = dukpy.install:main'
|
||||
]
|
||||
}
|
||||
)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
import dukpy
|
||||
|
||||
|
||||
class TestPackageInstaller(object):
|
||||
def setup(self):
|
||||
self.tmpdir = tempfile.mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
#shutil.rmtree(self.tmpdir)
|
||||
pass
|
||||
|
||||
def test_install_react(self):
|
||||
dukpy.install_jspackage('react', '0.14.8', self.tmpdir)
|
||||
dukpy.install_jspackage('react-dom', '0.14.8', self.tmpdir)
|
||||
dukpy.install_jspackage('fbjs', '0.8.0', self.tmpdir)
|
||||
|
||||
jsx = dukpy.jsx_compile(TEST_CODE)
|
||||
|
||||
jsi = dukpy.JSInterpreter()
|
||||
jsi.loader.register_path(self.tmpdir)
|
||||
res = jsi.evaljs(jsx, data={'id': 1, 'name': "Alessandro"})
|
||||
assert res == '<div class="helloworld">Hello Alessandro</div>', res
|
||||
|
||||
|
||||
TEST_CODE = '''
|
||||
var React = require('react/react'),
|
||||
ReactDOM = require('react-dom/server');
|
||||
|
||||
var HelloWorld = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<div className="helloworld">
|
||||
Hello {this.props.data.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.renderToStaticMarkup(<HelloWorld data={dukpy.data}/>, null);
|
||||
'''
|
Loading…
Reference in New Issue