Matt Godbolt | f68198a | 2020-09-26 17:50:40 -0500 | [diff] [blame] | 1 | // Copyright (c) 2017, Compiler Explorer Authors |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 2 | // All rights reserved. |
| 3 | // |
| 4 | // Redistribution and use in source and binary forms, with or without |
| 5 | // modification, are permitted provided that the following conditions are met: |
| 6 | // |
| 7 | // * Redistributions of source code must retain the above copyright notice, |
| 8 | // this list of conditions and the following disclaimer. |
| 9 | // * Redistributions in binary form must reproduce the above copyright |
| 10 | // notice, this list of conditions and the following disclaimer in the |
| 11 | // documentation and/or other materials provided with the distribution. |
| 12 | // |
| 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 16 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| 17 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 18 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 19 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 20 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 21 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 22 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 23 | // POSSIBILITY OF SUCH DAMAGE. |
| 24 | |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 25 | import bodyParser from 'body-parser'; |
| 26 | import express from 'express'; |
| 27 | import _ from 'underscore'; |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 28 | |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 29 | import {ClientStateNormalizer} from '../clientstate-normalizer'; |
| 30 | import {logger} from '../logger'; |
| 31 | import {getShortenerTypeByKey} from '../shortener'; |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 32 | import * as utils from '../utils'; |
| 33 | |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 34 | import {withAssemblyDocumentationProviders} from './assembly-documentation'; |
| 35 | import {FormattingHandler} from './formatting'; |
Jeremy Rifkin | 4c2fe0a | 2022-06-09 16:52:45 -0400 | [diff] [blame] | 36 | import {getSiteTemplates} from './site-templates'; |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 37 | |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 38 | function methodNotAllowed(req, res) { |
| 39 | res.send('Method Not Allowed'); |
| 40 | return res.status(405).end(); |
| 41 | } |
| 42 | |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 43 | export class ApiHandler { |
Matt Godbolt | 17b2bb8 | 2021-02-15 12:52:46 -0600 | [diff] [blame] | 44 | constructor(compileHandler, ceProps, storageHandler, urlShortenService) { |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 45 | this.compilers = []; |
partouf | 2ef40c9 | 2018-01-01 22:30:26 +0100 | [diff] [blame] | 46 | this.languages = []; |
RabsRincon | 8429842 | 2018-04-08 03:05:38 +0200 | [diff] [blame] | 47 | this.usedLangIds = []; |
Partouf | 8bb5e7d | 2018-10-15 02:32:31 +0200 | [diff] [blame] | 48 | this.options = null; |
Partouf | 652fd6b | 2018-10-01 20:03:51 +0200 | [diff] [blame] | 49 | this.storageHandler = storageHandler; |
Mats Larsen | d7c4eec | 2021-12-07 10:43:08 +0000 | [diff] [blame] | 50 | /** @type {e.Router} */ |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 51 | this.handle = express.Router(); |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 52 | const cacheHeader = `public, max-age=${ceProps('apiMaxAgeSecs', 24 * 60 * 60)}`; |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 53 | this.handle.use((req, res, next) => { |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 54 | res.header({ |
| 55 | 'Access-Control-Allow-Origin': '*', |
| 56 | 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept', |
| 57 | 'Cache-Control': cacheHeader, |
| 58 | }); |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 59 | next(); |
| 60 | }); |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 61 | this.handle.route('/compilers').get(this.handleCompilers.bind(this)).all(methodNotAllowed); |
| 62 | |
| 63 | this.handle.route('/compilers/:language').get(this.handleCompilers.bind(this)).all(methodNotAllowed); |
| 64 | |
| 65 | this.handle.route('/languages').get(this.handleLanguages.bind(this)).all(methodNotAllowed); |
| 66 | |
| 67 | this.handle.route('/libraries/:language').get(this.handleLangLibraries.bind(this)).all(methodNotAllowed); |
| 68 | |
| 69 | this.handle.route('/libraries').get(this.handleAllLibraries.bind(this)).all(methodNotAllowed); |
RabsRincon | b8c8c65 | 2018-04-20 22:07:40 +0200 | [diff] [blame] | 70 | |
Mats Larsen | d7c4eec | 2021-12-07 10:43:08 +0000 | [diff] [blame] | 71 | // Binding for assembly documentation |
Mats Larsen | 9b890b1 | 2022-01-31 14:05:21 +0100 | [diff] [blame] | 72 | withAssemblyDocumentationProviders(this.handle); |
Matt Godbolt | 273017c | 2021-03-14 12:39:55 -0500 | [diff] [blame] | 73 | // Legacy binding for old clients. |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 74 | this.handle |
| 75 | .route('/asm/:opcode') |
| 76 | .get((req, res) => res.redirect(`amd64/${req.params.opcode}`)) |
| 77 | .all(methodNotAllowed); |
Partouf | 865d217 | 2018-10-26 13:33:42 +0200 | [diff] [blame] | 78 | |
Patrick Quist | 0f01b99 | 2020-09-05 12:22:44 +0200 | [diff] [blame] | 79 | const maxUploadSize = ceProps('maxUploadSize', '1mb'); |
| 80 | const textParser = bodyParser.text({limit: ceProps('bodyParserLimit', maxUploadSize), type: () => true}); |
| 81 | |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 82 | this.handle |
| 83 | .route('/compiler/:compiler/compile') |
| 84 | .post(textParser, compileHandler.handle.bind(compileHandler)) |
| 85 | .all(methodNotAllowed); |
| 86 | this.handle |
| 87 | .route('/compiler/:compiler/cmake') |
| 88 | .post(compileHandler.handleCmake.bind(compileHandler)) |
| 89 | .all(methodNotAllowed); |
Partouf | 69a43f7 | 2019-08-13 22:15:53 +0200 | [diff] [blame] | 90 | |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 91 | this.handle |
| 92 | .route('/popularArguments/:compiler') |
| 93 | .post(compileHandler.handlePopularArguments.bind(compileHandler)) |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 94 | .get(compileHandler.handlePopularArguments.bind(compileHandler)) |
| 95 | .all(methodNotAllowed); |
| 96 | this.handle |
| 97 | .route('/optimizationArguments/:compiler') |
Rubén Rincón Blanco | 16dca9d | 2022-08-25 21:51:10 +0200 | [diff] [blame] | 98 | .post(compileHandler.handleOptimizationArguments.bind(compileHandler)) |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 99 | .get(compileHandler.handleOptimizationArguments.bind(compileHandler)) |
| 100 | .all(methodNotAllowed); |
RabsRincon | b8c8c65 | 2018-04-20 22:07:40 +0200 | [diff] [blame] | 101 | |
Mats Larsen | 53b9e0a | 2021-08-25 00:46:38 +0100 | [diff] [blame] | 102 | const formatHandler = new FormattingHandler(ceProps); |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 103 | this.handle |
| 104 | .route('/format/:tool') |
| 105 | .post((req, res) => formatHandler.handle(req, res)) |
| 106 | .all(methodNotAllowed); |
| 107 | this.handle |
| 108 | .route('/formats') |
| 109 | .get((req, res) => { |
| 110 | const all = Object.values(formatHandler.formatters).map(formatter => formatter.formatterInfo); |
| 111 | res.send(all); |
| 112 | }) |
| 113 | .all(methodNotAllowed); |
Jeremy Rifkin | 4c2fe0a | 2022-06-09 16:52:45 -0400 | [diff] [blame] | 114 | this.handle |
| 115 | .route('/siteTemplates') |
| 116 | .get((req, res) => { |
| 117 | res.send(getSiteTemplates()); |
| 118 | }) |
| 119 | .all(methodNotAllowed); |
Partouf | 652fd6b | 2018-10-01 20:03:51 +0200 | [diff] [blame] | 120 | |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 121 | this.handle.route('/shortlinkinfo/:id').get(this.shortlinkInfoHandler.bind(this)).all(methodNotAllowed); |
Matt Godbolt | 17b2bb8 | 2021-02-15 12:52:46 -0600 | [diff] [blame] | 122 | |
| 123 | const shortenerType = getShortenerTypeByKey(urlShortenService); |
| 124 | this.shortener = new shortenerType(storageHandler); |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 125 | this.handle.route('/shortener').post(this.shortener.handle.bind(this.shortener)).all(methodNotAllowed); |
RabsRincon | 16ff1a8 | 2021-08-13 05:31:40 +0200 | [diff] [blame] | 126 | |
| 127 | this.release = { |
| 128 | gitReleaseName: '', |
| 129 | releaseBuildNumber: '', |
| 130 | }; |
Rubén Rincón Blanco | f19bebc | 2022-05-06 18:56:33 +0200 | [diff] [blame] | 131 | this.handle.route('/version').get(this.handleReleaseName.bind(this)).all(methodNotAllowed); |
| 132 | this.handle.route('/releaseBuild').get(this.handleReleaseBuild.bind(this)).all(methodNotAllowed); |
Partouf | 652fd6b | 2018-10-01 20:03:51 +0200 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | shortlinkInfoHandler(req, res, next) { |
| 136 | const id = req.params.id; |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 137 | this.storageHandler |
| 138 | .expandId(id) |
Partouf | 652fd6b | 2018-10-01 20:03:51 +0200 | [diff] [blame] | 139 | .then(result => { |
| 140 | const config = JSON.parse(result.config); |
| 141 | |
| 142 | if (config.content) { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 143 | const normalizer = new ClientStateNormalizer(); |
Partouf | 652fd6b | 2018-10-01 20:03:51 +0200 | [diff] [blame] | 144 | normalizer.fromGoldenLayout(config); |
| 145 | |
Matt Godbolt | 4cf5792 | 2020-01-12 11:18:39 -0600 | [diff] [blame] | 146 | res.send(normalizer.normalized); |
Partouf | 652fd6b | 2018-10-01 20:03:51 +0200 | [diff] [blame] | 147 | } else { |
Matt Godbolt | 4cf5792 | 2020-01-12 11:18:39 -0600 | [diff] [blame] | 148 | res.send(config); |
Partouf | 652fd6b | 2018-10-01 20:03:51 +0200 | [diff] [blame] | 149 | } |
| 150 | }) |
| 151 | .catch(err => { |
| 152 | logger.warn(`Exception thrown when expanding ${id}: `, err); |
| 153 | next({ |
| 154 | statusCode: 404, |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 155 | message: `ID "${id}" could not be found`, |
Partouf | 652fd6b | 2018-10-01 20:03:51 +0200 | [diff] [blame] | 156 | }); |
| 157 | }); |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 158 | } |
| 159 | |
partouf | 2ef40c9 | 2018-01-01 22:30:26 +0100 | [diff] [blame] | 160 | handleLanguages(req, res) { |
Partouf | 8bb5e7d | 2018-10-15 02:32:31 +0200 | [diff] [blame] | 161 | const availableLanguages = this.usedLangIds.map(val => { |
| 162 | let lang = this.languages[val]; |
| 163 | let newLangObj = Object.assign({}, lang); |
| 164 | if (this.options) { |
| 165 | newLangObj.defaultCompiler = this.options.options.defaultCompiler[lang.id]; |
| 166 | } |
| 167 | return newLangObj; |
| 168 | }); |
partouf | 2ef40c9 | 2018-01-01 22:30:26 +0100 | [diff] [blame] | 169 | |
Matt Godbolt | 4cf5792 | 2020-01-12 11:18:39 -0600 | [diff] [blame] | 170 | this.outputList(availableLanguages, 'Id', req, res); |
| 171 | } |
| 172 | |
Patrick Quist | ab2f8e2 | 2020-09-02 21:36:02 +0200 | [diff] [blame] | 173 | filterCompilerProperties(list, selectedFields) { |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 174 | return _.map(list, compiler => { |
Partouf | 6b6a9ef | 2020-09-03 00:03:25 +0200 | [diff] [blame] | 175 | return _.pick(compiler, selectedFields); |
Patrick Quist | ab2f8e2 | 2020-09-02 21:36:02 +0200 | [diff] [blame] | 176 | }); |
| 177 | } |
| 178 | |
Matt Godbolt | 4cf5792 | 2020-01-12 11:18:39 -0600 | [diff] [blame] | 179 | outputList(list, title, req, res) { |
partouf | 2ef40c9 | 2018-01-01 22:30:26 +0100 | [diff] [blame] | 180 | if (req.accepts(['text', 'json']) === 'json') { |
Patrick Quist | ab2f8e2 | 2020-09-02 21:36:02 +0200 | [diff] [blame] | 181 | if (req.query.fields === 'all') { |
| 182 | res.send(list); |
| 183 | } else { |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 184 | const defaultfields = [ |
| 185 | 'id', |
| 186 | 'name', |
| 187 | 'lang', |
| 188 | 'compilerType', |
| 189 | 'semver', |
| 190 | 'extensions', |
| 191 | 'monaco', |
| 192 | 'instructionSet', |
| 193 | ]; |
Patrick Quist | ab2f8e2 | 2020-09-02 21:36:02 +0200 | [diff] [blame] | 194 | if (req.query.fields) { |
| 195 | const filteredList = this.filterCompilerProperties(list, req.query.fields.split(',')); |
| 196 | res.send(filteredList); |
| 197 | } else { |
| 198 | const filteredList = this.filterCompilerProperties(list, defaultfields); |
| 199 | res.send(filteredList); |
| 200 | } |
| 201 | } |
Matt Godbolt | 4cf5792 | 2020-01-12 11:18:39 -0600 | [diff] [blame] | 202 | return; |
Partouf | 8bb5e7d | 2018-10-15 02:32:31 +0200 | [diff] [blame] | 203 | } |
Patrick Quist | ab2f8e2 | 2020-09-02 21:36:02 +0200 | [diff] [blame] | 204 | |
Matt Godbolt | 4cf5792 | 2020-01-12 11:18:39 -0600 | [diff] [blame] | 205 | const maxLength = _.max(_.pluck(_.pluck(list, 'id').concat([title]), 'length')); |
| 206 | res.set('Content-Type', 'text/plain'); |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 207 | res.send( |
| 208 | utils.padRight(title, maxLength) + |
| 209 | ' | Name\n' + |
RabsRincon | 40fe769 | 2022-04-26 05:26:48 +0200 | [diff] [blame] | 210 | list.map(lang => utils.padRight(lang.id, maxLength) + ' | ' + lang.name).join('\n'), |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 211 | ); |
Partouf | 8bb5e7d | 2018-10-15 02:32:31 +0200 | [diff] [blame] | 212 | } |
| 213 | |
Partouf | 7ba94cc | 2018-10-15 02:39:11 +0200 | [diff] [blame] | 214 | getLibrariesAsArray(languageId) { |
| 215 | const libsForLanguageObj = this.options.options.libs[languageId]; |
Partouf | 5556038 | 2018-10-15 02:36:39 +0200 | [diff] [blame] | 216 | if (!libsForLanguageObj) return []; |
| 217 | |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 218 | return Object.keys(libsForLanguageObj).map(key => { |
Partouf | 7ba94cc | 2018-10-15 02:39:11 +0200 | [diff] [blame] | 219 | const language = libsForLanguageObj[key]; |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 220 | const versionArr = Object.keys(language.versions).map(key => { |
Partouf | 7ba94cc | 2018-10-15 02:39:11 +0200 | [diff] [blame] | 221 | let versionObj = Object.assign({}, language.versions[key]); |
Partouf | 5556038 | 2018-10-15 02:36:39 +0200 | [diff] [blame] | 222 | versionObj.id = key; |
| 223 | return versionObj; |
| 224 | }); |
| 225 | |
| 226 | return { |
| 227 | id: key, |
Partouf | 7ba94cc | 2018-10-15 02:39:11 +0200 | [diff] [blame] | 228 | name: language.name, |
| 229 | description: language.description, |
| 230 | url: language.url, |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 231 | versions: versionArr, |
Partouf | 5556038 | 2018-10-15 02:36:39 +0200 | [diff] [blame] | 232 | }; |
| 233 | }); |
| 234 | } |
| 235 | |
RabsRincon | a492311 | 2019-01-28 08:22:54 +0100 | [diff] [blame] | 236 | handleLangLibraries(req, res, next) { |
Partouf | 8bb5e7d | 2018-10-15 02:32:31 +0200 | [diff] [blame] | 237 | if (this.options) { |
| 238 | if (req.params.language) { |
Matt Godbolt | 4cf5792 | 2020-01-12 11:18:39 -0600 | [diff] [blame] | 239 | res.send(this.getLibrariesAsArray(req.params.language)); |
Partouf | 8bb5e7d | 2018-10-15 02:32:31 +0200 | [diff] [blame] | 240 | } else { |
| 241 | next({ |
| 242 | statusCode: 404, |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 243 | message: 'Language is required', |
Partouf | 8bb5e7d | 2018-10-15 02:32:31 +0200 | [diff] [blame] | 244 | }); |
| 245 | } |
| 246 | } else { |
| 247 | next({ |
| 248 | statusCode: 500, |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 249 | message: 'Internal error', |
Partouf | 8bb5e7d | 2018-10-15 02:32:31 +0200 | [diff] [blame] | 250 | }); |
partouf | 2ef40c9 | 2018-01-01 22:30:26 +0100 | [diff] [blame] | 251 | } |
| 252 | } |
| 253 | |
RabsRincon | a492311 | 2019-01-28 08:22:54 +0100 | [diff] [blame] | 254 | handleAllLibraries(req, res, next) { |
| 255 | if (this.options) { |
Matt Godbolt | 4cf5792 | 2020-01-12 11:18:39 -0600 | [diff] [blame] | 256 | res.send(this.options.options.libs); |
RabsRincon | a492311 | 2019-01-28 08:22:54 +0100 | [diff] [blame] | 257 | } else { |
| 258 | next({ |
| 259 | statusCode: 500, |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 260 | message: 'Internal error', |
RabsRincon | a492311 | 2019-01-28 08:22:54 +0100 | [diff] [blame] | 261 | }); |
| 262 | } |
| 263 | } |
| 264 | |
partouf | 2ef40c9 | 2018-01-01 22:30:26 +0100 | [diff] [blame] | 265 | handleCompilers(req, res) { |
| 266 | let filteredCompilers = this.compilers; |
| 267 | if (req.params.language) { |
Matt Godbolt | 21b764f | 2022-04-25 18:22:11 -0500 | [diff] [blame] | 268 | filteredCompilers = this.compilers.filter(val => val.lang === req.params.language); |
partouf | 2ef40c9 | 2018-01-01 22:30:26 +0100 | [diff] [blame] | 269 | } |
| 270 | |
Matt Godbolt | 4cf5792 | 2020-01-12 11:18:39 -0600 | [diff] [blame] | 271 | this.outputList(filteredCompilers, 'Compiler Name', req, res); |
partouf | 2ef40c9 | 2018-01-01 22:30:26 +0100 | [diff] [blame] | 272 | } |
| 273 | |
RabsRincon | 16ff1a8 | 2021-08-13 05:31:40 +0200 | [diff] [blame] | 274 | handleReleaseName(req, res) { |
| 275 | res.send(this.release.gitReleaseName); |
| 276 | } |
| 277 | |
| 278 | handleReleaseBuild(req, res) { |
| 279 | res.send(this.release.releaseBuildNumber); |
| 280 | } |
| 281 | |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 282 | setCompilers(compilers) { |
| 283 | this.compilers = compilers; |
RabsRincon | 8429842 | 2018-04-08 03:05:38 +0200 | [diff] [blame] | 284 | this.usedLangIds = _.uniq(_.pluck(this.compilers, 'lang')); |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 285 | } |
partouf | 2ef40c9 | 2018-01-01 22:30:26 +0100 | [diff] [blame] | 286 | |
| 287 | setLanguages(languages) { |
| 288 | this.languages = languages; |
| 289 | } |
Partouf | 8bb5e7d | 2018-10-15 02:32:31 +0200 | [diff] [blame] | 290 | |
| 291 | setOptions(options) { |
| 292 | this.options = options; |
| 293 | } |
RabsRincon | 16ff1a8 | 2021-08-13 05:31:40 +0200 | [diff] [blame] | 294 | |
| 295 | setReleaseInfo(gitReleaseName, releaseBuildNumber) { |
| 296 | this.release = { |
| 297 | gitReleaseName: gitReleaseName || '', |
| 298 | releaseBuildNumber: releaseBuildNumber || '', |
| 299 | }; |
| 300 | } |
Matt Godbolt | 1c3e94d | 2017-12-11 20:05:58 -0600 | [diff] [blame] | 301 | } |