sysgears / grain

Grain is a lightweight and powerful static website generator with custom themes to help create static, SEO-friendly websites or a blog in no time.
https://sysgears.com/grain
Other
160 stars 30 forks source link

StackOverflow during generate #9

Closed altavir closed 9 years ago

altavir commented 9 years ago

Preview is working fine but when i am trying to either run generate task or run grainw.generate, I am getting StackOveflow cycle:

java.lang.StackOverflowError
    at java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:72)
    at sun.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.MethodMetaProperty$GetBeanMethodMetaProperty.getProperty(MethodMetaProperty.java:73)
    at org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.callGetProperty(GetEffectivePogoPropertySite.java:47)
    at com.sysgears.grain.translator.writer.ScriptWriter.calculateMaxChars(ScriptWriter.groovy:55)
    at com.sysgears.grain.translator.writer.ScriptWriter.write(ScriptWriter.groovy:84)
    at com.sysgears.grain.translator.writer.ScriptWriter.write(ScriptWriter.groovy)
    at com.sysgears.grain.translator.writer.ScriptWriter$write$2.callCurrent(Unknown Source)
    at com.sysgears.grain.translator.writer.ScriptWriter.write(ScriptWriter.groovy:89)
    at com.sysgears.grain.translator.writer.ScriptWriter.write(ScriptWriter.groovy)
    at com.sysgears.grain.translator.writer.ScriptWriter$write$2.callCurrent(Unknown Source)
    at com.sysgears.grain.translator.writer.ScriptWriter.write(ScriptWriter.groovy:89)
...

I am getting the same behavior with gradle 1.8 and 2.6.

Update: With little debugging I found that problem is narrowed to this method:

    private def calculateMaxChars(StatementType statement) {
        def maxChars = MAX_LINE_LENGTH - statement.closeStr.trim().length() - lineLength
        if (curStatement != statement) {
            maxChars -= curStatement.closeStr.trim().length() + statement.openStr.length()
        }

        maxChars
    }

With curStatement = "PLAIN_CODE" and statment = "GSTRING_WRITE" it always produces zero which causes the loop.

altavir commented 9 years ago

The bug appears while using bootstrap 3.3.5 stylesheets. After I have deleted all unnecessary files, everything works fine.

dmitriypdv commented 9 years ago

The default behavior for Grain is to parse and run embedded Groovy code ${ ... } for all the non-binary template files, this often comes in handy for passing configuration parameters from the page model to javascript or stylesheets. In this case, it looks like Grain finds ${ in the bootstrap files and tries to parse the presumed Groovy code which causes the error.

To disable this you can add the file extension to the list of non-script files in the SiteConfig.groovy:

non_script_files = [/(?i).*\.(js|css)$/]

We are going to add the default configuration in the next revision, so users won't encounter the error after adding third-party files to the project.

altavir commented 9 years ago

Ok, thank you, I think this solves the problem. By the way, thank you for the great tool. It would be good to have basic JBake-like predefined templates for simple projects.