Repository: ckan/ckan

Issue:
Less compiler does not work on Ubuntu 14.04
If I follow the instructions on the [Frontend Development docs](http://docs.ckan.org/en/latest/contributing/frontend/index.html) (freshly updated on #1734) and install node using the following (as I'm on Ubuntu 14.04):

```
sudo apt-get install nodejs
```

and I try to rebuild the CSS using

```
./bin/less
```

I get an error because the node binary is named differently as the one defined on our `bin/less` script:

```
/usr/bin/env: node: No such file or directory
```

Look like the version that gets installed this way is called `nodejs`.
According to [this comment](https://github.com/joyent/node/issues/3911#issuecomment-12798913) from a Node developer, installing the default node package is frowned upon anyway, so perhaps we should recommend using Chris Lea's PPA anyway (or you know, getting rid of the node dependency).



Discussion:
https://github.com/robotis/Lesscpy/ looks like a good thing. I haven't worked with our .less files much, do we need javascript evaluation? 

I'd recommend talking to @mintcanary or another frontend developer for their opinion before we remove the dep.

I don't have any insight here I'm afraid, I've only used an external less app with CKAN.

I haven't used lessc.py, but the message on their message (`This is an early version, so you are likly to find bugs.`) doesn't make me comfortable. I tried compiling our `main.less` with it, but got:

```
$ lesscpy ckan/public/base/less/main.less
Traceback (most recent call last):
  File "/tmp/lesscpy/blah/bin/lesscpy", line 5, in <module>
    pkg_resources.run_script('lesscpy==0.10.1', 'lesscpy')
  File "/tmp/lesscpy/blah/local/lib/python2.7/site-packages/pkg_resources.py", line 488, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "/tmp/lesscpy/blah/local/lib/python2.7/site-packages/pkg_resources.py", line 1354, in run_script
    execfile(script_filename, namespace, namespace)
  File "/tmp/lesscpy/blah/lib/python2.7/site-packages/lesscpy-0.10.1-py2.7.egg/EGG-INFO/scripts/lesscpy", line 16, in <module>
    compiler.run()
  File "/tmp/lesscpy/lesscpy/scripts/compiler.py", line 177, in run
    p.parse(filename=args.target, debuglevel=args.debug)
  File "/tmp/lesscpy/lesscpy/lessc/parser.py", line 105, in parse
    file, lexer=self.lex, debug=debuglevel)
  File "build/bdist.linux-x86_64/egg/ply/yacc.py", line 265, in parse
  File "build/bdist.linux-x86_64/egg/ply/yacc.py", line 971, in parseopt_notrack
  File "/tmp/lesscpy/lesscpy/lessc/parser.py", line 204, in p_statement_import
    recurse.parse(filename=filename, debuglevel=0)
  File "/tmp/lesscpy/lesscpy/lessc/parser.py", line 105, in parse
    file, lexer=self.lex, debug=debuglevel)
  File "build/bdist.linux-x86_64/egg/ply/yacc.py", line 265, in parse
  File "build/bdist.linux-x86_64/egg/ply/yacc.py", line 971, in parseopt_notrack
  File "/tmp/lesscpy/lesscpy/lessc/parser.py", line 204, in p_statement_import
    recurse.parse(filename=filename, debuglevel=0)
  File "/tmp/lesscpy/lesscpy/lessc/parser.py", line 107, in parse
    self.post_parse()
  File "/tmp/lesscpy/lesscpy/lessc/parser.py", line 118, in post_parse
    out.append(pu.parse(self.scope))
  File "/tmp/lesscpy/lesscpy/plib/block.py", line 43, in parse
    inner = list(utility.flatten([p.parse(scope) for p in inner if p]))
  File "/tmp/lesscpy/lesscpy/plib/property.py", line 39, in parse
    self.parsed = self.process(style, scope)
  File "/tmp/lesscpy/lesscpy/plib/node.py", line 49, in process
    for t in tokens]
  File "/tmp/lesscpy/lesscpy/plib/expression.py", line 40, in parse
    if str(e).strip()]
ValueError: too many values to unpack
```

They disabled issues on their github repository, so I'm not sure where to submit this bug report either. IMHO, we should keep using node's lessc for now.

I agree that installing from the Ubuntu packages isn't ideal, because you'll get a quite old node, but it doesn't matter if all you want is to compile less, and it's simpler than using a PPA.

@vitorbaptista I worked around that first lesscpy issue (I think it was having trouble subtracting from a negative number) but now it seems to be in an endless loop.

How do we get a lessc that's old enough for the system node without a PPA? download it directly?

Eventually, the node and npm version gets too old. As it's happened with Ubuntu 12.04.

Hi amercader,
a few weeks ago I had the same issue you had in Ubuntu 14.04 (I am starting to develop on CKAN).
I wrote a mini-guide for me, and I think I solved the problem by:
sudo ln -s /usr/bin/nodejs /usr/bin/node

This is what I did in Ubuntu 14.04:

```
sudo apt-get install nodejs npm
```

#have your virtualenv active when you do this:
    . /usr/lib/ckan/default/bin/activate
    cd ~/ckan/lib/default/src/ckan

# and run:

```
 npm install less nodewatch
```

# Next

```
sudo ln -s /usr/bin/nodejs /usr/bin/node
. /usr/lib/ckan/default/bin/activate
cd ~/ckan/lib/default/src/ckan
```

   ./bin/less

@amercader It looks like we're bumping all the 14.04 issues to 2.4. Can this be bumped as well or do we want this one fixed for 2.3?


Resolving patch:
diff --git a/doc/conf.py b/doc/conf.py
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -45,7 +45,7 @@
 .. |datastore_user| replace:: datastore_default
 .. |test_database| replace:: ckan_test
 .. |test_datastore| replace:: datastore_test
-.. |apache_config_file| replace:: /etc/apache2/sites-available/ckan_default
+.. |apache_config_file| replace:: /etc/apache2/sites-available/ckan_default.conf
 .. |apache.wsgi| replace:: |config_dir|/apache.wsgi
 .. |data_dir| replace:: |config_dir|/data
 .. |sstore| replace:: |config_dir|/sstore
@@ -63,9 +63,10 @@
 .. |sqlalchemy| replace:: SQLAlchemy
 .. |javascript| replace:: JavaScript
 .. |apache| replace:: Apache
-.. |nginx_config_file| replace:: /etc/nginx/sites-available/ckan_default
+.. |nginx_config_file| replace:: /etc/nginx/sites-available/ckan
 .. |reload_nginx| replace:: sudo service nginx reload
 .. |jquery| replace:: jQuery
+.. |nodejs| replace:: Node.js
 
 .. _Jinja2: http://jinja.pocoo.org/
 .. _CKAN front page: http://127.0.0.1:5000
@@ -154,10 +155,10 @@ def latest_release_version():
     return version
 
 
-def latest_package_name():
+def latest_package_name(distro='trusty'):
     '''Return the filename of the Ubuntu package for the latest stable release.
 
-    e.g. "python-ckan_2.1_amd64.deb"
+    e.g. "python-ckan_2.1-trusty_amd64.deb"
 
     '''
     # We don't create a new package file name for a patch release like 2.1.1,
@@ -165,8 +166,8 @@ def latest_package_name():
     # have the X.Y part of the version number in them, not X.Y.Z.
     latest_minor_version = latest_release_version()[:3]
 
-    return 'python-ckan_{version}_amd64.deb'.format(
-        version=latest_minor_version)
+    return 'python-ckan_{version}-{distro}_amd64.deb'.format(
+        version=latest_minor_version, distro=distro)
 
 
 def write_latest_release_file():
@@ -192,14 +193,16 @@ def write_latest_release_file():
 
 .. |latest_release_tag| replace:: {latest_tag}
 .. |latest_release_version| replace:: {latest_version}
-.. |latest_package_name| replace:: {package_name}
+.. |latest_package_name_precise| replace:: {package_name_precise}
+.. |latest_package_name_trusty| replace:: {package_name_trusty}
 
 '''
     open(filename, 'w').write(template.format(
         filename=filename,
         latest_tag=latest_release_tag(),
         latest_version=latest_release_version(),
-        package_name=latest_package_name(),
+        package_name_precise=latest_package_name('precise'),
+        package_name_trusty=latest_package_name('trusty'),
         ))
 
 


Test patch:
diff --git a/ckanext/datapusher/tests/test.py b/ckanext/datapusher/tests/test.py
--- a/ckanext/datapusher/tests/test.py
+++ b/ckanext/datapusher/tests/test.py
@@ -47,11 +47,20 @@ def setup_class(cls):
         set_url_type(
             model.Package.get('annakarenina').resources, cls.sysadmin_user)
 
+        # Httpretty crashes with Solr on Python 2.6,
+        # skip the tests
+        if (sys.version_info[0] == 2 and sys.version_info[1] == 6):
+            raise nose.SkipTest()
+
     @classmethod
     def teardown_class(cls):
         rebuild_all_dbs(cls.Session)
         p.unload('datastore')
         p.unload('datapusher')
+        # Reenable Solr indexing
+        if (sys.version_info[0] == 2 and sys.version_info[1] == 6
+                and not p.plugin_loaded('synchronous_search')):
+            p.load('synchronous_search')
 
     def test_create_ckan_resource_in_package(self):
         package = model.Package.get('annakarenina')
diff --git a/ckanext/resourceproxy/tests/test_proxy.py b/ckanext/resourceproxy/tests/test_proxy.py
--- a/ckanext/resourceproxy/tests/test_proxy.py
+++ b/ckanext/resourceproxy/tests/test_proxy.py
@@ -1,7 +1,9 @@
+import sys
 import requests
 import unittest
 import json
 import httpretty
+import nose
 
 import paste.fixture
 from pylons import config
@@ -27,7 +29,8 @@ def set_resource_url(url):
     context = {
         'model': model,
         'session': model.Session,
-        'user': model.User.get('testsysadmin').name
+        'user': model.User.get('testsysadmin').name,
+        'use_cache': False,
     }
 
     resource = p.toolkit.get_action('resource_show')(
@@ -55,12 +58,20 @@ def setup_class(cls):
         wsgiapp = middleware.make_app(config['global_conf'], **config)
         cls.app = paste.fixture.TestApp(wsgiapp)
         create_test_data.CreateTestData.create()
+        # Httpretty crashes with Solr on Python 2.6,
+        # skip the tests
+        if (sys.version_info[0] == 2 and sys.version_info[1] == 6):
+            raise nose.SkipTest()
 
     @classmethod
     def teardown_class(cls):
         config.clear()
         config.update(cls._original_config)
         model.repo.rebuild_db()
+        # Reenable Solr indexing
+        if (sys.version_info[0] == 2 and sys.version_info[1] == 6
+                and not p.plugin_loaded('synchronous_search')):
+            p.load('synchronous_search')
 
     def setUp(self):
         self.url = 'http://www.ckan.org/static/example.json'