alexo / wro4j

New project location is:https://github.com/wro4j/wro4j
442 stars 110 forks source link

incrementalBuild breaks with different groups using same resources #209

Open muffl0n opened 10 years ago

muffl0n commented 10 years ago

In my project muffl0n/wro4j-scss-test I have two different groups using two different scss-files: wro.xml:

<groups xmlns="http://www.isdc.ro/wro">
    <group name="base">
        <css minimize="true">/scss/base.scss</css>
    </group>
    <group name="base2">
        <css minimize="true">/scss/base2.scss</css>
    </group>
</groups>

The base.scss and base2.scss however both import the same header.scss:

@import 'header.scss';

On the first run the plugin does just fine:

[INFO] --- wro4j-maven-plugin:1.7.7-SNAPSHOT:run (css_test) @ test ---
[INFO] /home/svs/git/wro4j-scss-test/src/main/webapp
[INFO] Executing the mojo: 
[INFO] Wro4j Model path: /home/svs/git/wro4j-scss-test/src/main/webapp/WEB-INF/classes/wro.xml
[INFO] targetGroups: base
[INFO] minimize: true
[INFO] ignoreMissingResources: false
[INFO] parallelProcessing: true
[INFO] buildDirectory: /home/svs/git/wro4j-scss-test/target
[INFO] destinationFolder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated
[INFO] wroManagerFactory class: ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory
[INFO] The following groups will be processed: [base]
[INFO] folder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated
[INFO] folder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated
[INFO] processing group: base.js
[INFO] processing group: base.css
[INFO] file size: base.css -> 27 bytes
[INFO] /home/svs/git/wro4j-scss-test/src/main/webapp/generated/base.css (27 bytes)
[INFO] 
[INFO] --- wro4j-maven-plugin:1.7.7-SNAPSHOT:run (css_test2) @ test ---
[INFO] /home/svs/git/wro4j-scss-test/src/main/webapp
[INFO] Executing the mojo: 
[INFO] Wro4j Model path: /home/svs/git/wro4j-scss-test/src/main/webapp/WEB-INF/classes/wro.xml
[INFO] targetGroups: base2
[INFO] minimize: true
[INFO] ignoreMissingResources: false
[INFO] parallelProcessing: true
[INFO] buildDirectory: /home/svs/git/wro4j-scss-test/target
[INFO] destinationFolder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated2
[INFO] wroManagerFactory class: ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory
[INFO] The following groups will be processed: [base2]
[INFO] folder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated2
[INFO] folder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated2
[INFO] processing group: base2.css
[INFO] processing group: base2.js
[INFO] file size: base2.css -> 27 bytes
[INFO] /home/svs/git/wro4j-scss-test/src/main/webapp/generated2/base2.css (27 bytes)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.814s
[INFO] Finished at: Fri Sep 19 10:39:42 CEST 2014
[INFO] Final Memory: 24M/103M
[INFO] ------------------------------------------------------------------------

But after changing the header.scss from

#header {
  width: 101%;
}

to

#header {
  width: 100%;
}

only the first group get's regenerated:

[INFO] --- wro4j-maven-plugin:1.7.7-SNAPSHOT:run (css_test) @ test ---
[INFO] /home/svs/git/wro4j-scss-test/src/main/webapp
[INFO] Executing the mojo: 
[INFO] Wro4j Model path: /home/svs/git/wro4j-scss-test/src/main/webapp/WEB-INF/classes/wro.xml
[INFO] targetGroups: base
[INFO] minimize: true
[INFO] ignoreMissingResources: false
[INFO] parallelProcessing: true
[INFO] buildDirectory: /home/svs/git/wro4j-scss-test/target
[INFO] destinationFolder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated
[INFO] wroManagerFactory class: ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory
[INFO] The following groups will be processed: [base]
[INFO] folder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated
[INFO] folder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated
[INFO] processing group: base.css
[INFO] processing group: base.js
[INFO] file size: base.css -> 27 bytes
[INFO] /home/svs/git/wro4j-scss-test/src/main/webapp/generated/base.css (27 bytes)
[INFO] 
[INFO] --- wro4j-maven-plugin:1.7.7-SNAPSHOT:run (css_test2) @ test ---
[INFO] /home/svs/git/wro4j-scss-test/src/main/webapp
[INFO] Executing the mojo: 
[INFO] Wro4j Model path: /home/svs/git/wro4j-scss-test/src/main/webapp/WEB-INF/classes/wro.xml
[INFO] targetGroups: base2
[INFO] minimize: true
[INFO] ignoreMissingResources: false
[INFO] parallelProcessing: true
[INFO] buildDirectory: /home/svs/git/wro4j-scss-test/target
[INFO] destinationFolder: /home/svs/git/wro4j-scss-test/src/main/webapp/generated2
[INFO] wroManagerFactory class: ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory
[INFO] Nothing to process (nothing configured or nothing changed since last build).
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.806s
[INFO] Finished at: Fri Sep 19 10:39:58 CEST 2014
[INFO] Final Memory: 24M/106M
[INFO] ------------------------------------------------------------------------

The problem seems to be that on the first plugin execution "css_test" the new fingerprint for header.scss get's written to the fallbackStorage. On the second execution "css_test2" the "previousFingerprint" is the one that was just written to the fallbackStorage by the first execution and not that one that was written there by the previouse run of the plugin. See: ro.isdc.wro.maven.plugin.support.ResourceChangeHandler.isResourceChanged(Resource).previousFingerprint

So in fact, if two executions share the same resources they have a problem sharing the same fallbackStorage, too.

alexo commented 10 years ago

This one is tricky :)

muffl0n commented 10 years ago

Thanks go out to my coworker who stresses wro4j with cascaded imports as if there were no tomorrow. :)

The only reason it works on the first run seems to be that the directory "generated2" does not exist. See ro.isdc.wro.maven.plugin.Wro4jMojo.isIncrementalCheckRequired():

@Override
  protected boolean isIncrementalCheckRequired() {
    return super.isIncrementalCheckRequired() && destinationFolder.exists();
  }
alexo commented 10 years ago

A possible solution could be holding a storage per group (which is expensive), or treating import statements differently when dealing with change detection...

muffl0n commented 10 years ago

My first idea was to store the hashes not only by path

/scss/header.scss=77141eb86ceb6a88beabe40d81fd1a65b5ce9e64

but also by group

base:/scss/header.scss=77141eb86ceb6a88beabe40d81fd1a65b5ce9e64
base2:/scss/header.scss=77141eb86ceb6a88beabe40d81fd1a65b5ce9e64

But I'm not sure if this is a good solution.

alexo commented 10 years ago

This is similar to have storage per group. The disadvantage is that there will be multiple checks for change for the same resource when it is referred from different groups.

I would prefer not checking twice for change. Instead of keeping a Map<String, Boolean> (<uri>, <change flag>), to keep Map<String, Map<String, Boolean> (where map holds the flag for each group).