ninetwozero / gradle-to-js

A quick & dirty Gradle build file to JavaScript object parser
Apache License 2.0
47 stars 21 forks source link

Parsing of a valid gradle file results in the error: Cannot assign to read only property '0' of object '[object String]' #7

Closed the-simian closed 7 years ago

the-simian commented 7 years ago
TypeError: Cannot assign to read only property '0' of object '[object String]'
    at assignKey (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:28:11)
    at assign (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:43:4)
    at assignKey (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:30:13)
    at assign (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:43:4)
    at deepAssign (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:64:3)
    at deepParse (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\gradle-to-js\lib\parser.js:135:27)
    at deepParse (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\gradle-to-js\lib\parser.js:137:27)
    at ReadStream.<anonymous> (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\gradle-to-js\lib\parser.js:392:13)
    at emitOne (events.js:96:13)
    at ReadStream.emit (events.js:191:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at ReadStream.Readable.push (_stream_readable.js:134:10)
    at onread (fs.js:1939:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:628:17)
the-simian commented 7 years ago

I have been able to reproduce the error, I'm zeroing in on why its breaking. it is related to this syntax:

    compile (project(':react-native-maps')) {
      exclude group: 'com.google.android.gms', module: 'play-services-base'
      exclude group: 'com.google.android.gms', module: 'play-services-maps'
    }
karllindmark commented 7 years ago

Hey Jesse!

Do you have any sample data that I can use to reproduce this unhandled error? 😊

Thanks for filing an issue!

Best regards, Karl Lindmark

On Sun, 9 Apr 2017 at 08:31, Jesse Harlin notifications@github.com wrote:

TypeError: Cannot assign to read only property '0' of object '[object String]' at assignKey (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:28:11) at assign (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:43:4) at assignKey (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:30:13) at assign (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:43:4) at deepAssign (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:64:3) at deepParse (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\gradle-to-js\lib\parser.js:135:27) at deepParse (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\gradle-to-js\lib\parser.js:137:27) at ReadStream. (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\gradle-to-js\lib\parser.js:392:13) at emitOne (events.js:96:13) at ReadStream.emit (events.js:191:7) at readableAddChunk (_stream_readable.js:176:18) at ReadStream.Readable.push (_stream_readable.js:134:10) at onread (fs.js:1939:12) at FSReqWrap.wrapper [as oncomplete] (fs.js:628:17)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ninetwozero/gradle-to-js/issues/7, or mute the thread https://github.com/notifications/unsubscribe-auth/AA7w0HNFg2HA-NgH1lY2unUNTbdWIMoNks5ruHssgaJpZM4M38GH .

the-simian commented 7 years ago

ok, by rearranging my compile statements, I can get the parser to not-break, but the resultant parsed js file is actually incorrect. Some excluded libraries are not present, and not associated with the right compile key I'll try to get this file paired down to the absolute bare minimum. give me a little time, I think I'm zeroing in on it. I'll push this up to repo for you to be able to run to repro in a bit. Thanks for replying..

the-simian commented 7 years ago

ok I got it working to a super-barebones test case: https://github.com/the-simian/gradle-to-js-test

the-simian commented 7 years ago

for convenience: https://github.com/the-simian/gradle-to-js-test/issues/1

Ok, I'll now post a description of what I am seeing:

you can run the example I posted yourself by just running the index file node index.js

in one file I've got the contents in this order:

dependencies {
  compile (project(':react-native-maps')) {
    exclude group: 'com.google.android.gms', module: 'play-services-base'
    exclude group: 'com.google.android.gms', module: 'play-services-maps'
  }
  compile (project(':react-native-background-geolocation')) {
    exclude group: 'com.google.android.gms', module: 'play-services-location'
  }
}

This does not break the parser and results in this output:

{ dependencies: { compile: { exclude: 'group: \'com.google.android.gms\', module: \'play-services-location\'\r' } },
  '\r': '' }

(which doesn't seem totally correct)

rearranging the modules to this order:

dependencies {
  compile (project(':react-native-background-geolocation')) {
    exclude group: 'com.google.android.gms', module: 'play-services-location'
  }
  compile (project(':react-native-maps')) {
    exclude group: 'com.google.android.gms', module: 'play-services-base'
    exclude group: 'com.google.android.gms', module: 'play-services-maps'
  }
}

results in an error in deep-assign:

E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:28
                to[key] = val;
                        ^

TypeError: Cannot assign to read only property '0' of object '[object String]'
    at assignKey (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:28:11)
    at assign (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:43:4)
    at assignKey (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:30:13)
    at assign (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:43:4)
    at deepAssign (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\deep-assign\index.js:64:3)
    at deepParse (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\gradle-to-js\lib\parser.js:135:27)
    at deepParse (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\gradle-to-js\lib\parser.js:137:27)
    at ReadStream.<anonymous> (E:\Users\Simian\Desktop\gradle-to-js-test\node_modules\gradle-to-js\lib\parser.js:392:13)
    at emitOne (events.js:96:13)
    at ReadStream.emit (events.js:191:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at ReadStream.Readable.push (_stream_readable.js:134:10)
    at onread (fs.js:1939:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:628:17)
the-simian commented 7 years ago

For my usage (and also code-push's usage of this module - I don't think we care about the dependencies. We only need the information to get the versionName.

For this reason I'll get by.

I'm going to close the issue on their project, and leave this here.

this might also help you: I am logging what is in the parser's out value during the deepParse:

WORKING------------------------
{ exclude:
   [ 'group: \'com.google.android.gms\', module: \'play-services-base\'\r',
     'group: \'com.google.android.gms\', module: \'play-services-maps\'\r' ] }
{ exclude: 'group: \'com.google.android.gms\', module: \'play-services-location\'\r' }
{ compile: { exclude: 'group: \'com.google.android.gms\', module: \'play-services-location\'\r' } }
{ dependencies: { compile: { exclude: 'group: \'com.google.android.gms\', module: \'play-services-location\'\r' } },
  '\r': '' }
{ dependencies: { compile: { exclude: 'group: \'com.google.android.gms\', module: \'play-services-location\'\r' } },
  '\r': '' }
BROKEN------------------------
{ exclude: 'group: \'com.google.android.gms\', module: \'play-services-location\'\r' }
{ exclude:
   [ 'group: \'com.google.android.gms\', module: \'play-services-base\'\r',
     'group: \'com.google.android.gms\', module: \'play-services-maps\'\r' ] }

I can see that at that point, the JSON seems to have been formed correctly thusfar

the-simian commented 7 years ago

I've found that the code is breaking when deepAssign is called on a non-object (or non-array) for out[currentKey] on line 135.

here: https://github.com/ninetwozero/gradle-to-js/blob/master/lib/parser.js#L135

the-simian commented 7 years ago

I can get the parser to at least produce some sort of result by doing this:

if(!Array.isArray(out[currentKey])){
     out[currentKey] = [out[currentKey]]
}
out[currentKey] = deepAssign({}, out[currentKey], deepParse(chunk, state, keepFunctionCalls, skipEmptyValues));

here the new output (which is not a really accurate representation of the file)

  //WORKING------------------------
  {
      "dependencies": {
          "compile": {
              "0": {
                  "exclude": [
                    "group: 'com.google.android.gms', module: 'play-services-base'\r",
                    "group: 'com.google.android.gms', module: 'play-services-maps'\r"
                  ]
              },
              "exclude":"group: 'com.google.android.gms', module: 'play-services-location'\r"
          }
      },
      "\r": ""
  }
  //(formerly)BROKEN------------------------
  {
      "dependencies": {
          "compile": {
              "0": {
                  "exclude": "group: 'com.google.android.gms', module: 'play-services-location'\r"
              },
              "exclude": [
                "group: 'com.google.android.gms', module: 'play-services-base'\r",
                "group: 'com.google.android.gms', module: 'play-services-maps'\r"
              ]
          }
      },
      "\r": ""
  }
karllindmark commented 7 years ago

I just noticed that my e-mail client had been lagging behind, making my previous response a bit weird - ha.

That said, thanks for the very thorough investigation!

I'll have to dig around a bit in everything you've posted above, and get back to you ASAP! :-)

the-simian commented 7 years ago

Sounds great! I won't have time to work on a possible PR for a few days, but I think the way the 'compile' section is parsed can be made to handle more situations. I'll keep an eye on this, and support as I can.

karllindmark commented 7 years ago

Hey Jesse!

First thing's first - sorry for the really belated response! I kinda forgot about it after giving it a quick look, only to forget about it even more until #8 popped up. Hmm. 🤔

Could you give #9 a look and see if it lives up to your expectations?

Thanks!

sterlingwes commented 7 years ago

We were able to resolve our specific situation for now using the parentheses format in our gradle file:

    compile (project(':react-native-maps')) {
      exclude(group: 'com.google.android.gms', module: 'play-services-base')
      exclude(group: 'com.google.android.gms', module: 'play-services-maps')
    }
SamMatthewsIsACommonName commented 7 years ago

re ordering the compile instructions worked for me, cheers

karllindmark commented 7 years ago

Roger that! I'll be pushing out #9 as v1.0.1, where no reordering should be needed. You'll also get the data back in a more normalized fashion, so it's a bit more helpful when/if you actually want the dependency information.

👋

the-simian commented 7 years ago

@karllindmark Sorry I haven't been able to reply, I've been really overwhelmed with work, myself. Looks like you've put some hard work into this! Thank you!