Arlolra has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/319257

Change subject: Get rid of simple debug helpers
......................................................................

Get rid of simple debug helpers

 * Use the logger instead.

Change-Id: I6039267e43b59fd647dfd3d85c69d7a3c8b707a4
---
M lib/config/MWParserEnvironment.js
M lib/logger/ParsoidLogger.js
M lib/mw/ApiRequest.js
M lib/utils/Util.js
M lib/wt2html/TokenTransformManager.js
M lib/wt2html/tt/ExtensionHandler.js
M lib/wt2html/tt/ParserFunctions.js
M lib/wt2html/tt/TemplateHandler.js
M lib/wt2html/tt/TokenCollector.js
9 files changed, 74 insertions(+), 110 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/parsoid 
refs/changes/57/319257/1

diff --git a/lib/config/MWParserEnvironment.js 
b/lib/config/MWParserEnvironment.js
index c30d3d7..c8c6a7c 100644
--- a/lib/config/MWParserEnvironment.js
+++ b/lib/config/MWParserEnvironment.js
@@ -605,52 +605,6 @@
        return this.normalizedTitleKey(this.resolveTitle(hrefToken, true), 
true) !== null;
 };
 
-/**
- * Simple debug helper
- */
-MWParserEnvironment.prototype.dp = function() {
-       if (this.conf.parsoid.debug) {
-               if (arguments.length > 1) {
-                       try {
-                               console.warn(JSON.stringify(arguments, null, 
2));
-                       } catch (e) {
-                               console.trace();
-                               console.warn(e);
-                       }
-               } else {
-                       console.warn(arguments[0]);
-               }
-       }
-};
-
-/**
- * Even simpler debug helper that always prints..
- */
-MWParserEnvironment.prototype.ap = function() {
-       if (arguments.length > 1) {
-               try {
-                       console.warn(JSON.stringify(arguments, null, 2));
-               } catch (e) {
-                       console.warn(e);
-               }
-       } else {
-               console.warn(arguments[0]);
-       }
-};
-
-/**
- * Simple debug helper, trace-only
- */
-MWParserEnvironment.prototype.tp = function() {
-       if (this.conf.parsoid.debug) {
-               if (arguments.length > 1) {
-                       console.warn(JSON.stringify(arguments, null, 2));
-               } else {
-                       console.warn(arguments[0]);
-               }
-       }
-};
-
 MWParserEnvironment.prototype.initUID = function() {
        this.uid = 1;
 };
diff --git a/lib/logger/ParsoidLogger.js b/lib/logger/ParsoidLogger.js
index d3bf078..15973b2 100644
--- a/lib/logger/ParsoidLogger.js
+++ b/lib/logger/ParsoidLogger.js
@@ -107,13 +107,15 @@
                
this.registerBackend(buildTraceOrDebugFlag(parsoidConfig.traceFlags, "trace"),
                        tracerBackend);
        }
-       if (parsoidConfig.debugFlags) {
+       if (parsoidConfig.debug) {
+               this.registerBackend(/^debug(\/.*)?/, tracerBackend);
+       } else if (parsoidConfig.debugFlags) {
                
this.registerBackend(buildTraceOrDebugFlag(parsoidConfig.debugFlags, "debug"),
                        tracerBackend);
        }
        if (linter && parsoidConfig.linting) {
-               this.registerBackend(/lint(\/.*)?/, 
linter.linterBackend.bind(linter));
-               this.registerBackend(/end(\/.*)/, 
linter.logLintOutput.bind(linter));
+               this.registerBackend(/^lint(\/.*)?/, 
linter.linterBackend.bind(linter));
+               this.registerBackend(/^end(\/.*)/, 
linter.logLintOutput.bind(linter));
        }
 };
 
@@ -146,6 +148,7 @@
 };
 
 var prettyLogTypeMap = {
+       "debug":            "[DEBUG]",
        "trace/peg":        "[peg]",
        "trace/pre":        "[PRE]",
        "debug/pre":        "[PRE-DBG]",
@@ -182,7 +185,8 @@
                }
 
                // indent by number of slashes
-               var level = logType.match(/\//g).length - 1;
+               var match = logType.match(/\//g);
+               var level = match ? match.length - 1 : 0;
                var indent = '  '.repeat(level);
                msg += indent;
 
diff --git a/lib/mw/ApiRequest.js b/lib/mw/ApiRequest.js
index 5394a0d..75d350f 100644
--- a/lib/mw/ApiRequest.js
+++ b/lib/mw/ApiRequest.js
@@ -311,8 +311,7 @@
                        options.headers['X-Forwarded-Proto'] = 'https';
                }
        }
-       this.env.dp("Starting HTTP request: ", options);
-       this.trace(options);
+       this.trace("Starting HTTP request: ", options);
 
        return request(options, callback);
 };
@@ -581,7 +580,7 @@
                return;
        }
 
-       this.env.tp('Retrieved ' + this.title, metadata);
+       this.trace('Retrieved ' + this.title, metadata);
 
        // Add the source to the cache
        // (both original title as well as possible redirected title)
diff --git a/lib/utils/Util.js b/lib/utils/Util.js
index e08430a..176592a 100644
--- a/lib/utils/Util.js
+++ b/lib/utils/Util.js
@@ -51,6 +51,10 @@
                        console.error(Util.dumpUsageHelp());
                        exit = true;
                }
+               if (opts.debug === 'help') {
+                       console.error(Util.debugUsageHelp());
+                       exit = true;
+               }
                if (exit) {
                        process.exit(1);
                }
@@ -144,14 +148,6 @@
                        "Examples:",
                        "$ node parse --trace pre,p-wrap,html < foo",
                        "$ node parse --trace sync:3,dsr < foo",
-                       "",
-                       "Debugging",
-                       "---------",
-                       "- With one or more comma-separated flags, provides 
more verbose tracing than the equivalent trace flag",
-                       "- Supported flags:",
-                       "  * pre       : shows actions of the pre handler",
-                       "  * wts       : trace actions of the regular wikitext 
serializer",
-                       "  * selser    : trace actions of the selective 
serializer",
                ].join('\n');
        },
 
@@ -187,6 +183,23 @@
        /**
         * @method
         *
+        * Returns a help message for the debug flags.
+        */
+       debugUsageHelp: function() {
+               return [
+                       "Debugging",
+                       "---------",
+                       "- With one or more comma-separated flags, provides 
more verbose tracing than the equivalent trace flag",
+                       "- Supported flags:",
+                       "  * pre       : shows actions of the pre handler",
+                       "  * wts       : trace actions of the regular wikitext 
serializer",
+                       "  * selser    : trace actions of the selective 
serializer",
+               ].join('\n');
+       },
+
+       /**
+        * @method
+        *
         * Sets templating and processing flags on an object,
         * based on an options object.
         *
diff --git a/lib/wt2html/TokenTransformManager.js 
b/lib/wt2html/TokenTransformManager.js
index 73239a9..2ccd12b 100644
--- a/lib/wt2html/TokenTransformManager.js
+++ b/lib/wt2html/TokenTransformManager.js
@@ -314,7 +314,7 @@
  * @param {Frame} parentFrame
  */
 AsyncTokenTransformManager.prototype.setFrame = function(parentFrame, title, 
args) {
-       this.env.dp('AsyncTokenTransformManager.setFrame', title, args);
+       this.env.log('debug', 'AsyncTokenTransformManager.setFrame', title, 
args);
 
        // Reset accumulators
        this.reset();
@@ -355,7 +355,7 @@
  * @private
  */
 AsyncTokenTransformManager.prototype.emitChunk = function(ret) {
-       this.env.dp('AsyncTokenTransformManager.emitChunk', ret);
+       this.env.log('debug', 'AsyncTokenTransformManager.emitChunk', ret);
        // This method is often the root of the call stack, so makes a good 
point
        // for a try/catch to ensure error handling.
        try {
@@ -394,21 +394,20 @@
  * @private
  */
 AsyncTokenTransformManager.prototype.onChunk = function(tokens) {
-
        // Set top-level callback to next transform phase
-       var res = this.transformTokens (tokens, this.tokenCB);
-       this.env.dp('AsyncTokenTransformManager onChunk', res.async? 'async' : 
'sync', res.tokens);
+       var res = this.transformTokens(tokens, this.tokenCB);
+       this.env.log('debug', 'AsyncTokenTransformManager onChunk', res.async? 
'async' : 'sync', res.tokens);
        if (!res.tokens.rank) {
                res.tokens.rank = this.phaseEndRank;
        }
 
        // Emit or append the returned tokens
        if (!this.tailAccumulator) {
-               this.env.dp('emitting');
+               this.env.log('debug', 'emitting');
                this.emit('chunk', res.tokens);
        } else {
                // console.warn("--> ATT-" + this.pipelineId + " appending: " + 
JSON.stringify(res.tokens));
-               this.env.dp('appending to tail');
+               this.env.log('debug', 'appending to tail');
                this.tailAccumulator.append(res.tokens);
        }
 
@@ -530,7 +529,7 @@
 /**
  * Run asynchronous transformations. This is the big workhorse where
  * templates, images, links and other async expansions (see the transform
- * recipe mediawiki.parser.js) are processed.
+ * recipe parser.js) are processed.
  *
  * The returned chunk is fully expanded for this phase, and the rank set
  * to reflect this.
@@ -683,7 +682,7 @@
 
                                                if (this.debug) {
                                                        // Avoid expensive map 
and slice if we dont need to.
-                                                       this.env.dp(
+                                                       this.env.log('debug',
                                                                'workStack',
                                                                
accumChain.state.c,
                                                                resTokens.rank,
@@ -707,7 +706,7 @@
                        }
 
                        if (res.async) {
-                               this.env.dp('res.async, creating new 
TokenAccumulator', accumChain.state.c);
+                               this.env.log('debug', 'res.async, creating new 
TokenAccumulator', accumChain.state.c);
                                accumChain.addNode();
                        }
                }
@@ -723,7 +722,7 @@
        var firstAccum = accumChain.firstAccum;
        firstAccum.rank = this.phaseEndRank;
 
-       this.env.dp(
+       this.env.log('debug',
                'firstAccum',
                accumChain.numNodes > 1 ? 'async' : 'sync',
                accumChain.state.c,
@@ -761,7 +760,7 @@
        if (s.transforming) {
                // transformTokens is still ongoing, handle as sync return by
                // collecting the results in s.res
-               this.env.dp('maybeSyncReturn transforming', s.c, ret);
+               this.env.log('debug', 'maybeSyncReturn transforming', s.c, ret);
                if (ret.tokens && ret.tokens.length > 0) {
                        if (s.res.tokens) {
                                var oldRank = s.res.tokens.rank;
@@ -781,7 +780,7 @@
        } else {
                // Since the original transformTokens call is already done, we 
have to
                // re-start application of any remaining transforms here.
-               this.env.dp('maybeSyncReturn async', s.c, ret);
+               this.env.log('debug', 'maybeSyncReturn async', s.c, ret);
                var asyncCB = cbs.parentCB;
                var tokens = ret.tokens;
                if (tokens) {
@@ -789,7 +788,7 @@
                                (!tokens.rank || tokens.rank < 
this.phaseEndRank) &&
                                !(tokens.length === 1 && tokens[0].constructor 
=== String)) {
                                // Re-process incomplete tokens
-                               this.env.dp('maybeSyncReturn: recursive 
transformTokens',
+                               this.env.log('debug', 'maybeSyncReturn: 
recursive transformTokens',
                                                this.frame.title, ret.tokens);
 
                                // Set up a new child callback with its own 
callback state
@@ -896,7 +895,7 @@
                return;
        }
 
-       this.env.dp('SyncTokenTransformManager.onChunk, input: ', tokens);
+       this.env.log('debug', 'SyncTokenTransformManager.onChunk, input: ', 
tokens);
 
        var localAccum = [];
 
@@ -979,7 +978,7 @@
                this.env.bumpTimeUse("SyncTTM", (Date.now() - startTime - 
tokenTimes));
        }
        localAccum.rank = this.phaseEndRank;
-       this.env.dp('SyncTokenTransformManager.onChunk: emitting ', localAccum);
+       this.env.log('debug', 'SyncTokenTransformManager.onChunk: emitting ', 
localAccum);
        this.emit('chunk', localAccum);
 };
 
@@ -1116,7 +1115,7 @@
  * @private
  */
 AttributeTransformManager.prototype._returnAttributeValue = function(ref, 
tokens) {
-       this.manager.env.dp('check _returnAttributeValue: ', ref,  tokens);
+       this.manager.env.log('debug', 'check _returnAttributeValue: ', ref,  
tokens);
        this.kvs[ref].v = Util.stripEOFTkfromTokens(tokens);
        this.outstanding--;
        if (this.outstanding === 0) {
@@ -1129,7 +1128,7 @@
  * @private
  */
 AttributeTransformManager.prototype._returnAttributeKey = function(ref, 
tokens) {
-       this.manager.env.dp('check _returnAttributeKey: ', ref,  tokens);
+       this.manager.env.log('debug', 'check _returnAttributeKey: ', ref,  
tokens);
        this.kvs[ref].k = Util.stripEOFTkfromTokens(tokens);
        this.outstanding--;
        if (this.outstanding === 0) {
@@ -1284,7 +1283,7 @@
        if (this.waitForChild) {
                // Just continue to accumulate sibling tokens.
                this.concatTokens(ret.tokens);
-               this.manager.env.dp('TokenAccumulator._receiveToksFromSibling: 
async=',
+               this.manager.env.log('debug', 
'TokenAccumulator._receiveToksFromSibling: async=',
                                ret.async, ', this.outstanding=', 
(this.waitForChild + this.waitForSibling),
                                ', this.siblingChunks=', this.siblingChunks, ' 
frame.title=', this.manager.frame.title);
        } else if (this.waitForSibling) {
@@ -1293,7 +1292,7 @@
                // tokens. The internal accumulator is empty at this stage, as 
its
                // tokens got passed to the parent when the child was done.
                if (ret.tokens.length && !ret.tokens.rank) {
-                       
this.manager.env.dp('TokenAccumulator.receiveToksFromSibling without rank', 
ret.tokens);
+                       this.manager.env.log('debug', 
'TokenAccumulator.receiveToksFromSibling without rank', ret.tokens);
                        ret.tokens.rank = this.manager.phaseEndRank;
                }
                // console.log("\nTA-"+this.uid+" emitTokens", 
JSON.stringify(ret));
@@ -1396,7 +1395,7 @@
 Frame.prototype.expand = function(chunk, options) {
        var outType = options.type || 'text/x-mediawiki/expanded';
        var cb = options.cb || console.warn(JSON.stringify(options));
-       this.manager.env.dp('Frame.expand', chunk);
+       this.manager.env.log('debug', 'Frame.expand', chunk);
 
        if (chunk.constructor === String) {
                // Plain text remains text. Nothing to do.
@@ -1486,9 +1485,9 @@
 Frame.prototype.onThunkEvent = function(state, notYetDone, ret) {
        if (notYetDone) {
                state.accum = JSUtils.pushArray(state.accum, 
Util.stripEOFTkfromTokens(ret));
-               this.manager.env.dp('Frame.onThunkEvent accum:', state.accum);
+               this.manager.env.log('debug', 'Frame.onThunkEvent accum:', 
state.accum);
        } else {
-               this.manager.env.dp('Frame.onThunkEvent:', state.accum);
+               this.manager.env.log('debug', 'Frame.onThunkEvent:', 
state.accum);
                state.cb(state.accum);
        }
 };
diff --git a/lib/wt2html/tt/ExtensionHandler.js 
b/lib/wt2html/tt/ExtensionHandler.js
index 9ab5f9c..4328f33 100644
--- a/lib/wt2html/tt/ExtensionHandler.js
+++ b/lib/wt2html/tt/ExtensionHandler.js
@@ -80,7 +80,7 @@
 ExtensionHandler.prototype.fetchExpandedExtension = function(text, parentCB, 
cb) {
        var env = this.env;
        // We are about to start an async request for an extension
-       env.dp('Note: trying to expand ', text);
+       env.log('debug', 'Note: trying to expand ', text);
        parentCB({ async: true });
        // Pass the page title to the API.
        var title = env.page && env.page.title && env.page.title.key || 'API';
diff --git a/lib/wt2html/tt/ParserFunctions.js 
b/lib/wt2html/tt/ParserFunctions.js
index e43f129..38342d9 100644
--- a/lib/wt2html/tt/ParserFunctions.js
+++ b/lib/wt2html/tt/ParserFunctions.js
@@ -85,8 +85,7 @@
 ParserFunctions.prototype._switchLookupFallback = function(frame, kvs, key, 
dict, cb, v) {
        var kv;
        var l = kvs.length;
-       this.env.tp('swl');
-       this.env.dp('_switchLookupFallback', kvs.length, key, v);
+       this.env.log('debug', '_switchLookupFallback', kvs.length, key, v);
        var _cbTrim = function(res) {
                if (res.constructor === String) {
                        cb({ tokens: [ res.trim() ], async: res.async });
@@ -122,7 +121,7 @@
                //
                // So if <key> matched c1, we want to return <res>.
                // Hence, we are looking for the next entry with a non-empty 
key.
-               this.env.dp('switch found');
+               this.env.log('debug', 'switch found');
                for (var j = 0; j < l; j++) {
                        kv = kvs[j];
                        // XXX: make sure the key is always one of these!
@@ -150,8 +149,7 @@
                                continue;
                        } else {
                                if (!kv.v.get) {
-                                       this.env.ap(kv.v);
-                                       console.trace();
+                                       this.env.log('debug', kv.v);
                                }
                                var self = this;
 
@@ -228,12 +226,12 @@
 // 
http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#Grouping_results
 ParserFunctions.prototype['pf_#switch'] = function(token, frame, cb, args) {
        var target = args[0].k.trim();
-       this.env.dp('switch enter', target, token);
+       this.env.log('debug', 'switch enter', target, token);
        // create a dict from the remaining args
        args.shift();
        var dict = args.dict();
        if (target && dict[target] !== undefined) {
-               this.env.dp('switch found: ', target, dict, ' res=', 
dict[target]);
+               this.env.log('debug', 'switch found: ', target, dict, ' res=', 
dict[target]);
                dict[target].get({
                        type: 'tokens/x-mediawiki/expanded',
                        cb: function(res) {
@@ -290,7 +288,7 @@
 };
 
 ParserFunctions.prototype['pf_#ifexpr'] = function(token, frame, cb, args) {
-       this.env.dp('#ifexp: ', args);
+       this.env.log('debug', '#ifexp: ', args);
        var res = null;
        var target = args[0].k;
        if (target) {
@@ -373,7 +371,7 @@
                                }
                                cb({ tokens: [target] });
                        } else {
-                               env.dp('padleft no pad width', args);
+                               env.log('debug', 'padleft no pad width', args);
                                cb({});
                        }
                },
@@ -407,7 +405,7 @@
                                }
                                cb({ tokens: [target] });
                        } else {
-                               env.dp('padright no pad width', args);
+                               env.log('debug', 'padright no pad width', args);
                                cb({});
                        }
                },
@@ -756,7 +754,6 @@
 };
 ParserFunctions.prototype.pf_urlencode = function(token, frame, cb, args) {
        var target = args[0].k;
-       this.env.tp('urlencode: ' + target);
        cb({ tokens: [encodeURIComponent(target.trim())] });
 };
 
diff --git a/lib/wt2html/tt/TemplateHandler.js 
b/lib/wt2html/tt/TemplateHandler.js
index adac655..2e94d62 100644
--- a/lib/wt2html/tt/TemplateHandler.js
+++ b/lib/wt2html/tt/TemplateHandler.js
@@ -528,8 +528,7 @@
        var target = attribs[0].k;
 
        if (!target) {
-               env.ap('No target! ', attribs);
-               console.trace();
+               env.log('debug', 'No target! ', attribs);
        }
 
        if (!state.resolveTemplateTarget) {
@@ -571,7 +570,7 @@
 
                var pfAttribs = new defines.Params(attribs);
                pfAttribs[0] = new KV(resolvedTgt.pfArg, []);
-               env.dp('entering prefix', target, state.token);
+               env.log('debug', 'entering prefix', target, state.token);
                var newCB;
                if (this.options.wrapTemplates) {
                        newCB = this._parserFunctionsWrapper.bind(this, state, 
cb);
@@ -627,7 +626,7 @@
                //  this.manager.env.errCB(err);
        }
 
-       this.manager.env.dp('TemplateHandler._startDocumentPipeline', 
tplArgs.name, tplArgs.attribs);
+       this.manager.env.log('debug', 'TemplateHandler._startDocumentPipeline', 
tplArgs.name, tplArgs.attribs);
        Util.processContentInPipeline(
                this.manager.env,
                this.manager.frame,
@@ -678,7 +677,7 @@
                console.log("---------------------------------");
        }
 
-       this.manager.env.dp('TemplateHandler._startTokenPipeline', 
tplArgs.name, tplArgs.attribs);
+       this.manager.env.log('debug', 'TemplateHandler._startTokenPipeline', 
tplArgs.name, tplArgs.attribs);
 
        // Get a nested transformation pipeline for the input type. The input
        // pipeline includes the tokenizer, synchronous stage-1 transforms for
@@ -856,7 +855,7 @@
                                        // Use a data-attribute to prevent the 
sanitizer from stripping this
                                        // attribute before it reaches the DOM 
pass where it is needed.
                                        chunk[0].dataAttribs.tmp.tplarginfo = 
JSON.stringify(argInfo);
-                                       
env.dp('TemplateHandler._encapsulateTemplate', chunk);
+                                       env.log('debug', 
'TemplateHandler._encapsulateTemplate', chunk);
                                        cb({tokens: chunk});
                                }.bind(this));
 
@@ -871,7 +870,7 @@
                }
        }
 
-       env.dp('TemplateHandler._encapsulateTemplate', chunk);
+       env.log('debug', 'TemplateHandler._encapsulateTemplate', chunk);
        cb({tokens: chunk});
 };
 
@@ -906,7 +905,7 @@
                chunk = newChunk;
        }
 
-       this.manager.env.dp('TemplateHandler._onChunk', chunk);
+       this.manager.env.log('debug', 'TemplateHandler._onChunk', chunk);
        chunk.rank = this.rank;
        cb({tokens: chunk, async: true});
 };
@@ -916,7 +915,7 @@
  * the template source.
  */
 TemplateHandler.prototype._onEnd = function(state, cb) {
-       this.manager.env.dp('TemplateHandler._onEnd');
+       this.manager.env.log('debug', 'TemplateHandler._onEnd');
        if (this.options.wrapTemplates) {
                var endTag = this.getEncapsulationInfoEndTag(state);
                var res = { tokens: [endTag] };
@@ -1097,10 +1096,9 @@
                parentCB({ tokens: tokens });
        } else {
                // We are about to start an async request for a template
-               env.dp('Note: trying to fetch ', title);
+               env.log('debug', 'Note: trying to fetch ', title);
                // Start a new request if none is outstanding
                if (env.requestQueue[title] === undefined) {
-                       env.tp('Note: Starting new request for ' + title);
                        env.requestQueue[title] = new TemplateRequest(env, 
title);
                }
                // append request, process in document order
@@ -1120,7 +1118,7 @@
                parentCB({ tokens: [ 'Warning: Page/template fetching disabled 
cannot expand ' + text] });
        } else {
                // We are about to start an async request for a template
-               env.dp('Note: trying to expand ', text);
+               env.log('debug', 'Note: trying to expand ', text);
                parentCB({ tokens: [], async: true });
                env.batcher.preprocess(title, text).nodify(cb);
        }
diff --git a/lib/wt2html/tt/TokenCollector.js b/lib/wt2html/tt/TokenCollector.js
index 5919cf4..370bb55 100644
--- a/lib/wt2html/tt/TokenCollector.js
+++ b/lib/wt2html/tt/TokenCollector.js
@@ -78,7 +78,7 @@
        if (tc === TagTk) {
                if (this.scopeStack.length === 0) {
                        // Set up transforms
-                       this.manager.env.dp('starting collection on ', token);
+                       this.manager.env.log('debug', 'starting collection on 
', token);
                        this.manager.addTransform(this._onAnyToken.bind (this),
                                'TokenCollector:_onAnyToken', this.rank + 
this._anyDelta, 'any');
                        
this.manager.addTransform(this._onDelimiterToken.bind(this),
@@ -96,7 +96,7 @@
                return this.transformation([token, token]);
        } else if (haveOpenTag) {
                // EOFTk or EndTagTk
-               this.manager.env.dp('finishing collection on ', token);
+               this.manager.env.log('debug', 'finishing collection on ', 
token);
 
                // Pop top scope and push token onto it
                var activeTokens = this.scopeStack.pop();

-- 
To view, visit https://gerrit.wikimedia.org/r/319257
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6039267e43b59fd647dfd3d85c69d7a3c8b707a4
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Arlolra <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to