[DRE-maint] Bug#1017609: ruby-terser: Test fails with node-terser >= 5

Yadd yadd at debian.org
Tue Sep 6 10:29:25 BST 2022


Control: tags -1 + pending patch

On 06/09/2022 10:38, Yadd wrote:
>> Le 28 août 2022 19:29:33 GMT+02:00, Mohd Bilal <mdbilal at disroot.org> a 
>> écrit :
>>
>>     Hi Yadd :)
>>
>>     On Thu, 25 Aug 2022 10:58:21 +0200 Yadd <yadd at debian.org> wrote:
>>
>>         ruby-terser uses a patched terser.js (see
>>         
>> https://github.com/ahorek/terser-ruby/blob/master/patches/terser-sync.patch) <https://github.com/ahorek/terser-ruby/blob/master/patches/terser-sync.patch)>
>>
>>         So this issue is simple to fix: copy node-terser files into
>>         vendor/terser and patch it using upstream patch.
>>
>>
>>
>>     I had a look at this and tried doing what you suggested, but 
>> copying and patching had zero effect on the tests. They are still 
>> failing.
>>
>>     According to [1] I think terser bin has to be generated from the 
>> source with the patches applied.
>>
>>     I tried your approach and tried generating the minfied terser.js 
>> but the autopkgtest error[2] suggests that the patched 
>> function(minifySync) aren't seen in the minified lib/terser.js
>>
>>     Can you maybe use this upstream patch onto node-terser and also 
>> generate a min file that can be used with ruby-terser? Is it possible?
>>
>>     Or do you have any other alternative to suggest ?
>>
>>     [1] 
>> -https://github.com/ahorek/terser-ruby/blob/master/Rakefile#L55  
>> <https://github.com/ahorek/terser-ruby/blob/master/Rakefile#L55>#L66
>>     [2] -http://paste.debian.net/1251967/  
>> <http://paste.debian.net/1251967/>
>>
>>     Thanks
> 
> Hi,
> 
> the Ruby patch can't be applied to node-terser because it provides a 
> wrong JavaScript: await call in a non-async function (maybe Ruby has its 
> own JS engine which accepts this?).
> So I don't see any way to do what you proposed on JS side.
> 
> Cheers,
> Yadd

Here is a patch that reproduce upstream terser's build.

Cheers,
Yadd
-------------- next part --------------
diff --git a/debian/changelog b/debian/changelog
index 8fea143..38b9f39 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+ruby-terser (1.0.2+dfsg-6) UNRELEASED; urgency=medium
+
+  [ Yadd ]
+  * Reproduce upstream terser.js (Closes: #1017609):
+    + Drop dependency to libjs-terser
+    + Add build dependency to node-terser >= 5
+    + Build terser.js using upstream patches
+
+ -- Yadd <yadd at debian.org>  Thu, 25 Aug 2022 09:44:17 +0200
+
 ruby-terser (1.0.2+dfsg-5) unstable; urgency=medium
 
   * Team upload.
diff --git a/debian/patches/terser-sync.patch b/debian/patches/terser-sync.patch
new file mode 100644
index 0000000..60e92d8
--- /dev/null
+++ b/debian/patches/terser-sync.patch
@@ -0,0 +1,151 @@
+Description: import upstream patches to render terser sync
+Origin: upstream,
+ https://github.com/ahorek/terser-ruby/blob/master/patches/terser-sync.patch
+ https://github.com/ahorek/terser-ruby/blob/master/patches/revert-source-maps.patch
+Bug-Debian: https://bugs.debian.org/1017609
+Forwarded: not-needed
+Reviewed-By: Yadd <yadd at debian.org>
+
+--- a/terser.js
++++ b/terser.js
+@@ -21156,7 +21156,7 @@
+  ***********************************************************************/
+ 
+ // a small wrapper around source-map and @jridgewell/source-map
+-async function SourceMap(options) {
++function SourceMap(options) {
+     options = defaults(options, {
+         file : null,
+         root : null,
+@@ -21164,31 +21164,20 @@
+         files: {},
+     });
+ 
+-    var orig_map;
+     var generator = new sourceMap.SourceMapGenerator({
+         file       : options.file,
+         sourceRoot : options.root
+     });
++    var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
+ 
+-    let sourcesContent = {__proto__: null};
+-    let files = options.files;
+-    for (var name in files) if (HOP(files, name)) {
+-        sourcesContent[name] = files[name];
+-    }
+-    if (options.orig) {
+-        // We support both @jridgewell/source-map (which has a sync
+-        // SourceMapConsumer) and source-map (which has an async
+-        // SourceMapConsumer).
+-        orig_map = await new sourceMap.SourceMapConsumer(options.orig);
+-        if (orig_map.sourcesContent) {
+-            orig_map.sources.forEach(function(source, i) {
+-                var content = orig_map.sourcesContent[i];
+-                if (content) {
+-                    sourcesContent[source] = content;
++    if (orig_map) {
++        orig_map.sources.forEach(function(source) {
++            var sourceContent = orig_map.sourceContentFor(source, true);
++            if (sourceContent) {
++                generator.setSourceContent(source, sourceContent);
+                 }
+             });
+         }
+-    }
+ 
+     function add(source, gen_line, gen_col, orig_line, orig_col, name) {
+         let generatedPos = { line: gen_line, column: gen_col };
+@@ -21245,10 +21234,9 @@
+     }
+ 
+     return {
+-        add,
+-        getDecoded,
+-        getEncoded,
+-        destroy,
++        add: add,
++        get: function() { return generator; },
++        toString: function() { return JSON.stringify(generator.toJSON()); },
+     };
+ }
+ 
+@@ -29459,6 +29447,10 @@
+ }
+ 
+ async function minify(files, options, _fs_module) {
++    return minifySync(files, options, _fs_module);
++}
++
++function minifySync(files, options, _fs_module) {
+     if (
+         _fs_module
+         && typeof process === "object"
+@@ -29650,15 +29642,21 @@
+         }
+ 
+         if (options.sourceMap) {
+-            if (options.sourceMap.includeSources && files instanceof AST_Toplevel) {
+-                throw new Error("original source content unavailable");
++            if (typeof options.sourceMap.content == "string") {
++                options.sourceMap.content = JSON.parse(options.sourceMap.content);
+             }
+-            options.format.source_map = await SourceMap({
++            options.format.source_map = SourceMap({
+                 file: options.sourceMap.filename,
+                 orig: options.sourceMap.content,
+                 root: options.sourceMap.root,
+-                files: options.sourceMap.includeSources ? files : null,
+             });
++            if (options.sourceMap.includeSources) {
++                if (files instanceof AST_Toplevel) {
++                    throw new Error("original source content unavailable");
++                } else for (var name in files) if (HOP(files, name)) {
++                    options.format.source_map.get().setSourceContent(name, files[name]);
++                }
++            }
+         }
+         delete options.format.ast;
+         delete options.format.code;
+@@ -29667,21 +29665,11 @@
+         toplevel.print(stream);
+         result.code = stream.get();
+         if (options.sourceMap) {
+-            Object.defineProperty(result, "map", {
+-                configurable: true,
+-                enumerable: true,
+-                get() {
+-                    const map = options.format.source_map.getEncoded();
+-                    return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map));
+-                },
+-                set(value) {
+-                    Object.defineProperty(result, "map", {
+-                        value,
+-                        writable: true,
+-                    });
++            if(options.sourceMap.asObject) {
++                result.map = options.format.source_map.get().toJSON();
++            } else {
++                result.map = options.format.source_map.toString();
+                 }
+-            });
+-            result.decoded_map = options.format.source_map.getDecoded();
+             if (options.sourceMap.url == "inline") {
+                 var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
+                 result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
+@@ -29696,9 +29684,6 @@
+             options.nameCache.props = cache_to_json(options.mangle.properties.cache);
+         }
+     }
+-    if (options.format && options.format.source_map) {
+-        options.format.source_map.destroy();
+-    }
+     if (timings) {
+         timings.end = Date.now();
+         result.timings = {
+@@ -30214,5 +30199,6 @@
+ exports._default_options = _default_options;
+ exports._run_cli = run_cli;
+ exports.minify = minify;
++exports.minifySync = minifySync;
+ 
+ }));
diff --git a/debian/rules b/debian/rules
index d8744ed..b807e34 100755
--- a/debian/rules
+++ b/debian/rules
@@ -7,10 +7,19 @@ version = $(shell ruby -r ./lib/terser/version  -e "puts Terser::VERSION")
 %:
 	dh $@ --buildsystem=ruby --with ruby
 
+override_dh_install:
+	dh_install
+	cp /usr/share/nodejs/terser/dist/bundle.min.cjs \
+		debian/ruby-terser/usr/share/rubygems-integration/all/gems/terser-$(version)/lib/terser.js
+	cat debian/patches/terser-sync.patch | \
+		(cd debian/ruby-terser/usr/share/rubygems-integration/all/gems/terser-$(version)/lib/ && \
+		patch -p1 && \
+		rm -f terser.js.orig)
+
 override_dh_link:
 	dh_link
 	mkdir -p debian/ruby-terser/usr/share/rubygems-integration/all/gems/terser-$(version)/lib
-	ln -s /usr/share/javascript/terser/bundle.min.js \
-		debian/ruby-terser/usr/share/rubygems-integration/all/gems/terser-$(version)/lib/terser.js
+	#ln -s /usr/share/javascript/terser/bundle.min.js \
+	#	debian/ruby-terser/usr/share/rubygems-integration/all/gems/terser-$(version)/lib/terser.js
 	ln -s /usr/share/javascript/source-map/source-map.min.js \
 		debian/ruby-terser/usr/share/rubygems-integration/all/gems/terser-$(version)/lib/source-map.js


More information about the Pkg-ruby-extras-maintainers mailing list