├── .github ├── dependabot.yml └── workflows │ └── rust.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE-MPL-2.0 ├── README.md ├── src ├── lib.rs └── parser.rs └── tests ├── generate.py ├── mc.rs ├── output ├── 044115544bf6.json ├── 0d6969b2a955.json ├── 6f5fc0d644dd.json ├── 77ec8a41ee73.json ├── 7dabae5e261a.json ├── 7e60ad275b73.json ├── 81d3e4a2f3f3.json ├── D174915.json ├── b184c87f7606.json ├── b3a7561624f9.json ├── b3a7561624f9_modified.json ├── b583dd397599.json ├── b8802b591ce2.json ├── basic.json ├── c4c0ad8b3eaa.json ├── c58e9e70f971.json ├── c6f9187b0b2e.json ├── d12b0a6c7641.json ├── d4f80c4ba719.json ├── d7a700707ddb.json ├── d8571fb523a0.json ├── dfe0b0d0827e.json ├── ea8bdd612f43.json ├── empty.json ├── f045ac9f76cf.json ├── f9b391e62608.json ├── issue68.json ├── janx.json ├── new_file_with_git.json └── no_git_header.json ├── patches ├── 044115544bf6.patch ├── 0d6969b2a955.patch ├── 6f5fc0d644dd.patch ├── 77ec8a41ee73.patch ├── 7dabae5e261a.patch ├── 7e60ad275b73.patch ├── 81d3e4a2f3f3.patch ├── D174915.patch ├── b184c87f7606.patch ├── b3a7561624f9.patch ├── b3a7561624f9_modified.patch ├── b583dd397599.patch ├── b8802b591ce2.patch ├── basic.patch ├── c4c0ad8b3eaa.patch ├── c58e9e70f971.patch ├── c6f9187b0b2e.patch ├── d12b0a6c7641.patch ├── d4f80c4ba719.patch ├── d7a700707ddb.patch ├── d8571fb523a0.patch ├── dfe0b0d0827e.patch ├── ea8bdd612f43.patch ├── empty.patch ├── f045ac9f76cf.patch ├── f9b391e62608.patch ├── issue68.patch ├── janx.patch ├── new_file_with_git.patch └── no_git_header.patch └── test.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | open-pull-requests-limit: 99 8 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | 15 | name: Build and test 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | - name: Build 21 | run: cargo build --verbose 22 | - name: Run tests 23 | run: cargo test --verbose 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | *~ -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Community Participation Guidelines 2 | 3 | This repository is governed by Mozilla's code of conduct and etiquette guidelines. 4 | For more details, please read the 5 | [Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/). 6 | 7 | ## How to Report 8 | For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page. 9 | 10 | 16 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "parsepatch" 3 | version = "0.3.1" 4 | edition = "2018" 5 | authors = ["calixteman "] 6 | repository = "https://github.com/mozilla/rust-parsepatch" 7 | documentation = "https://docs.rs/parsepatch/" 8 | keywords = ["patch", "git"] 9 | description = "Parse git patch." 10 | license = "MPL-2.0" 11 | 12 | [dependencies] 13 | log = "0.4" 14 | 15 | [dev-dependencies] 16 | chardet = "0.2" 17 | crossbeam = "^0.8" 18 | encoding = "0.2" 19 | num_cpus = "^1.16" 20 | serde = "1.0" 21 | serde_derive = "1.0" 22 | serde_json = "1.0" 23 | env_logger = "0.10" 24 | hglib-rs = "0.1" 25 | indicatif = "0.17" 26 | 27 | [lib] 28 | name = "parsepatch" 29 | path = "src/lib.rs" 30 | -------------------------------------------------------------------------------- /LICENSE-MPL-2.0: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-parsepatch 2 | 3 | [![Rust](https://github.com/mozilla/rust-parsepatch/actions/workflows/rust.yml/badge.svg)](https://github.com/mozilla/rust-parsepatch/actions/workflows/rust.yml) 4 | [![codecov](https://codecov.io/gh/mozilla/rust-parsepatch/branch/master/graph/badge.svg)](https://codecov.io/gh/mozilla/rust-parsepatch) 5 | [![Crates.io](https://img.shields.io/crates/v/parsepatch.svg)](https://crates.io/crates/parsepatch) 6 | 7 | ## License 8 | 9 | Published under the MPL 2.0 license. 10 | 11 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate log; 3 | 4 | pub mod parser; 5 | pub use self::parser::*; 6 | -------------------------------------------------------------------------------- /tests/generate.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | from collections import OrderedDict 3 | import json 4 | import os 5 | import re 6 | import whatthepatch 7 | from pprint import pprint 8 | 9 | def _bytes_repr(c): 10 | # https://github.com/jboy/distil/blob/master/distil/unicode_string_utils.py#L170 11 | if c == 146: 12 | return u'\u2019' 13 | if c == 147: 14 | return u'\u201C' 15 | if c == 150: 16 | return u'\u2013' 17 | raise UnicodeDecodeError() 18 | 19 | 20 | def myreplacement(ex): 21 | s, start, end = ex.object, ex.start, ex.end 22 | return ''.join(_bytes_repr(c) for c in s[start:end]), end 23 | 24 | 25 | codecs.register_error('myreplacement', myreplacement) 26 | 27 | 28 | pat = re.compile(r"\t+$", re.MULTILINE) 29 | directory = './patches' 30 | for f in os.listdir(directory): 31 | #if not f.endswith("ea8bdd612f43.patch"): 32 | # continue 33 | if not f.endswith('.patch'): 34 | continue 35 | with open(os.path.join(directory, f), 'rb') as In: 36 | patch = In.read() 37 | 38 | patch = patch.decode('utf-8', errors='myreplacement') 39 | bp = 'third_party/rust/bitvec/doc/Bit Patterns.md' 40 | rep = 'third_party/rust/bitvec/doc/BitPatterns.md' 41 | if bp in patch: 42 | patch = patch.replace(bp, rep) 43 | patch = pat.sub('', patch) 44 | res = [] 45 | 46 | if 'd12b0a6c7641' in f: 47 | # need to hack here because of bug in wtp 48 | patch = patch.replace('diff commits', 'Diff commits') 49 | patch = patch.replace('diffs for', 'Diffs for') 50 | 51 | if '044115544bf6' in f: 52 | # wtp sees a diff entry because of the --- 53 | # so workaround to avoid to have this entry in the output. 54 | patch = patch.replace('--- target_task_set@d009f0738a', '___ target_task_set@d009f0738a') 55 | 56 | for diff in whatthepatch.parse_patch(patch): 57 | r = OrderedDict() 58 | 59 | old = diff.header.old_path 60 | new = diff.header.new_path 61 | 62 | old = old[2:] if old.startswith('a/') else old 63 | new = new[2:] if new.startswith('b/') else new 64 | 65 | if old == rep: 66 | old = bp 67 | 68 | if new == rep: 69 | new = bp 70 | 71 | if old == "/dev/null": 72 | old = None 73 | 74 | r['filename'] = new 75 | r['new'] = False 76 | r['deleted'] = False 77 | r['binary'] = "GIT binary patch" in diff.text 78 | r['copied_from'] = old if old != new else None 79 | r['hunks'] = hunks = [] 80 | last_hunk = -1 81 | 82 | if diff.changes: 83 | for old, new, line, hunk in diff.changes: 84 | if hunk != last_hunk: 85 | lines = [] 86 | hunks.append({'lines': lines}) 87 | last_hunk = hunk 88 | 89 | if old is None: 90 | lines.append( 91 | OrderedDict([('line', new), ('deleted', False), ('data', line)]) 92 | ) 93 | if new is None and old != 0: 94 | lines.append( 95 | OrderedDict([('line', old), ('deleted', True), ('data', line)]) 96 | ) 97 | 98 | res.append(r) 99 | res = {'diffs': res} 100 | 101 | f = os.path.splitext(f)[0] 102 | 103 | with open(os.path.join('output', f + '.json'), 'w') as Out: 104 | json.dump(res, Out, indent=4, separators=(',', ': ')) 105 | -------------------------------------------------------------------------------- /tests/mc.rs: -------------------------------------------------------------------------------- 1 | extern crate parsepatch; 2 | use crate::parsepatch::*; 3 | 4 | use crossbeam::channel::{bounded, Receiver}; 5 | use hglib::{export, hg, runcommand, Client, MkArg, Runner}; 6 | use indicatif::{ProgressBar, ProgressStyle}; 7 | use std::collections::HashSet; 8 | use std::sync::{Arc, Mutex}; 9 | use std::thread; 10 | 11 | struct DiffImpl; 12 | 13 | struct PatchImpl { 14 | diffs: Vec, 15 | } 16 | 17 | impl Patch for PatchImpl { 18 | fn new_diff(&mut self) -> &mut DiffImpl { 19 | self.diffs.push(DiffImpl {}); 20 | self.diffs.last_mut().unwrap() 21 | } 22 | 23 | fn close(&mut self) {} 24 | } 25 | 26 | impl Diff for DiffImpl { 27 | fn set_info( 28 | &mut self, 29 | _old_name: &str, 30 | _new_name: &str, 31 | _op: FileOp, 32 | _binary_sizes: Option>, 33 | _file_mode: Option, 34 | ) { 35 | } 36 | 37 | fn add_line(&mut self, _old_line: u32, _new_line: u32, _line: &[u8]) {} 38 | fn new_hunk(&mut self) {} 39 | fn close(&mut self) {} 40 | } 41 | 42 | fn get_log(path: &str, range: &str) -> Vec { 43 | let mut client = Client::open(path, "UTF-8", &[]).unwrap(); 44 | let range = [range]; 45 | let (mut data, _) = runcommand!( 46 | client, 47 | "log", 48 | &[""], 49 | "--template", 50 | "{node}\\0", 51 | "-r", 52 | &range 53 | ) 54 | .unwrap(); 55 | data.remove(data.len() - 1); 56 | data.split(|&c| c == b'\0') 57 | .map(|s| unsafe { String::from_utf8_unchecked(s.to_vec()) }) 58 | .collect() 59 | } 60 | 61 | fn consumer( 62 | path: String, 63 | receiver: Receiver>>, 64 | set: &Mutex>, 65 | pb: &Mutex, 66 | ) { 67 | let mut client = Client::open(&path, "UTF-8", &[]).unwrap(); 68 | 69 | while let Ok(nodes) = receiver.recv() { 70 | if nodes.is_none() { 71 | break; 72 | } 73 | 74 | let mut nodes = nodes.unwrap(); 75 | let n_nodes = nodes.len(); 76 | 77 | for node in nodes.drain(..) { 78 | let patch = hg!(client, export, revs = &[&node]).unwrap(); 79 | 80 | if let Some(diff) = patch { 81 | let mut patch = PatchImpl { diffs: Vec::new() }; 82 | 83 | { 84 | let mut set = set.lock().unwrap(); 85 | set.insert(node.clone()); 86 | } 87 | PatchReader::by_buf(&diff, &mut patch).unwrap(); 88 | { 89 | let mut set = set.lock().unwrap(); 90 | set.remove(&node); 91 | } 92 | } 93 | } 94 | let pb = pb.lock().unwrap(); 95 | pb.inc(n_nodes as u64); 96 | } 97 | } 98 | 99 | #[test] 100 | #[ignore] 101 | fn test_mc() { 102 | let path = "/home/calixte/dev/mozilla/mozilla-central.hg"; 103 | let nodes = get_log(path, "0:tip"); 104 | let total = nodes.len(); 105 | let set = Arc::new(Mutex::new(HashSet::new())); 106 | let n_threads = num_cpus::get(); 107 | let chunk_size = 32.min(total / n_threads + 1); 108 | let (sender, receiver) = bounded(total / chunk_size + 1 + n_threads); 109 | 110 | let pb = ProgressBar::new(total as u64); 111 | pb.set_style( 112 | ProgressStyle::default_bar() 113 | .template("[{elapsed_precise}] {bar:100.cyan/blue} {pos}/{len}") 114 | .unwrap(), 115 | ); 116 | let pb = Arc::new(Mutex::new(pb)); 117 | 118 | println!( 119 | "Chunk size is {} for {} collected nodes.", 120 | chunk_size, total 121 | ); 122 | 123 | let mut threads = Vec::new(); 124 | for i in 0..n_threads { 125 | let receiver = receiver.clone(); 126 | let path = path.to_string(); 127 | let set = Arc::clone(&set); 128 | let pb = Arc::clone(&pb); 129 | 130 | let t = thread::Builder::new() 131 | .name(format!("Consumer {}", i)) 132 | .spawn(move || { 133 | consumer(path, receiver, &set, &pb); 134 | }) 135 | .unwrap(); 136 | 137 | threads.push(t); 138 | } 139 | 140 | for c in nodes.chunks(chunk_size) { 141 | sender.send(Some(c.to_vec())).unwrap(); 142 | } 143 | 144 | for _ in 0..n_threads { 145 | sender.send(None).unwrap(); 146 | } 147 | 148 | for t in threads.drain(..) { 149 | if let Err(e) = t.join() { 150 | eprintln!("Error {:?}", e); 151 | let set = set.lock().unwrap(); 152 | eprintln!("Current parsed patches:\n{:?}", set); 153 | } 154 | } 155 | 156 | let erroneous = Arc::try_unwrap(set).unwrap().into_inner().unwrap(); 157 | assert!(erroneous.is_empty(), "Erroneous patches:\n{:?}", erroneous); 158 | } 159 | -------------------------------------------------------------------------------- /tests/output/044115544bf6.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "devtools/client/debugger/test/mochitest/browser.ini", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 144, 14 | "deleted": true, 15 | "data": "skip-if = os == \"win\"" 16 | }, 17 | { 18 | "line": 144, 19 | "deleted": false, 20 | "data": "skip-if =" 21 | }, 22 | { 23 | "line": 145, 24 | "deleted": false, 25 | "data": " os == \"win\"" 26 | }, 27 | { 28 | "line": 146, 29 | "deleted": false, 30 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov)" 31 | } 32 | ] 33 | }, 34 | { 35 | "lines": [ 36 | { 37 | "line": 207, 38 | "deleted": true, 39 | "data": "skip-if = !serviceworker_e10s || (os == 'linux' && ccov) # parent intercept mode is needed bug 1588154. Bug 1613543, the test consistently timeouts on Linux coverage builds." 40 | }, 41 | { 42 | "line": 209, 43 | "deleted": false, 44 | "data": "skip-if =" 45 | }, 46 | { 47 | "line": 210, 48 | "deleted": false, 49 | "data": " !serviceworker_e10s # parent intercept mode is needed bug 1588154. Bug 1613543, the test consistently timeouts on Linux coverage builds and WR debug builds." 50 | }, 51 | { 52 | "line": 211, 53 | "deleted": false, 54 | "data": " (os == 'linux' && (ccov || (webrender && !swgl && debug)))" 55 | } 56 | ] 57 | } 58 | ] 59 | }, 60 | { 61 | "filename": "devtools/client/inspector/animation/test/browser.ini", 62 | "new": false, 63 | "deleted": false, 64 | "binary": false, 65 | "copied_from": null, 66 | "hunks": [ 67 | { 68 | "lines": [ 69 | { 70 | "line": 43, 71 | "deleted": true, 72 | "data": " apple_catalina && !debug # Disabled in Bug 1713158. Intemittent bug: Bug 1665011" 73 | }, 74 | { 75 | "line": 43, 76 | "deleted": false, 77 | "data": " (apple_catalina && !debug) # Disabled in Bug 1713158. Intemittent bug: Bug 1665011" 78 | }, 79 | { 80 | "line": 44, 81 | "deleted": false, 82 | "data": " (os == \"linux\" && !debug && !asan && !swgl && !ccov) # Bug 1665011" 83 | } 84 | ] 85 | }, 86 | { 87 | "lines": [ 88 | { 89 | "line": 77, 90 | "deleted": true, 91 | "data": "skip-if = debug || (os == \"win\" && bits == 32) # Bug 1567800" 92 | }, 93 | { 94 | "line": 78, 95 | "deleted": false, 96 | "data": "skip-if =" 97 | }, 98 | { 99 | "line": 79, 100 | "deleted": false, 101 | "data": " debug" 102 | }, 103 | { 104 | "line": 80, 105 | "deleted": false, 106 | "data": " (os == \"win\" && bits == 32) # Bug 1567800" 107 | }, 108 | { 109 | "line": 81, 110 | "deleted": false, 111 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1567800" 112 | } 113 | ] 114 | } 115 | ] 116 | }, 117 | { 118 | "filename": "devtools/client/jsonview/test/browser.ini", 119 | "new": false, 120 | "deleted": false, 121 | "binary": false, 122 | "copied_from": null, 123 | "hunks": [ 124 | { 125 | "lines": [ 126 | { 127 | "line": 23, 128 | "deleted": false, 129 | "data": "skip-if = (os == 'linux' && webrender && !swgl) # bug 1720898" 130 | } 131 | ] 132 | } 133 | ] 134 | }, 135 | { 136 | "filename": "devtools/client/netmonitor/test/browser.ini", 137 | "new": false, 138 | "deleted": false, 139 | "binary": false, 140 | "copied_from": null, 141 | "hunks": [ 142 | { 143 | "lines": [ 144 | { 145 | "line": 95, 146 | "deleted": false, 147 | "data": "skip-if = (os == 'linux' && a11y_checks) # Bug 1721160" 148 | } 149 | ] 150 | } 151 | ] 152 | }, 153 | { 154 | "filename": "devtools/client/shared/test/browser.ini", 155 | "new": false, 156 | "deleted": false, 157 | "binary": false, 158 | "copied_from": null, 159 | "hunks": [ 160 | { 161 | "lines": [ 162 | { 163 | "line": 76, 164 | "deleted": false, 165 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 166 | }, 167 | { 168 | "line": 83, 169 | "deleted": false, 170 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 171 | } 172 | ] 173 | }, 174 | { 175 | "lines": [ 176 | { 177 | "line": 168, 178 | "deleted": false, 179 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 180 | }, 181 | { 182 | "line": 172, 183 | "deleted": false, 184 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 185 | }, 186 | { 187 | "line": 174, 188 | "deleted": false, 189 | "data": "skip-if =" 190 | }, 191 | { 192 | "line": 175, 193 | "deleted": false, 194 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 195 | }, 196 | { 197 | "line": 180, 198 | "deleted": false, 199 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 200 | }, 201 | { 202 | "line": 184, 203 | "deleted": false, 204 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 205 | }, 206 | { 207 | "line": 193, 208 | "deleted": false, 209 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 210 | }, 211 | { 212 | "line": 200, 213 | "deleted": false, 214 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 215 | }, 216 | { 217 | "line": 204, 218 | "deleted": false, 219 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 220 | }, 221 | { 222 | "line": 211, 223 | "deleted": false, 224 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 225 | }, 226 | { 227 | "line": 216, 228 | "deleted": false, 229 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 230 | }, 231 | { 232 | "line": 221, 233 | "deleted": false, 234 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 235 | }, 236 | { 237 | "line": 225, 238 | "deleted": false, 239 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 240 | }, 241 | { 242 | "line": 229, 243 | "deleted": false, 244 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 245 | }, 246 | { 247 | "line": 241, 248 | "deleted": false, 249 | "data": " (os == \"linux\" && !asan && !debug && !swgl && !ccov) # Bug 1721159" 250 | } 251 | ] 252 | } 253 | ] 254 | }, 255 | { 256 | "filename": "devtools/client/webconsole/test/browser/_webconsole.ini", 257 | "new": false, 258 | "deleted": false, 259 | "binary": false, 260 | "copied_from": null, 261 | "hunks": [ 262 | { 263 | "lines": [ 264 | { 265 | "line": 306, 266 | "deleted": true, 267 | "data": "skip-if = (os == \"linux\" && fission && !ccov) || (os == \"win\" && fission) #Bug 1601331" 268 | }, 269 | { 270 | "line": 306, 271 | "deleted": false, 272 | "data": "skip-if = (os == \"linux\" && fission && ccov) || (os == \"win\" && fission) #Bug 1601331" 273 | } 274 | ] 275 | } 276 | ] 277 | }, 278 | { 279 | "filename": "taskcluster/ci/test/mochitest.yml", 280 | "new": false, 281 | "deleted": false, 282 | "binary": false, 283 | "copied_from": null, 284 | "hunks": [ 285 | { 286 | "lines": [ 287 | { 288 | "line": 276, 289 | "deleted": true, 290 | "data": " linux.*64(-shippable)?/opt: ['fission', 'a11y-checks', 'wayland']" 291 | }, 292 | { 293 | "line": 276, 294 | "deleted": false, 295 | "data": " linux.*64(-shippable)?-qr/opt: ['fission', 'a11y-checks', 'wayland']" 296 | }, 297 | { 298 | "line": 283, 299 | "deleted": true, 300 | "data": " linux.*64(-shippable)?/(opt|debug): ['trunk']" 301 | }, 302 | { 303 | "line": 283, 304 | "deleted": false, 305 | "data": " linux.*64(-shippable)?-qr/(opt|debug): ['trunk']" 306 | }, 307 | { 308 | "line": 294, 309 | "deleted": true, 310 | "data": " linux.*64(-shippable)?(-qr)?/(opt|debug): 1" 311 | }, 312 | { 313 | "line": 295, 314 | "deleted": true, 315 | "data": " windows10-64(-shippable)?(-qr)?/(opt|debug): 1" 316 | }, 317 | { 318 | "line": 294, 319 | "deleted": false, 320 | "data": " linux.*64(-shippable)?-qr/(opt|debug): 1" 321 | }, 322 | { 323 | "line": 295, 324 | "deleted": false, 325 | "data": " windows10-64(-shippable)?-qr/(opt|debug): 1" 326 | }, 327 | { 328 | "line": 308, 329 | "deleted": true, 330 | "data": " linux.*64/debug: 12" 331 | }, 332 | { 333 | "line": 309, 334 | "deleted": true, 335 | "data": " macosx.*64/debug: 8" 336 | }, 337 | { 338 | "line": 308, 339 | "deleted": false, 340 | "data": " linux.*64-qr/debug: 12" 341 | }, 342 | { 343 | "line": 309, 344 | "deleted": false, 345 | "data": " macosx.*64-qr/debug: 8" 346 | }, 347 | { 348 | "line": 318, 349 | "deleted": true, 350 | "data": " linux.*64-[at]san/opt: xlarge # runs out of memory on default/m3.large" 351 | }, 352 | { 353 | "line": 318, 354 | "deleted": false, 355 | "data": " linux.*64-[at]san(-qr)?/opt: xlarge # runs out of memory on default/m3.large" 356 | } 357 | ] 358 | } 359 | ] 360 | }, 361 | { 362 | "filename": "taskcluster/ci/test/test-sets.yml", 363 | "new": false, 364 | "deleted": false, 365 | "binary": false, 366 | "copied_from": null, 367 | "hunks": [ 368 | { 369 | "lines": [ 370 | { 371 | "line": 175, 372 | "deleted": true, 373 | "data": " - mochitest-devtools-chrome" 374 | } 375 | ] 376 | }, 377 | { 378 | "lines": [ 379 | { 380 | "line": 202, 381 | "deleted": false, 382 | "data": " - mochitest-devtools-chrome" 383 | } 384 | ] 385 | }, 386 | { 387 | "lines": [ 388 | { 389 | "line": 220, 390 | "deleted": false, 391 | "data": " - mochitest-devtools-chrome" 392 | } 393 | ] 394 | }, 395 | { 396 | "lines": [ 397 | { 398 | "line": 244, 399 | "deleted": false, 400 | "data": " - mochitest-devtools-chrome" 401 | } 402 | ] 403 | } 404 | ] 405 | } 406 | ] 407 | } -------------------------------------------------------------------------------- /tests/output/6f5fc0d644dd.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "taskcluster/scripts/tester/test-linux.sh", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [] 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /tests/output/7dabae5e261a.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "browser/branding/aurora/content/jar.mn", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 11, 14 | "deleted": true, 15 | "data": " content/branding/icon48.png" 16 | }, 17 | { 18 | "line": 12, 19 | "deleted": true, 20 | "data": " content/branding/icon64.png" 21 | }, 22 | { 23 | "line": 15, 24 | "deleted": true, 25 | "data": " content/branding/icon128.png (../mozicon128.png)" 26 | }, 27 | { 28 | "line": 13, 29 | "deleted": false, 30 | "data": " content/branding/icon48.png" 31 | }, 32 | { 33 | "line": 14, 34 | "deleted": false, 35 | "data": " content/branding/icon64.png (../default64.png)" 36 | }, 37 | { 38 | "line": 15, 39 | "deleted": false, 40 | "data": " content/branding/icon128.png (../default128.png)" 41 | } 42 | ] 43 | } 44 | ] 45 | }, 46 | { 47 | "filename": "browser/branding/aurora/default128.png", 48 | "new": false, 49 | "deleted": false, 50 | "binary": false, 51 | "copied_from": "browser/branding/aurora/mozicon128.png", 52 | "hunks": [] 53 | }, 54 | { 55 | "filename": "browser/branding/aurora/default64.png", 56 | "new": false, 57 | "deleted": false, 58 | "binary": false, 59 | "copied_from": "browser/branding/aurora/content/icon64.png", 60 | "hunks": [] 61 | }, 62 | { 63 | "filename": "browser/branding/branding-common.mozbuild", 64 | "new": false, 65 | "deleted": false, 66 | "binary": false, 67 | "copied_from": null, 68 | "hunks": [ 69 | { 70 | "lines": [ 71 | { 72 | "line": 45, 73 | "deleted": false, 74 | "data": " 'default128.png'," 75 | }, 76 | { 77 | "line": 48, 78 | "deleted": true, 79 | "data": " 'mozicon128.png'," 80 | }, 81 | { 82 | "line": 49, 83 | "deleted": false, 84 | "data": " 'default64.png'," 85 | }, 86 | { 87 | "line": 50, 88 | "deleted": true, 89 | "data": " FINAL_TARGET_FILES.icons += ['mozicon128.png']" 90 | }, 91 | { 92 | "line": 52, 93 | "deleted": false, 94 | "data": " 'default128.png'," 95 | }, 96 | { 97 | "line": 56, 98 | "deleted": false, 99 | "data": " 'default64.png'," 100 | } 101 | ] 102 | } 103 | ] 104 | }, 105 | { 106 | "filename": "browser/branding/nightly/content/jar.mn", 107 | "new": false, 108 | "deleted": false, 109 | "binary": false, 110 | "copied_from": null, 111 | "hunks": [ 112 | { 113 | "lines": [ 114 | { 115 | "line": 11, 116 | "deleted": true, 117 | "data": " content/branding/icon48.png" 118 | }, 119 | { 120 | "line": 12, 121 | "deleted": true, 122 | "data": " content/branding/icon64.png" 123 | }, 124 | { 125 | "line": 15, 126 | "deleted": true, 127 | "data": " content/branding/icon128.png (../mozicon128.png)" 128 | }, 129 | { 130 | "line": 13, 131 | "deleted": false, 132 | "data": " content/branding/icon48.png" 133 | }, 134 | { 135 | "line": 14, 136 | "deleted": false, 137 | "data": " content/branding/icon64.png (../default64.png)" 138 | }, 139 | { 140 | "line": 15, 141 | "deleted": false, 142 | "data": " content/branding/icon128.png (../default128.png)" 143 | } 144 | ] 145 | } 146 | ] 147 | }, 148 | { 149 | "filename": "browser/branding/nightly/default128.png", 150 | "new": false, 151 | "deleted": false, 152 | "binary": false, 153 | "copied_from": "browser/branding/nightly/mozicon128.png", 154 | "hunks": [] 155 | }, 156 | { 157 | "filename": "browser/branding/nightly/default64.png", 158 | "new": false, 159 | "deleted": false, 160 | "binary": false, 161 | "copied_from": "browser/branding/nightly/content/icon64.png", 162 | "hunks": [] 163 | }, 164 | { 165 | "filename": "browser/branding/official/content/jar.mn", 166 | "new": false, 167 | "deleted": false, 168 | "binary": false, 169 | "copied_from": null, 170 | "hunks": [ 171 | { 172 | "lines": [ 173 | { 174 | "line": 11, 175 | "deleted": true, 176 | "data": " content/branding/icon48.png" 177 | }, 178 | { 179 | "line": 12, 180 | "deleted": true, 181 | "data": " content/branding/icon64.png" 182 | }, 183 | { 184 | "line": 13, 185 | "deleted": false, 186 | "data": " content/branding/icon48.png" 187 | }, 188 | { 189 | "line": 14, 190 | "deleted": false, 191 | "data": " content/branding/icon64.png (../default64.png)" 192 | } 193 | ] 194 | } 195 | ] 196 | }, 197 | { 198 | "filename": "browser/branding/official/default128.png", 199 | "new": false, 200 | "deleted": false, 201 | "binary": false, 202 | "copied_from": "browser/branding/official/mozicon128.png", 203 | "hunks": [] 204 | }, 205 | { 206 | "filename": "browser/branding/official/default64.png", 207 | "new": false, 208 | "deleted": false, 209 | "binary": false, 210 | "copied_from": "browser/branding/official/content/icon64.png", 211 | "hunks": [] 212 | }, 213 | { 214 | "filename": "browser/branding/unofficial/content/jar.mn", 215 | "new": false, 216 | "deleted": false, 217 | "binary": false, 218 | "copied_from": null, 219 | "hunks": [ 220 | { 221 | "lines": [ 222 | { 223 | "line": 12, 224 | "deleted": true, 225 | "data": " content/branding/icon48.png" 226 | }, 227 | { 228 | "line": 13, 229 | "deleted": true, 230 | "data": " content/branding/icon64.png" 231 | }, 232 | { 233 | "line": 16, 234 | "deleted": true, 235 | "data": " content/branding/icon128.png (../mozicon128.png)" 236 | }, 237 | { 238 | "line": 14, 239 | "deleted": false, 240 | "data": " content/branding/icon48.png" 241 | }, 242 | { 243 | "line": 15, 244 | "deleted": false, 245 | "data": " content/branding/icon64.png (../default64.png)" 246 | }, 247 | { 248 | "line": 16, 249 | "deleted": false, 250 | "data": " content/branding/icon128.png (../default128.png)" 251 | } 252 | ] 253 | } 254 | ] 255 | }, 256 | { 257 | "filename": "browser/branding/unofficial/default128.png", 258 | "new": false, 259 | "deleted": false, 260 | "binary": false, 261 | "copied_from": "browser/branding/unofficial/mozicon128.png", 262 | "hunks": [] 263 | }, 264 | { 265 | "filename": "browser/branding/unofficial/default64.png", 266 | "new": false, 267 | "deleted": false, 268 | "binary": false, 269 | "copied_from": "browser/branding/unofficial/content/icon64.png", 270 | "hunks": [] 271 | }, 272 | { 273 | "filename": "browser/installer/allowed-dupes.mn", 274 | "new": false, 275 | "deleted": false, 276 | "binary": false, 277 | "copied_from": null, 278 | "hunks": [ 279 | { 280 | "lines": [ 281 | { 282 | "line": 79, 283 | "deleted": false, 284 | "data": "browser/chrome/icons/default/default64.png" 285 | }, 286 | { 287 | "line": 80, 288 | "deleted": false, 289 | "data": "browser/chrome/icons/default/default128.png" 290 | } 291 | ] 292 | }, 293 | { 294 | "lines": [ 295 | { 296 | "line": 108, 297 | "deleted": true, 298 | "data": "browser/icons/mozicon128.png" 299 | } 300 | ] 301 | } 302 | ] 303 | }, 304 | { 305 | "filename": "browser/installer/package-manifest.in", 306 | "new": false, 307 | "deleted": false, 308 | "binary": false, 309 | "copied_from": null, 310 | "hunks": [ 311 | { 312 | "lines": [ 313 | { 314 | "line": 618, 315 | "deleted": false, 316 | "data": "@RESPATH@/browser/chrome/icons/default/default64.png" 317 | }, 318 | { 319 | "line": 619, 320 | "deleted": false, 321 | "data": "@RESPATH@/browser/chrome/icons/default/default128.png" 322 | } 323 | ] 324 | }, 325 | { 326 | "lines": [ 327 | { 328 | "line": 640, 329 | "deleted": true, 330 | "data": "; shell icons" 331 | }, 332 | { 333 | "line": 641, 334 | "deleted": true, 335 | "data": "@RESPATH@/browser/icons/*.png" 336 | } 337 | ] 338 | } 339 | ] 340 | } 341 | ] 342 | } -------------------------------------------------------------------------------- /tests/output/D174915.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "toolkit/content/tests/widgets/mochitest.ini", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 51, 14 | "deleted": false, 15 | "data": "[test_videocontrols_scrubber_position_nopreload.html]" 16 | } 17 | ] 18 | } 19 | ] 20 | }, 21 | { 22 | "filename": "toolkit/content/tests/widgets/test_videocontrols_scrubber_position.html", 23 | "new": false, 24 | "deleted": false, 25 | "binary": false, 26 | "copied_from": null, 27 | "hunks": [ 28 | { 29 | "lines": [ 30 | { 31 | "line": 2, 32 | "deleted": false, 33 | "data": "" 39 | } 40 | ] 41 | } 42 | ] 43 | }, 44 | { 45 | "filename": "toolkit/content/tests/widgets/test_videocontrols_scrubber_position_nopreload.html", 46 | "new": false, 47 | "deleted": false, 48 | "binary": false, 49 | "copied_from": "toolkit/content/tests/widgets/test_videocontrols_scrubber_position.html", 50 | "hunks": [ 51 | { 52 | "lines": [ 53 | { 54 | "line": 2, 55 | "deleted": false, 56 | "data": "" 62 | }, 63 | { 64 | "line": 4, 65 | "deleted": true, 66 | "data": " Video controls test - Initial scrubber position" 67 | }, 68 | { 69 | "line": 6, 70 | "deleted": false, 71 | "data": " Video controls test - Initial scrubber position when preload is turned off" 72 | }, 73 | { 74 | "line": 14, 75 | "deleted": true, 76 | "data": " " 77 | }, 78 | { 79 | "line": 16, 80 | "deleted": false, 81 | "data": " " 82 | }, 83 | { 84 | "line": 24, 85 | "deleted": true, 86 | "data": "add_task(async function setup() {" 87 | }, 88 | { 89 | "line": 25, 90 | "deleted": true, 91 | "data": " await new Promise(resolve => {" 92 | }, 93 | { 94 | "line": 26, 95 | "deleted": true, 96 | "data": " video.addEventListener(\"canplaythrough\", resolve, {once: true});" 97 | }, 98 | { 99 | "line": 27, 100 | "deleted": true, 101 | "data": " video.src = \"seek_with_sound.ogg\";" 102 | }, 103 | { 104 | "line": 28, 105 | "deleted": true, 106 | "data": " });" 107 | }, 108 | { 109 | "line": 29, 110 | "deleted": true, 111 | "data": "" 112 | }, 113 | { 114 | "line": 26, 115 | "deleted": false, 116 | "data": "add_task(function test_initial_scrubber_position() {" 117 | }, 118 | { 119 | "line": 32, 120 | "deleted": true, 121 | "data": "});" 122 | }, 123 | { 124 | "line": 34, 125 | "deleted": true, 126 | "data": "add_task(function test_initial_scrubber_position() {" 127 | }, 128 | { 129 | "line": 35, 130 | "deleted": true, 131 | "data": " // When the controls are shown after the initial video frame," 132 | }, 133 | { 134 | "line": 36, 135 | "deleted": true, 136 | "data": " // reflowedDimensions might not be set..." 137 | }, 138 | { 139 | "line": 37, 140 | "deleted": true, 141 | "data": " video.setAttribute(\"controls\", \"true\");" 142 | }, 143 | { 144 | "line": 38, 145 | "deleted": true, 146 | "data": "" 147 | }, 148 | { 149 | "line": 39, 150 | "deleted": true, 151 | "data": " // ... but we still want to ensure the initial scrubber position" 152 | }, 153 | { 154 | "line": 40, 155 | "deleted": true, 156 | "data": " // is reasonable." 157 | } 158 | ] 159 | } 160 | ] 161 | }, 162 | { 163 | "filename": "toolkit/content/widgets/videocontrols.js", 164 | "new": false, 165 | "deleted": false, 166 | "binary": false, 167 | "copied_from": null, 168 | "hunks": [ 169 | { 170 | "lines": [ 171 | { 172 | "line": 1237, 173 | "deleted": false, 174 | "data": " let scrubberProgress = Math.abs(" 175 | }, 176 | { 177 | "line": 1238, 178 | "deleted": false, 179 | "data": " currentTimeMs / durationMs - this.scrubber.value / this.scrubber.max" 180 | }, 181 | { 182 | "line": 1239, 183 | "deleted": false, 184 | "data": " );" 185 | }, 186 | { 187 | "line": 1240, 188 | "deleted": false, 189 | "data": " let devPxProgress =" 190 | }, 191 | { 192 | "line": 1241, 193 | "deleted": false, 194 | "data": " scrubberProgress *" 195 | }, 196 | { 197 | "line": 1242, 198 | "deleted": false, 199 | "data": " this.reflowedDimensions.scrubberWidth *" 200 | }, 201 | { 202 | "line": 1243, 203 | "deleted": false, 204 | "data": " this.window.devicePixelRatio;" 205 | }, 206 | { 207 | "line": 1238, 208 | "deleted": true, 209 | "data": " if (" 210 | }, 211 | { 212 | "line": 1239, 213 | "deleted": true, 214 | "data": " Math.abs(" 215 | }, 216 | { 217 | "line": 1240, 218 | "deleted": true, 219 | "data": " currentTimeMs / durationMs - this.scrubber.value / this.scrubber.max" 220 | }, 221 | { 222 | "line": 1241, 223 | "deleted": true, 224 | "data": " ) *" 225 | }, 226 | { 227 | "line": 1242, 228 | "deleted": true, 229 | "data": " this.reflowedDimensions.scrubberWidth *" 230 | }, 231 | { 232 | "line": 1243, 233 | "deleted": true, 234 | "data": " this.window.devicePixelRatio >" 235 | }, 236 | { 237 | "line": 1244, 238 | "deleted": true, 239 | "data": " 0.5" 240 | }, 241 | { 242 | "line": 1245, 243 | "deleted": true, 244 | "data": " ) {" 245 | }, 246 | { 247 | "line": 1245, 248 | "deleted": false, 249 | "data": " // Note that this.scrubber.max can be \"\" if unitialized," 250 | }, 251 | { 252 | "line": 1246, 253 | "deleted": false, 254 | "data": " // and either or both of currentTimeMs or durationMs can be 0, leading" 255 | }, 256 | { 257 | "line": 1247, 258 | "deleted": false, 259 | "data": " // to NaN or Infinity values for devPxProgress." 260 | }, 261 | { 262 | "line": 1248, 263 | "deleted": false, 264 | "data": " if (!this.scrubber.max || isNaN(devPxProgress) || devPxProgress > 0.5) {" 265 | } 266 | ] 267 | }, 268 | { 269 | "lines": [ 270 | { 271 | "line": 2879, 272 | "deleted": true, 273 | "data": " " 274 | }, 275 | { 276 | "line": 2882, 277 | "deleted": false, 278 | "data": " " 279 | } 280 | ] 281 | } 282 | ] 283 | } 284 | ] 285 | } -------------------------------------------------------------------------------- /tests/output/b3a7561624f9.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "xpcom/stub/Makefile.in", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 75, 14 | "deleted": false, 15 | "data": "# Must be included before DEPENDENT_LIBS_LIST starts so that apps have a chance" 16 | }, 17 | { 18 | "line": 76, 19 | "deleted": false, 20 | "data": "# of getting their stuff in before xul." 21 | }, 22 | { 23 | "line": 77, 24 | "deleted": false, 25 | "data": "# It is ok for this file not to exist" 26 | }, 27 | { 28 | "line": 78, 29 | "deleted": false, 30 | "data": "-include $(topsrcdir)/$(MOZ_BUILD_APP)/extradependlibs.mk" 31 | }, 32 | { 33 | "line": 79, 34 | "deleted": false, 35 | "data": "" 36 | } 37 | ] 38 | }, 39 | { 40 | "lines": [ 41 | { 42 | "line": 120, 43 | "deleted": true, 44 | "data": "# It is ok for this file not to exist" 45 | }, 46 | { 47 | "line": 121, 48 | "deleted": true, 49 | "data": "-include $(topsrcdir)/$(MOZ_BUILD_APP)/extradependlibs.mk" 50 | }, 51 | { 52 | "line": 122, 53 | "deleted": true, 54 | "data": "" 55 | } 56 | ] 57 | } 58 | ] 59 | } 60 | ] 61 | } -------------------------------------------------------------------------------- /tests/output/b3a7561624f9_modified.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "xpcom/stub/Makefile.in", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 75, 14 | "deleted": false, 15 | "data": "# Must be included before DEPENDENT_LIBS_LIST starts so that apps have a chance" 16 | }, 17 | { 18 | "line": 76, 19 | "deleted": false, 20 | "data": "# of getting their stuff in before xul." 21 | }, 22 | { 23 | "line": 77, 24 | "deleted": false, 25 | "data": "# It is ok for this file not to exist" 26 | }, 27 | { 28 | "line": 78, 29 | "deleted": false, 30 | "data": "-include $(topsrcdir)/$(MOZ_BUILD_APP)/extradependlibs.mk" 31 | }, 32 | { 33 | "line": 79, 34 | "deleted": false, 35 | "data": "" 36 | } 37 | ] 38 | }, 39 | { 40 | "lines": [ 41 | { 42 | "line": 120, 43 | "deleted": true, 44 | "data": "# It is ok for this file not to exist" 45 | }, 46 | { 47 | "line": 121, 48 | "deleted": true, 49 | "data": "-include $(topsrcdir)/$(MOZ_BUILD_APP)/extradependlibs.mk" 50 | }, 51 | { 52 | "line": 122, 53 | "deleted": true, 54 | "data": "" 55 | } 56 | ] 57 | } 58 | ] 59 | } 60 | ] 61 | } -------------------------------------------------------------------------------- /tests/output/basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "foo", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 226, 14 | "deleted": true, 15 | "data": "b" 16 | }, 17 | { 18 | "line": 226, 19 | "deleted": false, 20 | "data": "c" 21 | }, 22 | { 23 | "line": 227, 24 | "deleted": false, 25 | "data": "d" 26 | }, 27 | { 28 | "line": 228, 29 | "deleted": true, 30 | "data": "f" 31 | } 32 | ] 33 | } 34 | ] 35 | }, 36 | { 37 | "filename": "bar", 38 | "new": false, 39 | "deleted": false, 40 | "binary": false, 41 | "copied_from": null, 42 | "hunks": [] 43 | }, 44 | { 45 | "filename": "oof", 46 | "new": false, 47 | "deleted": false, 48 | "binary": false, 49 | "copied_from": null, 50 | "hunks": [ 51 | { 52 | "lines": [ 53 | { 54 | "line": 1, 55 | "deleted": false, 56 | "data": "a" 57 | }, 58 | { 59 | "line": 2, 60 | "deleted": false, 61 | "data": "b" 62 | } 63 | ] 64 | } 65 | ] 66 | }, 67 | { 68 | "filename": "rab", 69 | "new": false, 70 | "deleted": false, 71 | "binary": false, 72 | "copied_from": null, 73 | "hunks": [ 74 | { 75 | "lines": [ 76 | { 77 | "line": 226, 78 | "deleted": true, 79 | "data": "b" 80 | }, 81 | { 82 | "line": 226, 83 | "deleted": false, 84 | "data": "c" 85 | } 86 | ] 87 | } 88 | ] 89 | }, 90 | { 91 | "filename": "tata", 92 | "new": false, 93 | "deleted": false, 94 | "binary": false, 95 | "copied_from": "toto", 96 | "hunks": [] 97 | }, 98 | { 99 | "filename": "tete", 100 | "new": false, 101 | "deleted": false, 102 | "binary": true, 103 | "copied_from": null, 104 | "hunks": [] 105 | }, 106 | { 107 | "filename": "tutu", 108 | "new": false, 109 | "deleted": false, 110 | "binary": false, 111 | "copied_from": "titi", 112 | "hunks": [ 113 | { 114 | "lines": [ 115 | { 116 | "line": 2, 117 | "deleted": true, 118 | "data": "b" 119 | }, 120 | { 121 | "line": 2, 122 | "deleted": false, 123 | "data": "c" 124 | }, 125 | { 126 | "line": 4, 127 | "deleted": true, 128 | "data": "e" 129 | }, 130 | { 131 | "line": 5, 132 | "deleted": true, 133 | "data": "f" 134 | } 135 | ] 136 | } 137 | ] 138 | }, 139 | { 140 | "filename": "tyty", 141 | "new": false, 142 | "deleted": false, 143 | "binary": true, 144 | "copied_from": null, 145 | "hunks": [] 146 | }, 147 | { 148 | "filename": "ofo", 149 | "new": false, 150 | "deleted": false, 151 | "binary": false, 152 | "copied_from": null, 153 | "hunks": [ 154 | { 155 | "lines": [ 156 | { 157 | "line": 1, 158 | "deleted": true, 159 | "data": "a" 160 | }, 161 | { 162 | "line": 2, 163 | "deleted": true, 164 | "data": "b" 165 | }, 166 | { 167 | "line": 3, 168 | "deleted": true, 169 | "data": "c" 170 | } 171 | ] 172 | } 173 | ] 174 | }, 175 | { 176 | "filename": "arb", 177 | "new": false, 178 | "deleted": false, 179 | "binary": false, 180 | "copied_from": null, 181 | "hunks": [ 182 | { 183 | "lines": [ 184 | { 185 | "line": 226, 186 | "deleted": true, 187 | "data": "b" 188 | }, 189 | { 190 | "line": 226, 191 | "deleted": false, 192 | "data": "c" 193 | } 194 | ] 195 | }, 196 | { 197 | "lines": [ 198 | { 199 | "line": 326, 200 | "deleted": true, 201 | "data": "b" 202 | }, 203 | { 204 | "line": 326, 205 | "deleted": false, 206 | "data": "c" 207 | }, 208 | { 209 | "line": 328, 210 | "deleted": true, 211 | "data": "e" 212 | }, 213 | { 214 | "line": 329, 215 | "deleted": true, 216 | "data": "f" 217 | }, 218 | { 219 | "line": 329, 220 | "deleted": false, 221 | "data": "h" 222 | } 223 | ] 224 | }, 225 | { 226 | "lines": [ 227 | { 228 | "line": 426, 229 | "deleted": true, 230 | "data": "b" 231 | }, 232 | { 233 | "line": 460, 234 | "deleted": false, 235 | "data": "c" 236 | } 237 | ] 238 | } 239 | ] 240 | } 241 | ] 242 | } -------------------------------------------------------------------------------- /tests/output/c58e9e70f971.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "browser/extensions/webcompat-reporter/test/browser/browser_report_site_issue.js", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 14, 14 | "deleted": true, 15 | "data": " let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);" 16 | }, 17 | { 18 | "line": 14, 19 | "deleted": false, 20 | "data": " let screenshotPromise;" 21 | }, 22 | { 23 | "line": 15, 24 | "deleted": false, 25 | "data": " let newTabPromise = new Promise(resolve => {" 26 | }, 27 | { 28 | "line": 16, 29 | "deleted": false, 30 | "data": " gBrowser.tabContainer.addEventListener(\"TabOpen\", event => {" 31 | }, 32 | { 33 | "line": 17, 34 | "deleted": false, 35 | "data": " let tab = event.target;" 36 | }, 37 | { 38 | "line": 18, 39 | "deleted": false, 40 | "data": " screenshotPromise = BrowserTestUtils.waitForContentEvent(" 41 | }, 42 | { 43 | "line": 19, 44 | "deleted": false, 45 | "data": " tab.linkedBrowser, \"ScreenshotReceived\", false, null, true);" 46 | }, 47 | { 48 | "line": 20, 49 | "deleted": false, 50 | "data": " resolve(tab);" 51 | }, 52 | { 53 | "line": 21, 54 | "deleted": false, 55 | "data": " }, { once: true });" 56 | }, 57 | { 58 | "line": 22, 59 | "deleted": false, 60 | "data": " });" 61 | }, 62 | { 63 | "line": 18, 64 | "deleted": true, 65 | "data": "" 66 | }, 67 | { 68 | "line": 19, 69 | "deleted": true, 70 | "data": " await BrowserTestUtils.waitForContentEvent(tab2.linkedBrowser, \"ScreenshotReceived\", false, null, true);" 71 | }, 72 | { 73 | "line": 26, 74 | "deleted": false, 75 | "data": " await screenshotPromise;" 76 | } 77 | ] 78 | } 79 | ] 80 | } 81 | ] 82 | } -------------------------------------------------------------------------------- /tests/output/c6f9187b0b2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "dom/workers/ServiceWorkerEvents.cpp", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 672, 14 | "deleted": false, 15 | "data": " Telemetry::ScalarAdd(Telemetry::ScalarID::SW_SYNTHESIZED_RES_COUNT, 1);" 16 | }, 17 | { 18 | "line": 673, 19 | "deleted": false, 20 | "data": "" 21 | }, 22 | { 23 | "line": 674, 24 | "deleted": false, 25 | "data": " if (mRequestMode == RequestMode::Same_origin &&" 26 | }, 27 | { 28 | "line": 675, 29 | "deleted": false, 30 | "data": " response->Type() == ResponseType::Cors) {" 31 | }, 32 | { 33 | "line": 676, 34 | "deleted": false, 35 | "data": " Telemetry::ScalarAdd(Telemetry::ScalarID::SW_CORS_RES_FOR_SO_REQ_COUNT, 1);" 36 | }, 37 | { 38 | "line": 677, 39 | "deleted": false, 40 | "data": " }" 41 | }, 42 | { 43 | "line": 678, 44 | "deleted": false, 45 | "data": "" 46 | } 47 | ] 48 | } 49 | ] 50 | }, 51 | { 52 | "filename": "toolkit/components/telemetry/Scalars.yaml", 53 | "new": false, 54 | "deleted": false, 55 | "binary": false, 56 | "copied_from": null, 57 | "hunks": [ 58 | { 59 | "lines": [ 60 | { 61 | "line": 1361, 62 | "deleted": false, 63 | "data": "# The following section contains the service worker scalars." 64 | }, 65 | { 66 | "line": 1362, 67 | "deleted": false, 68 | "data": "sw:" 69 | }, 70 | { 71 | "line": 1363, 72 | "deleted": false, 73 | "data": " synthesized_res_count:" 74 | }, 75 | { 76 | "line": 1364, 77 | "deleted": false, 78 | "data": " bug_numbers:" 79 | }, 80 | { 81 | "line": 1365, 82 | "deleted": false, 83 | "data": " - 1416629" 84 | }, 85 | { 86 | "line": 1366, 87 | "deleted": false, 88 | "data": " description: >" 89 | }, 90 | { 91 | "line": 1367, 92 | "deleted": false, 93 | "data": " The count of number of synthesize response made by service workers." 94 | }, 95 | { 96 | "line": 1368, 97 | "deleted": false, 98 | "data": " expires: \"61\"" 99 | }, 100 | { 101 | "line": 1369, 102 | "deleted": false, 103 | "data": " kind: uint" 104 | }, 105 | { 106 | "line": 1370, 107 | "deleted": false, 108 | "data": " notification_emails:" 109 | }, 110 | { 111 | "line": 1371, 112 | "deleted": false, 113 | "data": " - sw-telemetry@mozilla.com" 114 | }, 115 | { 116 | "line": 1372, 117 | "deleted": false, 118 | "data": " - ttung@mozilla.com" 119 | }, 120 | { 121 | "line": 1373, 122 | "deleted": false, 123 | "data": " release_channel_collection: opt-out" 124 | }, 125 | { 126 | "line": 1374, 127 | "deleted": false, 128 | "data": " record_in_processes:" 129 | }, 130 | { 131 | "line": 1375, 132 | "deleted": false, 133 | "data": " - 'main'" 134 | }, 135 | { 136 | "line": 1376, 137 | "deleted": false, 138 | "data": " - 'content'" 139 | }, 140 | { 141 | "line": 1377, 142 | "deleted": false, 143 | "data": "" 144 | }, 145 | { 146 | "line": 1378, 147 | "deleted": false, 148 | "data": " cors_res_for_so_req_count:" 149 | }, 150 | { 151 | "line": 1379, 152 | "deleted": false, 153 | "data": " bug_numbers:" 154 | }, 155 | { 156 | "line": 1380, 157 | "deleted": false, 158 | "data": " - 1416629" 159 | }, 160 | { 161 | "line": 1381, 162 | "deleted": false, 163 | "data": " description: >" 164 | }, 165 | { 166 | "line": 1382, 167 | "deleted": false, 168 | "data": " The count of number of synthesize response made by service workers and" 169 | }, 170 | { 171 | "line": 1383, 172 | "deleted": false, 173 | "data": " it's a cors type resposne for a same-origin mode request." 174 | }, 175 | { 176 | "line": 1384, 177 | "deleted": false, 178 | "data": " expires: \"61\"" 179 | }, 180 | { 181 | "line": 1385, 182 | "deleted": false, 183 | "data": " kind: uint" 184 | }, 185 | { 186 | "line": 1386, 187 | "deleted": false, 188 | "data": " notification_emails:" 189 | }, 190 | { 191 | "line": 1387, 192 | "deleted": false, 193 | "data": " - sw-telemetry@mozilla.com" 194 | }, 195 | { 196 | "line": 1388, 197 | "deleted": false, 198 | "data": " - ttung@mozilla.com" 199 | }, 200 | { 201 | "line": 1389, 202 | "deleted": false, 203 | "data": " release_channel_collection: opt-out" 204 | }, 205 | { 206 | "line": 1390, 207 | "deleted": false, 208 | "data": " record_in_processes:" 209 | }, 210 | { 211 | "line": 1391, 212 | "deleted": false, 213 | "data": " - 'main'" 214 | }, 215 | { 216 | "line": 1392, 217 | "deleted": false, 218 | "data": " - 'content'" 219 | }, 220 | { 221 | "line": 1393, 222 | "deleted": false, 223 | "data": "" 224 | } 225 | ] 226 | } 227 | ] 228 | } 229 | ] 230 | } -------------------------------------------------------------------------------- /tests/output/d4f80c4ba719.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "gfx/thebes/gfxFont.cpp", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 3484, 14 | "deleted": true, 15 | "data": " mFontEntry->GetSVGGlyphExtents(aDrawTarget, aGlyphID, &svgBounds)) {" 16 | }, 17 | { 18 | "line": 3484, 19 | "deleted": false, 20 | "data": " mFontEntry->GetSVGGlyphExtents(aDrawTarget, aGlyphID," 21 | }, 22 | { 23 | "line": 3485, 24 | "deleted": false, 25 | "data": " GetAdjustedSize(), &svgBounds)) {" 26 | }, 27 | { 28 | "line": 3494, 29 | "deleted": true, 30 | "data": " cairo_glyph_t glyph;" 31 | }, 32 | { 33 | "line": 3495, 34 | "deleted": true, 35 | "data": " glyph.index = aGlyphID;" 36 | }, 37 | { 38 | "line": 3496, 39 | "deleted": true, 40 | "data": " glyph.x = 0;" 41 | }, 42 | { 43 | "line": 3497, 44 | "deleted": true, 45 | "data": " glyph.y = 0;" 46 | }, 47 | { 48 | "line": 3498, 49 | "deleted": true, 50 | "data": " cairo_text_extents_t extents;" 51 | }, 52 | { 53 | "line": 3499, 54 | "deleted": true, 55 | "data": " cairo_glyph_extents(gfxFont::RefCairo(aDrawTarget), &glyph, 1, &extents);" 56 | }, 57 | { 58 | "line": 3495, 59 | "deleted": false, 60 | "data": " RefPtr sf = GetScaledFont(aDrawTarget);" 61 | }, 62 | { 63 | "line": 3496, 64 | "deleted": false, 65 | "data": " uint16_t glyphIndex = aGlyphID;" 66 | }, 67 | { 68 | "line": 3497, 69 | "deleted": false, 70 | "data": " GlyphMetrics metrics;" 71 | }, 72 | { 73 | "line": 3498, 74 | "deleted": false, 75 | "data": " if (mAntialiasOption == kAntialiasNone) {" 76 | }, 77 | { 78 | "line": 3499, 79 | "deleted": false, 80 | "data": " sf->GetGlyphDesignMetrics(&glyphIndex, 1, &metrics);" 81 | }, 82 | { 83 | "line": 3500, 84 | "deleted": false, 85 | "data": " } else {" 86 | }, 87 | { 88 | "line": 3501, 89 | "deleted": false, 90 | "data": " aDrawTarget->GetGlyphRasterizationMetrics(sf, &glyphIndex, 1, &metrics);" 91 | }, 92 | { 93 | "line": 3502, 94 | "deleted": false, 95 | "data": " }" 96 | }, 97 | { 98 | "line": 3503, 99 | "deleted": true, 100 | "data": " if (!aNeedTight && extents.x_bearing >= 0 &&" 101 | }, 102 | { 103 | "line": 3504, 104 | "deleted": true, 105 | "data": " extents.y_bearing >= -fontMetrics.maxAscent &&" 106 | }, 107 | { 108 | "line": 3505, 109 | "deleted": true, 110 | "data": " extents.height + extents.y_bearing <= fontMetrics.maxDescent) {" 111 | }, 112 | { 113 | "line": 3506, 114 | "deleted": false, 115 | "data": " if (!aNeedTight && metrics.mXBearing >= 0.0 &&" 116 | }, 117 | { 118 | "line": 3507, 119 | "deleted": false, 120 | "data": " metrics.mYBearing >= -fontMetrics.maxAscent &&" 121 | }, 122 | { 123 | "line": 3508, 124 | "deleted": false, 125 | "data": " metrics.mHeight + metrics.mYBearing <= fontMetrics.maxDescent) {" 126 | }, 127 | { 128 | "line": 3507, 129 | "deleted": true, 130 | "data": " uint32_t(ceil((extents.x_bearing + extents.width)*appUnitsPerDevUnit));" 131 | }, 132 | { 133 | "line": 3510, 134 | "deleted": false, 135 | "data": " uint32_t(ceil((metrics.mXBearing + metrics.mWidth)*appUnitsPerDevUnit));" 136 | }, 137 | { 138 | "line": 3520, 139 | "deleted": true, 140 | "data": " gfxRect bounds(extents.x_bearing*d2a, extents.y_bearing*d2a," 141 | }, 142 | { 143 | "line": 3521, 144 | "deleted": true, 145 | "data": " extents.width*d2a, extents.height*d2a);" 146 | }, 147 | { 148 | "line": 3523, 149 | "deleted": false, 150 | "data": " gfxRect bounds(metrics.mXBearing * d2a, metrics.mYBearing * d2a," 151 | }, 152 | { 153 | "line": 3524, 154 | "deleted": false, 155 | "data": " metrics.mWidth * d2a, metrics.mHeight * d2a);" 156 | } 157 | ] 158 | } 159 | ] 160 | }, 161 | { 162 | "filename": "gfx/thebes/gfxFontEntry.cpp", 163 | "new": false, 164 | "deleted": false, 165 | "binary": false, 166 | "copied_from": null, 167 | "hunks": [ 168 | { 169 | "lines": [ 170 | { 171 | "line": 37, 172 | "deleted": true, 173 | "data": "#include \"cairo.h\"" 174 | }, 175 | { 176 | "line": 38, 177 | "deleted": true, 178 | "data": "" 179 | } 180 | ] 181 | }, 182 | { 183 | "lines": [ 184 | { 185 | "line": 322, 186 | "deleted": true, 187 | "data": " gfxRect *aResult)" 188 | }, 189 | { 190 | "line": 320, 191 | "deleted": false, 192 | "data": " gfxFloat aSize, gfxRect* aResult)" 193 | }, 194 | { 195 | "line": 329, 196 | "deleted": true, 197 | "data": " cairo_matrix_t fontMatrix;" 198 | }, 199 | { 200 | "line": 330, 201 | "deleted": true, 202 | "data": " cairo_get_font_matrix(gfxFont::RefCairo(aDrawTarget), &fontMatrix);" 203 | }, 204 | { 205 | "line": 331, 206 | "deleted": true, 207 | "data": "" 208 | }, 209 | { 210 | "line": 332, 211 | "deleted": true, 212 | "data": " gfxMatrix svgToAppSpace(fontMatrix.xx, fontMatrix.yx," 213 | }, 214 | { 215 | "line": 333, 216 | "deleted": true, 217 | "data": " fontMatrix.xy, fontMatrix.yy," 218 | }, 219 | { 220 | "line": 334, 221 | "deleted": true, 222 | "data": " fontMatrix.x0, fontMatrix.y0);" 223 | }, 224 | { 225 | "line": 335, 226 | "deleted": true, 227 | "data": " svgToAppSpace.PreScale(1.0f / mUnitsPerEm, 1.0f / mUnitsPerEm);" 228 | }, 229 | { 230 | "line": 336, 231 | "deleted": true, 232 | "data": "" 233 | }, 234 | { 235 | "line": 337, 236 | "deleted": true, 237 | "data": " return mSVGGlyphs->GetGlyphExtents(aGlyphId, svgToAppSpace, aResult);" 238 | }, 239 | { 240 | "line": 327, 241 | "deleted": false, 242 | "data": " gfxMatrix svgToApp(aSize / mUnitsPerEm, 0, 0, aSize / mUnitsPerEm, 0, 0);" 243 | }, 244 | { 245 | "line": 328, 246 | "deleted": false, 247 | "data": " return mSVGGlyphs->GetGlyphExtents(aGlyphId, svgToApp, aResult);" 248 | } 249 | ] 250 | } 251 | ] 252 | }, 253 | { 254 | "filename": "gfx/thebes/gfxFontEntry.h", 255 | "new": false, 256 | "deleted": false, 257 | "binary": false, 258 | "copied_from": null, 259 | "hunks": [ 260 | { 261 | "lines": [ 262 | { 263 | "line": 208, 264 | "deleted": true, 265 | "data": " gfxRect *aResult);" 266 | }, 267 | { 268 | "line": 208, 269 | "deleted": false, 270 | "data": " gfxFloat aSize, gfxRect* aResult);" 271 | } 272 | ] 273 | } 274 | ] 275 | }, 276 | { 277 | "filename": "gfx/thebes/gfxTextRun.cpp", 278 | "new": false, 279 | "deleted": false, 280 | "binary": false, 281 | "copied_from": null, 282 | "hunks": [ 283 | { 284 | "lines": [ 285 | { 286 | "line": 32, 287 | "deleted": true, 288 | "data": "#include \"cairo.h\"" 289 | }, 290 | { 291 | "line": 33, 292 | "deleted": true, 293 | "data": "" 294 | } 295 | ] 296 | }, 297 | { 298 | "lines": [ 299 | { 300 | "line": 1691, 301 | "deleted": true, 302 | "data": " bool fontIsSetup = false;" 303 | }, 304 | { 305 | "line": 1703, 306 | "deleted": true, 307 | "data": " if (!fontIsSetup) {" 308 | }, 309 | { 310 | "line": 1704, 311 | "deleted": true, 312 | "data": " if (!font->SetupCairoFont(aRefDrawTarget)) {" 313 | }, 314 | { 315 | "line": 1705, 316 | "deleted": true, 317 | "data": " NS_WARNING(\"failed to set up font for glyph extents\");" 318 | }, 319 | { 320 | "line": 1706, 321 | "deleted": true, 322 | "data": " break;" 323 | }, 324 | { 325 | "line": 1707, 326 | "deleted": true, 327 | "data": " }" 328 | }, 329 | { 330 | "line": 1708, 331 | "deleted": true, 332 | "data": " fontIsSetup = true;" 333 | }, 334 | { 335 | "line": 1709, 336 | "deleted": true, 337 | "data": " }" 338 | } 339 | ] 340 | }, 341 | { 342 | "lines": [ 343 | { 344 | "line": 1729, 345 | "deleted": true, 346 | "data": " if (!fontIsSetup) {" 347 | }, 348 | { 349 | "line": 1730, 350 | "deleted": true, 351 | "data": " if (!font->SetupCairoFont(aRefDrawTarget)) {" 352 | }, 353 | { 354 | "line": 1731, 355 | "deleted": true, 356 | "data": " NS_WARNING(\"failed to set up font for glyph extents\");" 357 | }, 358 | { 359 | "line": 1732, 360 | "deleted": true, 361 | "data": " break;" 362 | }, 363 | { 364 | "line": 1733, 365 | "deleted": true, 366 | "data": " }" 367 | }, 368 | { 369 | "line": 1734, 370 | "deleted": true, 371 | "data": " fontIsSetup = true;" 372 | }, 373 | { 374 | "line": 1735, 375 | "deleted": true, 376 | "data": " }" 377 | } 378 | ] 379 | } 380 | ] 381 | }, 382 | { 383 | "filename": "layout/reftests/border-radius/reftest.list", 384 | "new": false, 385 | "deleted": false, 386 | "binary": false, 387 | "copied_from": null, 388 | "hunks": [ 389 | { 390 | "lines": [ 391 | { 392 | "line": 54, 393 | "deleted": true, 394 | "data": "fuzzy-if(winWidget,105,71) fuzzy-if(Android,8,469) fuzzy-if(skiaContent,7,58) fuzzy-if(d3d11&&advancedLayers,120,319) fuzzy-if(winWidget&&stylo,137,319) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical" 395 | }, 396 | { 397 | "line": 54, 398 | "deleted": false, 399 | "data": "fuzzy-if(winWidget,105,71) fuzzy-if(Android,8,469) fuzzy-if(skiaContent,7,58) fuzzy-if(d3d11&&advancedLayers,120,319) fuzzy-if(winWidget&&stylo,144,319) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical" 400 | } 401 | ] 402 | } 403 | ] 404 | } 405 | ] 406 | } -------------------------------------------------------------------------------- /tests/output/d8571fb523a0.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "dom/media/test/crashtests/crashtests.list", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 121, 14 | "deleted": false, 15 | "data": "load empty-samples.webm # Bug 1540580" 16 | } 17 | ] 18 | } 19 | ] 20 | }, 21 | { 22 | "filename": "dom/media/test/crashtests/empty-samples.webm", 23 | "new": false, 24 | "deleted": false, 25 | "binary": false, 26 | "copied_from": null, 27 | "hunks": [] 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /tests/output/dfe0b0d0827e.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "testing/mochitest/moz.build", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 54, 14 | "deleted": true, 15 | "data": " 'tests/SimpleTest/AddTask.js'," 16 | } 17 | ] 18 | } 19 | ] 20 | }, 21 | { 22 | "filename": "testing/mochitest/tests/SimpleTest/AddTask.js", 23 | "new": false, 24 | "deleted": false, 25 | "binary": false, 26 | "copied_from": null, 27 | "hunks": [] 28 | }, 29 | { 30 | "filename": "testing/mochitest/tests/SimpleTest/moz.build", 31 | "new": false, 32 | "deleted": false, 33 | "binary": false, 34 | "copied_from": null, 35 | "hunks": [ 36 | { 37 | "lines": [ 38 | { 39 | "line": 10, 40 | "deleted": true, 41 | "data": " 'AddTask.js'," 42 | } 43 | ] 44 | } 45 | ] 46 | } 47 | ] 48 | } -------------------------------------------------------------------------------- /tests/output/empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [] 3 | } -------------------------------------------------------------------------------- /tests/output/issue68.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "js/src/vm/Printer.cpp", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 55, 14 | "deleted": true, 15 | "data": " for (char16_t c: str) {" 16 | }, 17 | { 18 | "line": 55, 19 | "deleted": false, 20 | "data": " for (char16_t c : str) {" 21 | } 22 | ] 23 | }, 24 | { 25 | "lines": [ 26 | { 27 | "line": 248, 28 | "deleted": true, 29 | "data": " for (char16_t c: str) {" 30 | }, 31 | { 32 | "line": 248, 33 | "deleted": false, 34 | "data": " for (char16_t c : str) {" 35 | } 36 | ] 37 | } 38 | ] 39 | }, 40 | { 41 | "filename": "js/src/vm/BytecodeUtil.cpp", 42 | "new": false, 43 | "deleted": false, 44 | "binary": false, 45 | "copied_from": null, 46 | "hunks": [ 47 | { 48 | "lines": [ 49 | { 50 | "line": 2311, 51 | "deleted": true, 52 | "data": "UniqueChars ExpressionDecompiler::getOutput() {" 53 | }, 54 | { 55 | "line": 2312, 56 | "deleted": true, 57 | "data": " return sprinter.release();" 58 | }, 59 | { 60 | "line": 2313, 61 | "deleted": true, 62 | "data": "}" 63 | }, 64 | { 65 | "line": 2311, 66 | "deleted": false, 67 | "data": "UniqueChars ExpressionDecompiler::getOutput() { return sprinter.release(); }" 68 | } 69 | ] 70 | } 71 | ] 72 | } 73 | ] 74 | } -------------------------------------------------------------------------------- /tests/output/janx.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "dom/media/CubebUtils.cpp", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 685, 14 | "deleted": true, 15 | "data": " } else if (aPreferred == CUBEB_DEVICE_PREF_ALL) { // before: readability-else-after-return" 16 | }, 17 | { 18 | "line": 685, 19 | "deleted": false, 20 | "data": " } else if (aPreferred ==" 21 | }, 22 | { 23 | "line": 686, 24 | "deleted": false, 25 | "data": " CUBEB_DEVICE_PREF_ALL) { // before: readability-else-after-return" 26 | } 27 | ] 28 | } 29 | ] 30 | }, 31 | { 32 | "filename": "js/ductwork/debugger/JSDebugger.cpp", 33 | "new": false, 34 | "deleted": false, 35 | "binary": false, 36 | "copied_from": null, 37 | "hunks": [ 38 | { 39 | "lines": [ 40 | { 41 | "line": 54, 42 | "deleted": true, 43 | "data": " JSAutoRealm ar(cx, obj);" 44 | }, 45 | { 46 | "line": 55, 47 | "deleted": true, 48 | "data": " if (!JS_DefineDebuggerObject(cx, obj)) {" 49 | }, 50 | { 51 | "line": 56, 52 | "deleted": true, 53 | "data": " return NS_ERROR_FAILURE; } // after: clang-format" 54 | }, 55 | { 56 | "line": 54, 57 | "deleted": false, 58 | "data": " JSAutoRealm ar(cx, obj);" 59 | }, 60 | { 61 | "line": 55, 62 | "deleted": false, 63 | "data": " if (!JS_DefineDebuggerObject(cx, obj)) {" 64 | }, 65 | { 66 | "line": 56, 67 | "deleted": false, 68 | "data": " return NS_ERROR_FAILURE;" 69 | }, 70 | { 71 | "line": 57, 72 | "deleted": false, 73 | "data": " } // after: clang-format" 74 | } 75 | ] 76 | } 77 | ] 78 | }, 79 | { 80 | "filename": "js/src/jsapi.cpp", 81 | "new": false, 82 | "deleted": false, 83 | "binary": false, 84 | "copied_from": null, 85 | "hunks": [ 86 | { 87 | "lines": [ 88 | { 89 | "line": 125, 90 | "deleted": true, 91 | "data": " \"line 1\"," 92 | }, 93 | { 94 | "line": 126, 95 | "deleted": true, 96 | "data": " \"line 2\"," 97 | }, 98 | { 99 | "line": 127, 100 | "deleted": true, 101 | "data": " \"line 3\"," 102 | }, 103 | { 104 | "line": 128, 105 | "deleted": true, 106 | "data": " \"line 4\"," 107 | }, 108 | { 109 | "line": 129, 110 | "deleted": true, 111 | "data": " \"line 5\"," 112 | }, 113 | { 114 | "line": 130, 115 | "deleted": true, 116 | "data": " \"line 6\" // after: bugprone-suspicious-missing-comma" 117 | }, 118 | { 119 | "line": 131, 120 | "deleted": true, 121 | "data": " \"line 7\"," 122 | }, 123 | { 124 | "line": 132, 125 | "deleted": true, 126 | "data": " \"line 8\"," 127 | }, 128 | { 129 | "line": 125, 130 | "deleted": false, 131 | "data": " \"line 1\"," 132 | }, 133 | { 134 | "line": 126, 135 | "deleted": false, 136 | "data": " \"line 2\"," 137 | }, 138 | { 139 | "line": 127, 140 | "deleted": false, 141 | "data": " \"line 3\"," 142 | }, 143 | { 144 | "line": 128, 145 | "deleted": false, 146 | "data": " \"line 4\"," 147 | }, 148 | { 149 | "line": 129, 150 | "deleted": false, 151 | "data": " \"line 5\"," 152 | }, 153 | { 154 | "line": 130, 155 | "deleted": false, 156 | "data": " \"line 6\" // after: bugprone-suspicious-missing-comma" 157 | }, 158 | { 159 | "line": 131, 160 | "deleted": false, 161 | "data": " \"line 7\"," 162 | }, 163 | { 164 | "line": 132, 165 | "deleted": false, 166 | "data": " \"line 8\"," 167 | }, 168 | { 169 | "line": 141, 170 | "deleted": true, 171 | "data": "class AnnotateConflict {" 172 | }, 173 | { 174 | "line": 142, 175 | "deleted": true, 176 | "data": " MOZ_NO_DANGLING_ON_TEMPORARIES int *get() && { return nullptr; } // after: mozilla-dangling-on-temporary" 177 | }, 178 | { 179 | "line": 143, 180 | "deleted": true, 181 | "data": " MOZ_NO_DANGLING_ON_TEMPORARIES int test() { return 0; } // after: mozilla-dangling-on-temporary" 182 | }, 183 | { 184 | "line": 141, 185 | "deleted": false, 186 | "data": "class AnnotateConflict" 187 | }, 188 | { 189 | "line": 142, 190 | "deleted": false, 191 | "data": "{" 192 | }, 193 | { 194 | "line": 143, 195 | "deleted": false, 196 | "data": " MOZ_NO_DANGLING_ON_TEMPORARIES int* get() &&" 197 | }, 198 | { 199 | "line": 144, 200 | "deleted": false, 201 | "data": " {" 202 | }, 203 | { 204 | "line": 145, 205 | "deleted": false, 206 | "data": " return nullptr;" 207 | }, 208 | { 209 | "line": 146, 210 | "deleted": false, 211 | "data": " } // after: mozilla-dangling-on-temporary" 212 | }, 213 | { 214 | "line": 147, 215 | "deleted": false, 216 | "data": " MOZ_NO_DANGLING_ON_TEMPORARIES int test() { return 0; } // after: mozilla-dangling-on-temporary" 217 | } 218 | ] 219 | }, 220 | { 221 | "lines": [ 222 | { 223 | "line": 195, 224 | "deleted": true, 225 | "data": " else if (ErrorTakesArguments(code_)) { // after: readability-misleading-indentation or readability-else-after-return" 226 | }, 227 | { 228 | "line": 199, 229 | "deleted": false, 230 | "data": " else if (" 231 | }, 232 | { 233 | "line": 200, 234 | "deleted": false, 235 | "data": " ErrorTakesArguments(" 236 | }, 237 | { 238 | "line": 201, 239 | "deleted": false, 240 | "data": " code_)) { // after: readability-misleading-indentation or readability-else-after-return" 241 | } 242 | ] 243 | }, 244 | { 245 | "lines": [ 246 | { 247 | "line": 227, 248 | "deleted": true, 249 | "data": " for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // after: clang-analyzer-security.FloatLoopCounter" 250 | }, 251 | { 252 | "line": 233, 253 | "deleted": false, 254 | "data": " for (float x = 0.1f; x <= 1.0f; x += 0.1f) {" 255 | }, 256 | { 257 | "line": 234, 258 | "deleted": false, 259 | "data": " } // after: clang-analyzer-security.FloatLoopCounter" 260 | }, 261 | { 262 | "line": 233, 263 | "deleted": true, 264 | "data": " if (x < y); // after: bugprone-suspicious-semicolon; readability-braces-around-statements" 265 | }, 266 | { 267 | "line": 240, 268 | "deleted": false, 269 | "data": " if (x < y)" 270 | }, 271 | { 272 | "line": 241, 273 | "deleted": false, 274 | "data": " ; // after: bugprone-suspicious-semicolon; readability-braces-around-statements" 275 | }, 276 | { 277 | "line": 235, 278 | "deleted": true, 279 | "data": " x++;" 280 | }, 281 | { 282 | "line": 243, 283 | "deleted": false, 284 | "data": " x++;" 285 | }, 286 | { 287 | "line": 248, 288 | "deleted": true, 289 | "data": "JS::ObjectOpResult::failCantRedefineProp(void) // (should not be published: modernize-redundant-void-arg)" 290 | }, 291 | { 292 | "line": 256, 293 | "deleted": false, 294 | "data": "JS::ObjectOpResult::failCantRedefineProp(" 295 | }, 296 | { 297 | "line": 257, 298 | "deleted": false, 299 | "data": " void) // (should not be published: modernize-redundant-void-arg)" 300 | } 301 | ] 302 | }, 303 | { 304 | "lines": [ 305 | { 306 | "line": 365, 307 | "deleted": true, 308 | "data": " for (const std::pair>& p : my_map) {} // after: performance-implicit-conversion-in-loop" 309 | }, 310 | { 311 | "line": 374, 312 | "deleted": false, 313 | "data": " for (const std::pair>& p : my_map) {" 314 | }, 315 | { 316 | "line": 375, 317 | "deleted": false, 318 | "data": " } // after: performance-implicit-conversion-in-loop" 319 | } 320 | ] 321 | } 322 | ] 323 | } 324 | ] 325 | } -------------------------------------------------------------------------------- /tests/output/new_file_with_git.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "a.txt", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 1, 14 | "deleted": false, 15 | "data": "a" 16 | }, 17 | { 18 | "line": 2, 19 | "deleted": false, 20 | "data": "b" 21 | }, 22 | { 23 | "line": 3, 24 | "deleted": false, 25 | "data": "c" 26 | } 27 | ] 28 | } 29 | ] 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /tests/output/no_git_header.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffs": [ 3 | { 4 | "filename": "gfx/2d/Factory.cpp", 5 | "new": false, 6 | "deleted": false, 7 | "binary": false, 8 | "copied_from": null, 9 | "hunks": [ 10 | { 11 | "lines": [ 12 | { 13 | "line": 616, 14 | "deleted": true, 15 | "data": " CGFontRef aCGFont, const RefPtr& aUnscaledFont, Float aSize, const DeviceColor& aFontSmoothingBackgroundColor, bool aUseFontSmoothing, bool aApplySyntheticBold) {" 16 | }, 17 | { 18 | "line": 617, 19 | "deleted": true, 20 | "data": " return MakeAndAddRef(aCGFont, aUnscaledFont, aSize, false, aFontSmoothingBackgroundColor, aUseFontSmoothing, aApplySyntheticBold);" 21 | }, 22 | { 23 | "line": 616, 24 | "deleted": false, 25 | "data": " CGFontRef aCGFont, const RefPtr& aUnscaledFont, Float aSize," 26 | }, 27 | { 28 | "line": 617, 29 | "deleted": false, 30 | "data": " const DeviceColor& aFontSmoothingBackgroundColor, bool aUseFontSmoothing," 31 | }, 32 | { 33 | "line": 618, 34 | "deleted": false, 35 | "data": " bool aApplySyntheticBold) {" 36 | }, 37 | { 38 | "line": 619, 39 | "deleted": false, 40 | "data": " return MakeAndAddRef(aCGFont, aUnscaledFont, aSize, false," 41 | }, 42 | { 43 | "line": 620, 44 | "deleted": false, 45 | "data": " aFontSmoothingBackgroundColor," 46 | }, 47 | { 48 | "line": 621, 49 | "deleted": false, 50 | "data": " aUseFontSmoothing, aApplySyntheticBold);" 51 | } 52 | ] 53 | } 54 | ] 55 | }, 56 | { 57 | "filename": "dom/canvas/ClientWebGLContext.cpp", 58 | "new": false, 59 | "deleted": false, 60 | "binary": false, 61 | "copied_from": null, 62 | "hunks": [ 63 | { 64 | "lines": [ 65 | { 66 | "line": 118, 67 | "deleted": true, 68 | "data": " }else {" 69 | }, 70 | { 71 | "line": 119, 72 | "deleted": true, 73 | "data": "\t\t// Comment to trigger readability-else-after-return" 74 | }, 75 | { 76 | "line": 120, 77 | "deleted": true, 78 | "data": "\t\tconst auto x = \"aa\";" 79 | }, 80 | { 81 | "line": 121, 82 | "deleted": true, 83 | "data": "\t}" 84 | }, 85 | { 86 | "line": 118, 87 | "deleted": false, 88 | "data": " } else {" 89 | }, 90 | { 91 | "line": 119, 92 | "deleted": false, 93 | "data": " // Comment to trigger readability-else-after-return" 94 | }, 95 | { 96 | "line": 120, 97 | "deleted": false, 98 | "data": " const auto x = \"aa\";" 99 | }, 100 | { 101 | "line": 121, 102 | "deleted": false, 103 | "data": " }" 104 | } 105 | ] 106 | } 107 | ] 108 | }, 109 | { 110 | "filename": "accessible/xul/XULAlertAccessible.cpp", 111 | "new": false, 112 | "deleted": false, 113 | "binary": false, 114 | "copied_from": null, 115 | "hunks": [ 116 | { 117 | "lines": [ 118 | { 119 | "line": 36, 120 | "deleted": true, 121 | "data": "\tif (false) return true;" 122 | }, 123 | { 124 | "line": 36, 125 | "deleted": false, 126 | "data": " if (false) return true;" 127 | } 128 | ] 129 | } 130 | ] 131 | } 132 | ] 133 | } -------------------------------------------------------------------------------- /tests/patches/6f5fc0d644dd.patch: -------------------------------------------------------------------------------- 1 | # HG changeset patch 2 | # User Mike Shal 3 | # Date 1552953181 0 4 | # lun. mars 18 23:53:01 2019 +0000 5 | # Node ID 6f5fc0d644dd1eb83294ce41b2b47be44c2d9783 6 | # Parent 53d3443e55d95af494d6c8bdc3d2d7a52c5eff1e 7 | Bug 632954 - Add execute bit to test-linux.sh; r=tomprince 8 | 9 | In order to call test-linux.sh with the job-script parameter, it needs 10 | to have executable permissions. 11 | 12 | Differential Revision: https://phabricator.services.mozilla.com/D22821 13 | 14 | diff --git a/taskcluster/scripts/tester/test-linux.sh b/taskcluster/scripts/tester/test-linux.sh 15 | old mode 100644 16 | new mode 100755 17 | -------------------------------------------------------------------------------- /tests/patches/7dabae5e261a.patch: -------------------------------------------------------------------------------- 1 | 2 | # HG changeset patch 3 | # User Makoto Kato 4 | # Date 1510284876 -32400 5 | # Node ID 7dabae5e261a121818cf7ce8e06fe91bd68a4913 6 | # Parent f962fb3449f44bdbe51299b8fa9b3b5a4970321b 7 | Bug 1415014 - Part 1. Add default64.png and default128.png for GTK HiDPI icons. r=dao 8 | 9 | Now, default48.png is highest resolition icon for Firfox/GTK. So we should add 10 | default64.png (from icon64.png) and default128.png (from mozicon128.png) for 11 | HiDPI. Also mozicon128.png is for Linux distribution, we should move to 12 | correct place for our GTK icons. 13 | 14 | MozReview-Commit-ID: BeLXzUcOgQu 15 | 16 | diff --git a/browser/branding/aurora/content/jar.mn b/browser/branding/aurora/content/jar.mn 17 | --- a/browser/branding/aurora/content/jar.mn 18 | +++ b/browser/branding/aurora/content/jar.mn 19 | @@ -3,15 +3,15 @@ 20 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 21 | 22 | browser.jar: 23 | % content branding %content/branding/ contentaccessible=yes 24 | content/branding/about.png 25 | content/branding/about-logo.png 26 | content/branding/about-logo@2x.png 27 | content/branding/about-wordmark.svg 28 | - content/branding/icon48.png 29 | - content/branding/icon64.png 30 | content/branding/icon16.png (../default16.png) 31 | content/branding/icon32.png (../default32.png) 32 | - content/branding/icon128.png (../mozicon128.png) 33 | + content/branding/icon48.png 34 | + content/branding/icon64.png (../default64.png) 35 | + content/branding/icon128.png (../default128.png) 36 | content/branding/identity-icons-brand.svg 37 | content/branding/aboutDialog.css 38 | diff --git a/browser/branding/aurora/mozicon128.png b/browser/branding/aurora/default128.png 39 | rename from browser/branding/aurora/mozicon128.png 40 | rename to browser/branding/aurora/default128.png 41 | diff --git a/browser/branding/aurora/content/icon64.png b/browser/branding/aurora/default64.png 42 | rename from browser/branding/aurora/content/icon64.png 43 | rename to browser/branding/aurora/default64.png 44 | diff --git a/browser/branding/branding-common.mozbuild b/browser/branding/branding-common.mozbuild 45 | --- a/browser/branding/branding-common.mozbuild 46 | +++ b/browser/branding/branding-common.mozbuild 47 | @@ -37,19 +37,21 @@ def FirefoxBranding(): 48 | 'background.png', 49 | 'disk.icns', 50 | 'document.icns', 51 | 'dsstore', 52 | 'firefox.icns', 53 | ] 54 | elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: 55 | BRANDING_FILES += [ 56 | + 'default128.png', 57 | 'default16.png', 58 | 'default32.png', 59 | 'default48.png', 60 | - 'mozicon128.png', 61 | + 'default64.png', 62 | ] 63 | - FINAL_TARGET_FILES.icons += ['mozicon128.png'] 64 | FINAL_TARGET_FILES.chrome.icons.default += [ 65 | + 'default128.png', 66 | 'default16.png', 67 | 'default32.png', 68 | 'default48.png', 69 | + 'default64.png', 70 | ] 71 | diff --git a/browser/branding/nightly/content/jar.mn b/browser/branding/nightly/content/jar.mn 72 | --- a/browser/branding/nightly/content/jar.mn 73 | +++ b/browser/branding/nightly/content/jar.mn 74 | @@ -3,15 +3,15 @@ 75 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 76 | 77 | browser.jar: 78 | % content branding %content/branding/ contentaccessible=yes 79 | content/branding/about.png 80 | content/branding/about-logo.png 81 | content/branding/about-logo@2x.png 82 | content/branding/about-wordmark.svg 83 | - content/branding/icon48.png 84 | - content/branding/icon64.png 85 | content/branding/icon16.png (../default16.png) 86 | content/branding/icon32.png (../default32.png) 87 | - content/branding/icon128.png (../mozicon128.png) 88 | + content/branding/icon48.png 89 | + content/branding/icon64.png (../default64.png) 90 | + content/branding/icon128.png (../default128.png) 91 | content/branding/identity-icons-brand.svg 92 | content/branding/aboutDialog.css 93 | diff --git a/browser/branding/nightly/mozicon128.png b/browser/branding/nightly/default128.png 94 | rename from browser/branding/nightly/mozicon128.png 95 | rename to browser/branding/nightly/default128.png 96 | diff --git a/browser/branding/nightly/content/icon64.png b/browser/branding/nightly/default64.png 97 | rename from browser/branding/nightly/content/icon64.png 98 | rename to browser/branding/nightly/default64.png 99 | diff --git a/browser/branding/official/content/jar.mn b/browser/branding/official/content/jar.mn 100 | --- a/browser/branding/official/content/jar.mn 101 | +++ b/browser/branding/official/content/jar.mn 102 | @@ -3,15 +3,15 @@ 103 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. 104 | 105 | browser.jar: 106 | % content branding %content/branding/ contentaccessible=yes 107 | content/branding/about.png 108 | content/branding/about-logo.png 109 | content/branding/about-logo@2x.png 110 | content/branding/about-wordmark.svg 111 | - content/branding/icon48.png 112 | - content/branding/icon64.png 113 | content/branding/icon16.png (../default16.png) 114 | content/branding/icon32.png (../default32.png) 115 | + content/branding/icon48.png 116 | + content/branding/icon64.png (../default64.png) 117 | content/branding/icon128.png (../mozicon128.png) 118 | content/branding/identity-icons-brand.svg 119 | content/branding/aboutDialog.css 120 | diff --git a/browser/branding/official/mozicon128.png b/browser/branding/official/default128.png 121 | rename from browser/branding/official/mozicon128.png 122 | rename to browser/branding/official/default128.png 123 | diff --git a/browser/branding/official/content/icon64.png b/browser/branding/official/default64.png 124 | rename from browser/branding/official/content/icon64.png 125 | rename to browser/branding/official/default64.png 126 | diff --git a/browser/branding/unofficial/content/jar.mn b/browser/branding/unofficial/content/jar.mn 127 | --- a/browser/branding/unofficial/content/jar.mn 128 | +++ b/browser/branding/unofficial/content/jar.mn 129 | @@ -4,15 +4,15 @@ 130 | 131 | browser.jar: 132 | % content branding %content/branding/ contentaccessible=yes 133 | content/branding/about.png 134 | content/branding/about-background.png 135 | content/branding/about-logo.png 136 | content/branding/about-logo@2x.png 137 | content/branding/about-wordmark.svg 138 | - content/branding/icon48.png 139 | - content/branding/icon64.png 140 | content/branding/icon16.png (../default16.png) 141 | content/branding/icon32.png (../default32.png) 142 | - content/branding/icon128.png (../mozicon128.png) 143 | + content/branding/icon48.png 144 | + content/branding/icon64.png (../default64.png) 145 | + content/branding/icon128.png (../default128.png) 146 | content/branding/identity-icons-brand.svg 147 | content/branding/aboutDialog.css 148 | diff --git a/browser/branding/unofficial/mozicon128.png b/browser/branding/unofficial/default128.png 149 | rename from browser/branding/unofficial/mozicon128.png 150 | rename to browser/branding/unofficial/default128.png 151 | diff --git a/browser/branding/unofficial/content/icon64.png b/browser/branding/unofficial/default64.png 152 | rename from browser/branding/unofficial/content/icon64.png 153 | rename to browser/branding/unofficial/default64.png 154 | diff --git a/browser/installer/allowed-dupes.mn b/browser/installer/allowed-dupes.mn 155 | --- a/browser/installer/allowed-dupes.mn 156 | +++ b/browser/installer/allowed-dupes.mn 157 | @@ -71,16 +71,18 @@ modules/devtools/Console.jsm 158 | modules/devtools/Loader.jsm 159 | modules/devtools/shared/Console.jsm 160 | modules/devtools/shared/Loader.jsm 161 | browser/modules/devtools/client/framework/gDevTools.jsm 162 | browser/modules/devtools/gDevTools.jsm 163 | browser/chrome/icons/default/default16.png 164 | browser/chrome/icons/default/default32.png 165 | browser/chrome/icons/default/default48.png 166 | +browser/chrome/icons/default/default64.png 167 | +browser/chrome/icons/default/default128.png 168 | browser/chrome/pdfjs/content/web/images/findbarButton-next-rtl.png 169 | browser/chrome/pdfjs/content/web/images/findbarButton-next-rtl@2x.png 170 | browser/chrome/pdfjs/content/web/images/findbarButton-next.png 171 | browser/chrome/pdfjs/content/web/images/findbarButton-next@2x.png 172 | browser/chrome/pdfjs/content/web/images/findbarButton-previous-rtl.png 173 | browser/chrome/pdfjs/content/web/images/findbarButton-previous-rtl@2x.png 174 | browser/chrome/pdfjs/content/web/images/findbarButton-previous.png 175 | browser/chrome/pdfjs/content/web/images/findbarButton-previous@2x.png 176 | @@ -100,17 +102,16 @@ browser/features/flyweb@mozilla.org/chro 177 | browser/features/flyweb@mozilla.org/chrome/skin/osx/icon-32-anchored.png 178 | browser/features/flyweb@mozilla.org/chrome/skin/osx/icon-64-anchored.png 179 | browser/features/flyweb@mozilla.org/chrome/skin/windows/flyweb.css 180 | browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-16.png 181 | browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-32-anchored.png 182 | browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-32.png 183 | browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-64-anchored.png 184 | browser/features/flyweb@mozilla.org/chrome/skin/windows/icon-64.png 185 | -browser/icons/mozicon128.png 186 | chrome.manifest 187 | chrome/toolkit/skin/classic/global/autocomplete.css 188 | chrome/toolkit/skin/classic/global/button.css 189 | chrome/toolkit/skin/classic/global/checkbox.css 190 | chrome/toolkit/skin/classic/global/dialog.css 191 | chrome/toolkit/skin/classic/global/dropmarker.css 192 | chrome/toolkit/skin/classic/global/global.css 193 | chrome/toolkit/skin/classic/global/groupbox.css 194 | diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in 195 | --- a/browser/installer/package-manifest.in 196 | +++ b/browser/installer/package-manifest.in 197 | @@ -610,16 +610,18 @@ 198 | @RESPATH@/chrome/toolkit@JAREXT@ 199 | @RESPATH@/chrome/toolkit.manifest 200 | @RESPATH@/chrome/recording.manifest 201 | @RESPATH@/chrome/recording/* 202 | #ifdef MOZ_GTK 203 | @RESPATH@/browser/chrome/icons/default/default16.png 204 | @RESPATH@/browser/chrome/icons/default/default32.png 205 | @RESPATH@/browser/chrome/icons/default/default48.png 206 | +@RESPATH@/browser/chrome/icons/default/default64.png 207 | +@RESPATH@/browser/chrome/icons/default/default128.png 208 | #endif 209 | @RESPATH@/browser/features/* 210 | 211 | ; [Webide Files] 212 | @RESPATH@/browser/chrome/webide@JAREXT@ 213 | @RESPATH@/browser/chrome/webide.manifest 214 | @RESPATH@/browser/@PREF_DIR@/webide-prefs.js 215 | 216 | @@ -632,18 +634,16 @@ 217 | @RESPATH@/browser/chrome/devtools@JAREXT@ 218 | @RESPATH@/browser/chrome/devtools.manifest 219 | @RESPATH@/browser/@PREF_DIR@/devtools.js 220 | @RESPATH@/browser/@PREF_DIR@/debugger.js 221 | 222 | ; shell icons 223 | #ifdef XP_UNIX 224 | #ifndef XP_MACOSX 225 | -; shell icons 226 | -@RESPATH@/browser/icons/*.png 227 | #ifdef MOZ_UPDATER 228 | ; updater icon 229 | @RESPATH@/icons/updater.png 230 | #endif 231 | #endif 232 | #endif 233 | 234 | ; [Default Preferences] 235 | 236 | -------------------------------------------------------------------------------- /tests/patches/7e60ad275b73.patch: -------------------------------------------------------------------------------- 1 | 2 | # HG changeset patch 3 | # User sotaro 4 | # Date 1511524704 -32400 5 | # Node ID 7e60ad275b73df53b06eebe2d71b788016e45cd6 6 | # Parent 45e4387bc585d3187d5fd945c2115e75195b0bfa 7 | Bug 1391159 - Handle WebRender ProgramBinary usage r=nical 8 | 9 | diff --git a/gfx/config/gfxVars.h b/gfx/config/gfxVars.h 10 | --- a/gfx/config/gfxVars.h 11 | +++ b/gfx/config/gfxVars.h 12 | @@ -31,16 +31,17 @@ class gfxVarReceiver; 13 | _(OffscreenFormat, gfxImageFormat, mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32) \ 14 | _(RequiresAcceleratedGLContextForCompositorOGL, bool, false) \ 15 | _(CanUseHardwareVideoDecoding, bool, false) \ 16 | _(PDMWMFDisableD3D11Dlls, nsCString, nsCString()) \ 17 | _(PDMWMFDisableD3D9Dlls, nsCString, nsCString()) \ 18 | _(DXInterop2Blocked, bool, false) \ 19 | _(UseWebRender, bool, false) \ 20 | _(UseWebRenderANGLE, bool, false) \ 21 | + _(UseWebRenderProgramBinary, bool, false) \ 22 | _(WebRenderDebugFlags, int32_t, 0) \ 23 | _(ScreenDepth, int32_t, 0) \ 24 | _(GREDirectory, nsCString, nsCString()) \ 25 | _(UseOMTP, bool, false) \ 26 | _(AllowD3D11KeyedMutex, bool, false) \ 27 | 28 | /* Add new entries above this line. */ 29 | 30 | diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp 31 | --- a/gfx/thebes/gfxPlatform.cpp 32 | +++ b/gfx/thebes/gfxPlatform.cpp 33 | @@ -2548,16 +2548,20 @@ gfxPlatform::InitWebRenderConfig() 34 | "ANGLE is disabled", 35 | NS_LITERAL_CSTRING("FEATURE_FAILURE_ANGLE_DISABLED")); 36 | } else { 37 | gfxVars::SetUseWebRenderANGLE(gfxConfig::IsEnabled(Feature::WEBRENDER)); 38 | } 39 | } 40 | #endif 41 | 42 | + if (Preferences::GetBool("gfx.webrender.program-binary", false)) { 43 | + gfx::gfxVars::SetUseWebRenderProgramBinary(gfxConfig::IsEnabled(Feature::WEBRENDER)); 44 | + } 45 | + 46 | #ifdef MOZ_WIDGET_ANDROID 47 | featureWebRender.ForceDisable( 48 | FeatureStatus::Unavailable, 49 | "WebRender not ready for use on Android", 50 | NS_LITERAL_CSTRING("FEATURE_FAILURE_ANDROID")); 51 | #endif 52 | 53 | // gfxFeature is not usable in the GPU process, so we use gfxVars to transmit this feature 54 | diff --git a/gfx/webrender_bindings/RenderThread.cpp b/gfx/webrender_bindings/RenderThread.cpp 55 | --- a/gfx/webrender_bindings/RenderThread.cpp 56 | +++ b/gfx/webrender_bindings/RenderThread.cpp 57 | @@ -417,26 +417,47 @@ RenderThread::GetRenderTexture(wr::WrExt 58 | { 59 | MOZ_ASSERT(IsInRenderThread()); 60 | 61 | MutexAutoLock lock(mRenderTextureMapLock); 62 | MOZ_ASSERT(mRenderTextures.GetWeak(aExternalImageId.mHandle)); 63 | return mRenderTextures.GetWeak(aExternalImageId.mHandle); 64 | } 65 | 66 | +WebRenderProgramCache* 67 | +RenderThread::ProgramCache() 68 | +{ 69 | + MOZ_ASSERT(IsInRenderThread()); 70 | + 71 | + if (!mProgramCache) { 72 | + mProgramCache = MakeUnique(); 73 | + } 74 | + return mProgramCache.get(); 75 | +} 76 | + 77 | WebRenderThreadPool::WebRenderThreadPool() 78 | { 79 | mThreadPool = wr_thread_pool_new(); 80 | } 81 | 82 | WebRenderThreadPool::~WebRenderThreadPool() 83 | { 84 | wr_thread_pool_delete(mThreadPool); 85 | } 86 | 87 | +WebRenderProgramCache::WebRenderProgramCache() 88 | +{ 89 | + mProgramCache = wr_program_cache_new(); 90 | +} 91 | + 92 | +WebRenderProgramCache::~WebRenderProgramCache() 93 | +{ 94 | + wr_program_cache_delete(mProgramCache); 95 | +} 96 | + 97 | } // namespace wr 98 | } // namespace mozilla 99 | 100 | extern "C" { 101 | 102 | void wr_notifier_new_frame_ready(mozilla::wr::WrWindowId aWindowId) 103 | { 104 | mozilla::wr::RenderThread::Get()->IncRenderingFrameCount(aWindowId); 105 | diff --git a/gfx/webrender_bindings/RenderThread.h b/gfx/webrender_bindings/RenderThread.h 106 | --- a/gfx/webrender_bindings/RenderThread.h 107 | +++ b/gfx/webrender_bindings/RenderThread.h 108 | @@ -35,16 +35,27 @@ public: 109 | ~WebRenderThreadPool(); 110 | 111 | wr::WrThreadPool* Raw() { return mThreadPool; } 112 | 113 | protected: 114 | wr::WrThreadPool* mThreadPool; 115 | }; 116 | 117 | +class WebRenderProgramCache { 118 | +public: 119 | + WebRenderProgramCache(); 120 | + 121 | + ~WebRenderProgramCache(); 122 | + 123 | + wr::WrProgramCache* Raw() { return mProgramCache; } 124 | + 125 | +protected: 126 | + wr::WrProgramCache* mProgramCache; 127 | +}; 128 | 129 | /// Base class for an event that can be scheduled to run on the render thread. 130 | /// 131 | /// The event can be passed through the same channels as regular WebRender messages 132 | /// to preserve ordering. 133 | class RendererEvent 134 | { 135 | public: 136 | @@ -138,27 +149,31 @@ public: 137 | /// Can be called from any thread. 138 | void IncRenderingFrameCount(wr::WindowId aWindowId); 139 | /// Can be called from any thread. 140 | void DecPendingFrameCount(wr::WindowId aWindowId); 141 | 142 | /// Can be called from any thread. 143 | WebRenderThreadPool& ThreadPool() { return mThreadPool; } 144 | 145 | + /// Can only be called from the render thread. 146 | + WebRenderProgramCache* ProgramCache(); 147 | + 148 | private: 149 | explicit RenderThread(base::Thread* aThread); 150 | 151 | void DeferredRenderTextureHostDestroy(RefPtr aTexture); 152 | void ShutDownTask(layers::SynchronousTask* aTask); 153 | 154 | ~RenderThread(); 155 | 156 | base::Thread* const mThread; 157 | 158 | WebRenderThreadPool mThreadPool; 159 | + UniquePtr mProgramCache; 160 | 161 | std::map> mRenderers; 162 | 163 | struct WindowInfo { 164 | bool mIsDestroyed = false; 165 | int64_t mPendingCount = 0; 166 | int64_t mRenderingCount = 0; 167 | }; 168 | diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp 169 | --- a/gfx/webrender_bindings/WebRenderAPI.cpp 170 | +++ b/gfx/webrender_bindings/WebRenderAPI.cpp 171 | @@ -85,16 +85,19 @@ public: 172 | Move(gl), 173 | Move(mCompositorWidget), 174 | aWindowId, 175 | wrRenderer, 176 | mBridge); 177 | if (wrRenderer && renderer) { 178 | wr::WrExternalImageHandler handler = renderer->GetExternalImageHandler(); 179 | wr_renderer_set_external_image_handler(wrRenderer, &handler); 180 | + if (gfx::gfxVars::UseWebRenderProgramBinary()) { 181 | + wr_renderer_update_program_cache(wrRenderer, aRenderThread.ProgramCache()->Raw()); 182 | + } 183 | } 184 | 185 | if (renderer) { 186 | layers::SyncObjectHost* syncObj = renderer->GetSyncObject(); 187 | if (syncObj) { 188 | *mSyncHandle = syncObj->GetSyncHandle(); 189 | } 190 | } 191 | diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs 192 | --- a/gfx/webrender_bindings/src/bindings.rs 193 | +++ b/gfx/webrender_bindings/src/bindings.rs 194 | @@ -1,21 +1,23 @@ 195 | use std::ffi::{CStr, CString}; 196 | use std::{mem, slice}; 197 | use std::path::PathBuf; 198 | use std::ptr; 199 | +use std::rc::Rc; 200 | use std::sync::Arc; 201 | use std::os::raw::{c_void, c_char, c_float}; 202 | use gleam::gl; 203 | 204 | use webrender::api::*; 205 | use webrender::{ReadPixelsFormat, Renderer, RendererOptions, ThreadListener}; 206 | use webrender::{ExternalImage, ExternalImageHandler, ExternalImageSource}; 207 | use webrender::DebugFlags; 208 | use webrender::{ApiRecordingReceiver, BinaryRecorder}; 209 | +use webrender::ProgramCache; 210 | use thread_profiler::register_thread_with_profiler; 211 | use moz2d_renderer::Moz2dImageRenderer; 212 | use app_units::Au; 213 | use rayon; 214 | use euclid::SideOffsets2D; 215 | use log::{set_logger, shutdown_logger, LogLevelFilter, Log, LogLevel, LogMetadata, LogRecord}; 216 | 217 | #[cfg(target_os = "windows")] 218 | @@ -655,16 +657,36 @@ pub unsafe extern "C" fn wr_thread_pool_ 219 | } 220 | 221 | /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC 222 | #[no_mangle] 223 | pub unsafe extern "C" fn wr_thread_pool_delete(thread_pool: *mut WrThreadPool) { 224 | Box::from_raw(thread_pool); 225 | } 226 | 227 | +pub struct WrProgramCache(Rc); 228 | + 229 | +#[no_mangle] 230 | +pub unsafe extern "C" fn wr_program_cache_new() -> *mut WrProgramCache { 231 | + let program_cache = ProgramCache::new(); 232 | + Box::into_raw(Box::new(WrProgramCache(program_cache))) 233 | +} 234 | + 235 | +/// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC 236 | +#[no_mangle] 237 | +pub unsafe extern "C" fn wr_program_cache_delete(program_cache: *mut WrProgramCache) { 238 | + Rc::from_raw(program_cache); 239 | +} 240 | + 241 | +#[no_mangle] 242 | +pub extern "C" fn wr_renderer_update_program_cache(renderer: &mut Renderer, program_cache: &mut WrProgramCache) { 243 | + let program_cache = Rc::clone(&program_cache.0); 244 | + renderer.update_program_cache(program_cache); 245 | +} 246 | + 247 | // Call MakeCurrent before this. 248 | #[no_mangle] 249 | pub extern "C" fn wr_window_new(window_id: WrWindowId, 250 | window_width: u32, 251 | window_height: u32, 252 | gl_context: *mut c_void, 253 | thread_pool: *mut WrThreadPool, 254 | out_handle: &mut *mut DocumentHandle, 255 | diff --git a/gfx/webrender_bindings/webrender_ffi_generated.h b/gfx/webrender_bindings/webrender_ffi_generated.h 256 | --- a/gfx/webrender_bindings/webrender_ffi_generated.h 257 | +++ b/gfx/webrender_bindings/webrender_ffi_generated.h 258 | @@ -245,16 +245,18 @@ struct DocumentHandle; 259 | // RenderBackend. 260 | struct Renderer; 261 | 262 | // The resource updates for a given transaction (they must be applied in the same frame). 263 | struct ResourceUpdates; 264 | 265 | struct Vec_u8; 266 | 267 | +struct WrProgramCache; 268 | + 269 | struct WrRenderedEpochs; 270 | 271 | struct WrState; 272 | 273 | struct WrThreadPool; 274 | 275 | struct IdNamespace { 276 | uint32_t mHandle; 277 | @@ -1405,16 +1407,24 @@ extern void wr_notifier_external_event(W 278 | size_t aRawEvent); 279 | 280 | extern void wr_notifier_new_frame_ready(WrWindowId aWindowId); 281 | 282 | extern void wr_notifier_new_scroll_frame_ready(WrWindowId aWindowId, 283 | bool aCompositeNeeded); 284 | 285 | WR_INLINE 286 | +void wr_program_cache_delete(WrProgramCache *aProgramCache) 287 | +WR_DESTRUCTOR_SAFE_FUNC; 288 | + 289 | +WR_INLINE 290 | +WrProgramCache *wr_program_cache_new() 291 | +WR_FUNC; 292 | + 293 | +WR_INLINE 294 | void wr_rendered_epochs_delete(WrRenderedEpochs *aPipelineEpochs) 295 | WR_DESTRUCTOR_SAFE_FUNC; 296 | 297 | WR_INLINE 298 | bool wr_rendered_epochs_next(WrRenderedEpochs *aPipelineEpochs, 299 | WrPipelineId *aOutPipeline, 300 | WrEpoch *aOutEpoch) 301 | WR_FUNC; 302 | @@ -1461,16 +1471,21 @@ void wr_renderer_set_external_image_hand 303 | WrExternalImageHandler *aExternalImageHandler) 304 | WR_FUNC; 305 | 306 | WR_INLINE 307 | void wr_renderer_update(Renderer *aRenderer) 308 | WR_FUNC; 309 | 310 | WR_INLINE 311 | +void wr_renderer_update_program_cache(Renderer *aRenderer, 312 | + WrProgramCache *aProgramCache) 313 | +WR_FUNC; 314 | + 315 | +WR_INLINE 316 | void wr_resource_updates_add_blob_image(ResourceUpdates *aResources, 317 | WrImageKey aImageKey, 318 | const WrImageDescriptor *aDescriptor, 319 | WrVecU8 *aBytes) 320 | WR_FUNC; 321 | 322 | WR_INLINE 323 | void wr_resource_updates_add_external_image(ResourceUpdates *aResources, 324 | diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js 325 | --- a/modules/libpref/init/all.js 326 | +++ b/modules/libpref/init/all.js 327 | @@ -855,16 +855,17 @@ pref("gfx.ycbcr.accurate-conversion", fa 328 | 329 | #ifdef MOZ_ENABLE_WEBRENDER 330 | pref("gfx.webrender.enabled", true); 331 | #else 332 | pref("gfx.webrender.enabled", false); 333 | #endif 334 | #ifdef XP_WIN 335 | pref("gfx.webrender.force-angle", true); 336 | +pref("gfx.webrender.program-binary", true); 337 | #endif 338 | 339 | pref("gfx.webrender.highlight-painted-layers", false); 340 | pref("gfx.webrender.blob-images", false); 341 | 342 | // WebRender debugging utilities. 343 | pref("gfx.webrender.debug.texture-cache", false); 344 | pref("gfx.webrender.debug.render-targets", false); 345 | 346 | -------------------------------------------------------------------------------- /tests/patches/D174915.patch: -------------------------------------------------------------------------------- 1 | diff --git a/toolkit/content/tests/widgets/mochitest.ini b/toolkit/content/tests/widgets/mochitest.ini 2 | --- a/toolkit/content/tests/widgets/mochitest.ini 3 | +++ b/toolkit/content/tests/widgets/mochitest.ini 4 | @@ -46,10 +46,11 @@ 5 | [test_videocontrols_audio_direction.html] 6 | skip-if = xorigin # Rendering of reftest videocontrols_direction-2a.html should not be different to the reference, fails/passes inconsistently 7 | [test_videocontrols_jsdisabled.html] 8 | skip-if = toolkit == 'android' # bug 1272646 9 | [test_videocontrols_scrubber_position.html] 10 | +[test_videocontrols_scrubber_position_nopreload.html] 11 | [test_videocontrols_standalone.html] 12 | skip-if = toolkit == 'android' # bug 1075573 13 | [test_videocontrols_video_direction.html] 14 | skip-if = 15 | os == 'win' 16 | diff --git a/toolkit/content/tests/widgets/test_videocontrols_scrubber_position.html b/toolkit/content/tests/widgets/test_videocontrols_scrubber_position.html 17 | --- a/toolkit/content/tests/widgets/test_videocontrols_scrubber_position.html 18 | +++ b/toolkit/content/tests/widgets/test_videocontrols_scrubber_position.html 19 | @@ -1,6 +1,8 @@ 20 | 21 | + 23 | 24 | 25 | Video controls test - Initial scrubber position 26 | 27 | 28 | diff --git a/toolkit/content/tests/widgets/test_videocontrols_scrubber_position.html b/toolkit/content/tests/widgets/test_videocontrols_scrubber_position_nopreload.html 29 | copy from toolkit/content/tests/widgets/test_videocontrols_scrubber_position.html 30 | copy to toolkit/content/tests/widgets/test_videocontrols_scrubber_position_nopreload.html 31 | --- a/toolkit/content/tests/widgets/test_videocontrols_scrubber_position.html 32 | +++ b/toolkit/content/tests/widgets/test_videocontrols_scrubber_position_nopreload.html 33 | @@ -1,45 +1,34 @@ 34 | 35 | + 37 | 38 | 39 | - Video controls test - Initial scrubber position 40 | + Video controls test - Initial scrubber position when preload is turned off 41 | 42 | 43 | 44 | 45 | 46 | 47 |

48 | 49 |
50 | - 51 | + 52 |
53 | 54 |
55 | 56 |
 57 |