bower / bower

A package manager for the web
bower.io
MIT License
14.99k stars 1.85k forks source link

Bower@1.7.1 Problem if Path is Github zip location #2101

Closed it-sumanp closed 8 years ago

it-sumanp commented 8 years ago

I my project I am having "Sankey": "https://github.com/tamc/Sankey/archive/master.zip", This give "Could not find the End of Central Directory Record" error ..in bower@1.7.1 but when i downgrade bower to 1.7.0 it worked fine

sheerun commented 8 years ago

Works for me.. Can you provide your platform details?

benmann commented 8 years ago

Works here as well :whale:
I'm on OS X 10.10.5 npm: 3.3.12 node: 0.10.35

it-sumanp commented 8 years ago

node @ v0.12.4 npm @2.10.1 MAC OS X 10.10.5

green-arrow commented 8 years ago

Same issue here when using a Github ZIP path.

node@0.12.2
npm@2.10.0
OSX 10.11.2
sheerun commented 8 years ago

@Utsav2 I think it might be https://github.com/bower/bower/commit/cdf45239f4853ce7d9ccd6b146ea84194bcf52fa

Could you verify it on node 0.12 on osx?

Utsav2 commented 8 years ago

That commit wasn't merged till yesterday, so it's not a part of 1.7.1, and the issue is something else.

sheerun commented 8 years ago

Hmm. Right

wkoffel commented 8 years ago

I can confirm that reverting to 1.7.0 fixed this issue for me.

sheerun commented 8 years ago

Could you all help to pinpoint the issue? It's either one of commits since 1.7.0 or updated dependency (Bower bundles dependencies on releases)

tgrux commented 8 years ago

I've spent about 4 hours trying to figure out our missing bower packages and discovered it to be related to 1.7.1. It seems to be randomly downloading and extracting gitHub packages in a weird way. It is excluding content, mainly the .bower config "main" param. This results in our gulp process NOT moving any files to the build directory and thus breaking our build. Rolling our bower version back to 1.7.0 seems to have fixed this.

bmcallis commented 8 years ago

I've confirmed that it's an issue with node 0.12 and bower 1.7.1. I was able to successfully bower install with the latest version of 0.10, 4 and 5.

imsky commented 8 years ago

can confirm this with 1.7.1 too

Utsav2 commented 8 years ago

What's weird is that I can reproduce the bug when I do npm install -g bower, but if I checkout 87cf578 (1.7.1 tagged release) and npm install -g, it works perfectly fine, making it impossible to debug. My guess is something went wrong with a bundled dependency.

If someone who had this issue can try this: npm uninstall -g bower git clone https://github.com/bower/bower.git git checkout 87cf578 npm install -g

And see if it solves it?

git diff 338ac99..87cf578 -- lib/* (between 1.7.0 and 1.7.1) doesn't seem to show any change which should break unzipping files.

tgrux commented 8 years ago

@Utsav2 I tried installing bower directly as you suggested and branch 87cf578 does not have this issue. I did verify this issue again though and can consistently produce the error when using 1.7.1 installed with NPM.

vchekan commented 8 years ago

Just to reiterate #2108. I have a project with maybe 15 packages (Polymer). Tracing showed that they were tar.gz packages, so seems it is not .zip specific. Once I discovered that cache is corrupt, I cleaned cache and re-downloaded. Every time I did so, different package(s) become corrupt. So the error was intermittent (github glitches?). After 4 or 5 retry, I finally got to the state where my project gave no errors. But I still have no confidence that all packages are correct, maybe more errors are just waiting :(

sheerun commented 8 years ago

Could you write tests to reproduce? Or something to reproduce?

vchekan commented 8 years ago

Unfortunately I do not know what happen, thus I don't know what unit test needs to do. As pointed by @BenMann, there is a check in the code for ContentLength field. This could be unit tested. But I am not sure what would happen if http would use chunked transfer encoding. There is no content-length http field in this case. Also it is potential possibility that for whatever reason server would cache incomplete package body...

sheerun commented 8 years ago

It is unit tested: https://github.com/bower/bower/blob/master/test/util/download.js#L160-L176

Maybe the issue is in extractor?

Utsav2 commented 8 years ago

@sheerun check out the mine and @tgrux's comments above, it doesn't seem like an issue in bower's code, and it's hard to debug, as it tends to disappear if we install bower from the repo directly.

vchekan commented 8 years ago

Ok, new info. I managed to reproduce it and compared bower_components folders.

As you can see, 2 files are incomplete and there is a bunch of missing. But it puzzle me even more. If it was premature https stream termination, than just one file would be incomplete.

diff -ru bower_components.bad/paper-behaviors/demo/paper-radio-button.html bower_components.good/paper-behaviors/demo/paper-radio-button.html
--- bower_components.bad/paper-behaviors/demo/paper-radio-button.html   2015-12-17 18:49:10.000000000 -0800
+++ bower_components.good/paper-behaviors/demo/paper-radio-button.html  2015-11-20 16:48:00.000000000 -0800
@@ -37,4 +37,84 @@
     position: absolute;
     top: 0px;
     left: 0px;
-    
\ No newline at end of file
+    width: 12px;
+    height: 12px;
+    border-radius: 50%;
+    border: solid 2px;
+    border-color: black;
+    transition: border-color 0.28s;
+  }
+
+  #onRadio {
+    position: absolute;
+    top: 4px;
+    left: 4px;
+    width: 8px;
+    height: 8px;
+    border-radius: 50%;
+    background-color: red;
+    -webkit-transform: scale(0);
+    transform: scale(0);
+    transition: -webkit-transform ease 0.28s;
+    transition: transform ease 0.28s;
+  }
+
+  :host([disabled]) {
+    opacity: 0.3;
+    pointer-events: none;
+  }
+
+  :host([pressed]) #offRadio,
+  :host([active]) #offRadio {
+    border-color: red;
+  }
+
+  :host([pressed]) #onRadio,
+  :host([active]) #onRadio {
+    -webkit-transform: scale(1);
+    transform: scale(1);
+  }
+
+  #ink {
+    position: absolute;
+    top: -16px;
+    left: -16px;
+    width: 48px;
+    height: 48px;
+  }
+
+  </style>
+
+  <template>
+    <div id="radioContainer">
+      <div id="offRadio"></div>
+      <div id="onRadio"></div>
+    </div>
+  </template>
+
+  <script>
+
+    Polymer({
+
+      behaviors: [
+        Polymer.PaperCheckedElementBehavior
+      ],
+
+      hostAttributes: {
+        role: 'radio'
+      },
+
+      ready: function() {
+        this.toggles = true;
+      },
+
+      _createRipple: function() {
+        this._rippleContainer = this.$.radioContainer;
+        return Polymer.PaperInkyFocusBehaviorImpl._createRipple.call(this);
+      }
+
+    });
+
+  </script>
+
+</dom-module>
Only in bower_components.good/paper-behaviors: index.html
Only in bower_components.good/paper-behaviors: paper-button-behavior.html
Only in bower_components.good/paper-behaviors: paper-checked-element-behavior.html
Only in bower_components.good/paper-behaviors: paper-inky-focus-behavior.html
Only in bower_components.good/paper-behaviors: paper-ripple-behavior.html
Only in bower_components.good/paper-behaviors: test
diff -ru bower_components.bad/paper-ripple/paper-ripple.html bower_components.good/paper-ripple/paper-ripple.html
--- bower_components.bad/paper-ripple/paper-ripple.html 2015-12-17 18:49:10.000000000 -0800
+++ bower_components.good/paper-ripple/paper-ripple.html    2015-11-18 10:22:06.000000000 -0800
@@ -459,4 +459,299 @@
          * @default 0.25
          */
         initialOpacity: {
-          t
\ No newline at end of file
+          type: Number,
+          value: 0.25
+        },
+
+        /**
+         * How fast (opacity per second) the wave fades out.
+         *
+         * @attribute opacityDecayVelocity
+         * @type number
+         * @default 0.8
+         */
+        opacityDecayVelocity: {
+          type: Number,
+          value: 0.8
+        },
+
+        /**
+         * If true, ripples will exhibit a gravitational pull towards
+         * the center of their container as they fade away.
+         *
+         * @attribute recenters
+         * @type boolean
+         * @default false
+         */
+        recenters: {
+          type: Boolean,
+          value: false
+        },
+
+        /**
+         * If true, ripples will center inside its container
+         *
+         * @attribute recenters
+         * @type boolean
+         * @default false
+         */
+        center: {
+          type: Boolean,
+          value: false
+        },
+
+        /**
+         * A list of the visual ripples.
+         *
+         * @attribute ripples
+         * @type Array
+         * @default []
+         */
+        ripples: {
+          type: Array,
+          value: function() {
+            return [];
+          }
+        },
+
+        /**
+         * True when there are visible ripples animating within the
+         * element.
+         */
+        animating: {
+          type: Boolean,
+          readOnly: true,
+          reflectToAttribute: true,
+          value: false
+        },
+
+        /**
+         * If true, the ripple will remain in the "down" state until `holdDown`
+         * is set to false again.
+         */
+        holdDown: {
+          type: Boolean,
+          value: false,
+          observer: '_holdDownChanged'
+        },
+
+        /**
+         * If true, the ripple will not generate a ripple effect
+         * via pointer interaction.
+         * Calling ripple's imperative api like `simulatedRipple` will
+         * still generate the ripple effect.
+         */
+        noink: {
+          type: Boolean,
+          value: false
+        },
+
+        _animating: {
+          type: Boolean
+        },
+
+        _boundAnimate: {
+          type: Function,
+          value: function() {
+            return this.animate.bind(this);
+          }
+        }
+      },
+
+      get target () {
+        var ownerRoot = Polymer.dom(this).getOwnerRoot();
+        var target;
+
+        if (this.parentNode.nodeType == 11) { // DOCUMENT_FRAGMENT_NODE
+          target = ownerRoot.host;
+        } else {
+          target = this.parentNode;
+        }
+
+        return target;
+      },
+
+      keyBindings: {
+        'enter:keydown': '_onEnterKeydown',
+        'space:keydown': '_onSpaceKeydown',
+        'space:keyup': '_onSpaceKeyup'
+      },
+
+      attached: function() {
+        // Set up a11yKeysBehavior to listen to key events on the target,
+        // so that space and enter activate the ripple even if the target doesn't
+        // handle key events. The key handlers deal with `noink` themselves.
+        this.keyEventTarget = this.target;
+        this.listen(this.target, 'up', 'uiUpAction');
+        this.listen(this.target, 'down', 'uiDownAction');
+      },
+
+      detached: function() {
+        this.unlisten(this.target, 'up', 'uiUpAction');
+        this.unlisten(this.target, 'down', 'uiDownAction');
+      },
+
+      get shouldKeepAnimating () {
+        for (var index = 0; index < this.ripples.length; ++index) {
+          if (!this.ripples[index].isAnimationComplete) {
+            return true;
+          }
+        }
+
+        return false;
+      },
+
+      simulatedRipple: function() {
+        this.downAction(null);
+
+        // Please see polymer/polymer#1305
+        this.async(function() {
+          this.upAction();
+        }, 1);
+      },
+
+      /**
+       * Provokes a ripple down effect via a UI event,
+       * respecting the `noink` property.
+       * @param {Event=} event
+       */
+      uiDownAction: function(event) {
+        if (!this.noink) {
+          this.downAction(event);
+        }
+      },
+
+      /**
+       * Provokes a ripple down effect via a UI event,
+       * *not* respecting the `noink` property.
+       * @param {Event=} event
+       */
+      downAction: function(event) {
+        if (this.holdDown && this.ripples.length > 0) {
+          return;
+        }
+
+        var ripple = this.addRipple();
+
+        ripple.downAction(event);
+
+        if (!this._animating) {
+          this.animate();
+        }
+      },
+
+      /**
+       * Provokes a ripple up effect via a UI event,
+       * respecting the `noink` property.
+       * @param {Event=} event
+       */
+      uiUpAction: function(event) {
+        if (!this.noink) {
+          this.upAction(event);
+        }
+      },
+
+      /**
+       * Provokes a ripple up effect via a UI event,
+       * *not* respecting the `noink` property.
+       * @param {Event=} event
+       */
+      upAction: function(event) {
+        if (this.holdDown) {
+          return;
+        }
+
+        this.ripples.forEach(function(ripple) {
+          ripple.upAction(event);
+        });
+
+        this.animate();
+      },
+
+      onAnimationComplete: function() {
+        this._animating = false;
+        this.$.background.style.backgroundColor = null;
+        this.fire('transitionend');
+      },
+
+      addRipple: function() {
+        var ripple = new Ripple(this);
+
+        Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
+        this.$.background.style.backgroundColor = ripple.color;
+        this.ripples.push(ripple);
+
+        this._setAnimating(true);
+
+        return ripple;
+      },
+
+      removeRipple: function(ripple) {
+        var rippleIndex = this.ripples.indexOf(ripple);
+
+        if (rippleIndex < 0) {
+          return;
+        }
+
+        this.ripples.splice(rippleIndex, 1);
+
+        ripple.remove();
+
+        if (!this.ripples.length) {
+          this._setAnimating(false);
+        }
+      },
+
+      animate: function() {
+        var index;
+        var ripple;
+
+        this._animating = true;
+
+        for (index = 0; index < this.ripples.length; ++index) {
+          ripple = this.ripples[index];
+
+          ripple.draw();
+
+          this.$.background.style.opacity = ripple.outerOpacity;
+
+          if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
+            this.removeRipple(ripple);
+          }
+        }
+
+        if (!this.shouldKeepAnimating && this.ripples.length === 0) {
+          this.onAnimationComplete();
+        } else {
+          window.requestAnimationFrame(this._boundAnimate);
+        }
+      },
+
+      _onEnterKeydown: function() {
+        this.uiDownAction();
+        this.async(this.uiUpAction, 1);
+      },
+
+      _onSpaceKeydown: function() {
+        this.uiDownAction();
+      },
+
+      _onSpaceKeyup: function() {
+        this.uiUpAction();
+      },
+
+      // note: holdDown does not respect noink since it can be a focus based
+      // effect.
+      _holdDownChanged: function(newVal, oldVal) {
+        if (oldVal === undefined) {
+          return;
+        }
+        if (newVal) {
+          this.downAction();
+        } else {
+          this.upAction();
+        }
+      }
+    });
+  })();
+</script>
Only in bower_components.good/paper-ripple: test
vchekan commented 8 years ago

My project:

{
  "name": "test1",
  "version": "0.0.0",
  "authors": [
    "Vadim Chekan"
  ],
  "description": "test",
  "keywords": [
    "test"
  ],
  "license": "test",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "polymer": "Polymer/polymer#^1.2.0",
    "paper-toolbar": "PolymerElements/paper-toolbar#~1.1.2",
    "paper-icon-button": "PolymerElements/paper-icon-button#~1.0.6"
  }
}
benmann commented 8 years ago

Maybe the issue is in extractor?

Just what I thought next, after checking the downloader. We use three libraries in the extractor that seem relevant: zlib, tar-fs and our own repo decompress-zip.. none of those changed in the last release and I think their dependencies didn't either. What I thought could be relevant is changes to the node streaming API, which we maybe didn't account for.. BUT all this seems irrelevant as @Utsav2 pointed out, cause it all works fine if you checkout https://github.com/bower/bower/commit/87cf578ba82e3d0eca4e5869469be85c4669cd23.
Right now I cannot reproduce this and I'd be highly interested how anyone of you actually get's to that point. Different people have different versions of node AND npm and still get the same result. No matter which setup of the above I try to emulate with my versions, I cannot reproduce. :persevere:

sheerun commented 8 years ago

I really can't reproduce it.. Even with Network Conditioner set on "Very Bad Network" Also I've checked and there's literally no difference between version published on npm and 1.7.1 tag, including dependencies.

sheerun commented 8 years ago

@it-sumanp @green-arrow @vchekan Maybe you could prepare Docker image that reproduces?

pkosenko commented 8 years ago

Can anyone remind me HOW one REVERTS a bower update using NPM, or downgrades to an earlier stable version?

I made the mistake of updating Bower to 1.7.1 when the "update available" message came through. (This is why we tend to get paranoid about updating things) "bower install" now refuses to install the latest Polymer Starter Kit 1.0 bower components. Bower seems to fail on trying to unpack a .gz zip file on Windows. It may be looking for the file in the wrong place?

I am running on Windows 7. I am running npm version 2.7.4 I am running bower version 1.7.1 (latest)


events.js:85 throw er; // Unhandled 'error' event ^ Error: ENOENT, rename 'C:\Users\pkosenko\AppData\Local\Temp\peter-kosenko-pkosenko\bower\c2d88334ceaa31e4b9aaa450cbde234e-836-znV3zB\archive.tar.gz.3582844010' at Error (native)


Other bower components are NOT in a "peter-kosenko-pkosenko" subfolder. No such folder exists, and it doesn't make sense, since we are already in the user temp folder anyway. If Bower1.7.1 is actually trying to look there, it has a MAJOR bug.

green-arrow commented 8 years ago

@pkosenko you can run the following to install a specific version:

npm install -g bower@1.7.0
pkosenko commented 8 years ago

Yes, thanks . . . I looked that one up before you posted. I don't do npm revert a lot.

pkosenko commented 8 years ago

I reverted to 1.6.8, which was working fine for me, and the error went away. So . . . it is definitely a bug in version 1.7.1. I'll have to try 1.7.0 later.

jcope2013 commented 8 years ago

I am reproducing it seemingly jumping between bower versions 1.7.1, 1.7.0, 1.6.8, etc I am uninstalling and reinstalling each new version but the issue persists, the only thing I have found that works for me is the solution @Utsav2 of cloning the repo/checking out a branch/npm install -g

node 0.12.9 npm 2.14.9 OS X 10.11.2

mmelvin0 commented 8 years ago

Here's a simple bower.json which causes the issue for me every time: https://gist.github.com/mmelvin0/d4588ccabebe3b32ecc6

Bower: 1.7.1 (problem goes away after npm install -g bower@1.7.0) Node: 0.12.9 (from homebrew/versions/node012) NPM: 2.14.15 OS: Mac OS X 10.11.2

Here's the stack trace:

Error: Could not find the End of Central Directory Record
    at DecompressZip.findEndOfDirectory (/usr/local/lib/node_modules/bower/node_modules/decompress-zip/lib/decompress-zip.js:165:15)
    at _fulfilled (/usr/local/lib/node_modules/bower/node_modules/q/q.js:834:54)
    at self.promiseDispatch.done (/usr/local/lib/node_modules/bower/node_modules/q/q.js:863:30)
    at Promise.promise.promiseDispatch (/usr/local/lib/node_modules/bower/node_modules/q/q.js:796:13)
    at /usr/local/lib/node_modules/bower/node_modules/q/q.js:604:44
    at runSingle (/usr/local/lib/node_modules/bower/node_modules/q/q.js:137:13)
    at flush (/usr/local/lib/node_modules/bower/node_modules/q/q.js:125:13)
    at process._tickCallback (node.js:355:11)
samccone commented 8 years ago

I hypothesize https://github.com/bower/bower/pull/2125 will resolve this issue...

@mmelvin0 can you give this a try?

samccone commented 8 years ago

Can you all try the new release? https://github.com/bower/bower/releases/tag/v1.7.2

benmann commented 8 years ago

Can someone confirm?

bmcallis commented 8 years ago

I was able to successfully run bower install with 1.7.2 with the same setup that fails with 1.7.1.

node v0.12.8 npm 3.5.1 osx 10.11.2

sheerun commented 8 years ago

It seems resolved then in 1.7.2 :) Please comment if it is not true

rhythmnewt commented 8 years ago

For those who find this thread because of issues during Visual Studio Online builds, VSO has pre-installed bower version 1.7.1 (as of time of posting) which has this issue. Make sure to either run "npm install bower -g" or specify bower as a dependency in the npm config file for the project (with version > 1.7.1).