jazzband / django-pipeline

Pipeline is an asset packaging library for Django.
https://django-pipeline.readthedocs.io/
MIT License
1.52k stars 372 forks source link

compression errors when using Yuglify in django-pipeline on Windows #546

Open chancegraff opened 8 years ago

chancegraff commented 8 years ago

I've spent the last couple of days troubleshooting my pipeline setup in an attempt to get compression to work correctly without success. I was originally receiving a "file not found" error whenever attempting to collectstatic in my Django project, which was happening because the pipeline needed to be pointed to the Yuglify file with the YUGLIFY_BINARY setting.

After setting that, I began receiving the error "OSError: [WinError 193] %1 is not a valid Win32 application" during the compression step. The traceback showed that the error was happening just before the subprocess.py file was hit, in the pipeline\compressors\yuglify.py file:

  File "C:\Users\cgraf\Documents\Projects\django_react\manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Python34\lib\site-packages\django\core\management\__init__.py", line 354, in execute_from_command_line
    utility.execute()
  File "C:\Python34\lib\site-packages\django\core\management\__init__.py", line 346, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Python34\lib\site-packages\django\core\management\base.py", line 394, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Python34\lib\site-packages\django\core\management\base.py", line 445, in execute
    output = self.handle(*args, **options)
  File "C:\Python34\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 168, in handle
    collected = self.collect()
  File "C:\Python34\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 114, in collect
    for original_path, processed_path, processed in processor:
  File "C:\Python34\lib\site-packages\pipeline\storage.py", line 26, in post_process
    packager.pack_stylesheets(package)
  File "C:\Python34\lib\site-packages\pipeline\packager.py", line 96, in pack_stylesheets
    variant=package.variant, **kwargs)
  File "C:\Python34\lib\site-packages\pipeline\packager.py", line 106, in pack
    content = compress(paths, **kwargs)
  File "C:\Python34\lib\site-packages\pipeline\compressors\__init__.py", line 78, in compress_css
    css = getattr(compressor(verbose=self.verbose), 'compress_css')(css)
  File "C:\Python34\lib\site-packages\pipeline\compressors\yuglify.py", line 26, in compress_css
    return self.compress_common(css, 'css', settings.YUGLIFY_CSS_ARGUMENTS)
  File "C:\Python34\lib\site-packages\pipeline\compressors\yuglify.py", line 18, in compress_common
    return self.execute_command(command, content)
  File "C:\Python34\lib\site-packages\pipeline\compressors\__init__.py", line 247, in execute_command
    stdin=subprocess.PIPE, stderr=subprocess.PIPE)
  File "C:\Python34\lib\subprocess.py", line 859, in __init__
    restore_signals, start_new_session)
  File "C:\Python34\lib\subprocess.py", line 1114, in _execute_child
    startupinfo)

I eventually found a question on StackOverflow in which the author had modified their compressor file with the following code (which I also added to my YuglifyCompressor class):

    def execute_command(self, command, content):
        print("\tCommand: " + command.__str__())
        print("\tContent: " + content)

Now upon running the collectstatic command, I was greeted with a beautiful success message, but ultimately the compressed files were only filled with the text "None", so I haven't exactly figured this out just quite yet.

In the log, the above print commands did come through with some answers about what was being called and subsequently throwing the OSError:

        compress_css:
        compress_common:
        Command: (('C:\\Python34\\Lib\\site-packages\\pipeline\\compressors\\yuglify.py',), '--type=css', ('--terminal',))
        Content:
Post-processed 'C:\Users\cgraf\Documents\Projects\django_react\static\bin\css\main.css' as 'C:\Users\cgraf\Documents\Projects\django_react\static\bin\css\main.css'`
        compress_js: (function() {

        }).call(this);
        compress_common: (function() {

        }).call(this);
        Command: (('C:\\Python34\\Lib\\site-packages\\pipeline\\compressors\\yuglify.py',), '--type=js', ('--terminal',))
        Content: (function() {

        }).call(this);

Previously I had checked to make sure that my file type associations were set correctly to rule out the possibility that Windows was simply failing to recognize what .exe file needed to be executed for the .py files. Sadly everything looked normal:

>ftype Python.File
Python.File="C:\Python34\python.exe" "%1" %*
>assoc .py
.py=Python.File

Any help would be appreciated.

Edit: I've narrowed it down a little further and found that it's only throwing this error whenever attempting to compress CSS files:

Compression error: 'str' does not support the buffer interface // arguments: ['C:\\Users\\cgraf\\AppData\\Roaming\\npm\\yuglify.cmd', '--type=css', '--terminal']

As you can see the exception being caught now has changed, so I've updated the title of this issue to reflect that. This change happened because I changed the YUGLIFY_BINARY setting to point to the .cmd file instead of its JavaScript sibling. I also realized I hadn't posted my PIPELINE settings:

PIPELINE = {
    'PIPELINE_ENABLED': True,
    'COMPILERS': ('pipeline_browserify.compiler.BrowserifyCompiler',),
    'CSS_COMPRESSOR': 'pipeline.compressors.yuglify.YuglifyCompressor',
    'JS_COMPRESSOR': 'pipeline.compressors.yuglify.YuglifyCompressor',
    'YUGLIFY_BINARY': r'C:\Users\cgraf\AppData\Roaming\npm\yuglify.cmd',
    'BROWSERIFY_ARGUMENTS': '-t babelify',
    'STYLESHEETS': {
        'main': {
            'source_filenames': (
                os.path.join(BASE_DIR, "static", "css", "example", "*.css"),
            ),
            'output_filename': os.path.join(BASE_DIR, "static", "bin", "css", "main.css"),
        }
    },
    'JAVASCRIPT': {
        'main': {
            'source_filenames': (
                os.path.join(BASE_DIR, "static", "js", "example", "*.js"),
            ),
            'output_filename': os.path.join(BASE_DIR, "static", "bin", "js", "main.js"),
        }
    },
}

Edit 2: Alright, I've managed to get my JavaScript files running into the compressor at least, but it's failing inside. Here's the stacktrace:

Compression error: b'\r\nC:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\bin\\yuglify:77\r\n throw(err);\r\n ^\r\nError\r\n at new JS_Parse_Error (C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:263:18)\r\n at js_error (C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:271:11)\r\n at croak (C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:733:9)\r\n at token_error (C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:740:9)\r\n at unexpected (C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:746:9)\r\n at C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:1124:9\r\n at maybe_unary (C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:1209:19)\r\n at expr_ops (C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:1236:24)\r\n at maybe_conditional (C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:1240:20)\r\n at maybe_assign (C:\\Users\\cgraf\\AppData\\Roaming\\npm\\node_modules\\yuglify\\node_modules\\uglify-js\\lib\\parse-js.js:1264:20)\r\n' // arguments: ['C:\\Users\\cgraf\\AppData\\Roaming\\npm\\yuglify.cmd', '--type=js', '--terminal']

CameronSima commented 3 years ago

can this be merged pls?

GitRon commented 2 years ago

I have the same issue with the sass compiler (either node-sass or dart-sass) - works perfectly on the regular shell but not with django-pipeline. Any idea what I am doing wrong? I added the PRs code but I always get WinError 193 - not valid Win32 application.