UNPKG

@splunk/rum-cli

Version:

Tools for handling symbol and mapping files for symbolication

149 lines (148 loc) 7.66 kB
"use strict"; /* * Copyright Splunk Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.iOSCommand = void 0; const commander_1 = require("commander"); const spinner_1 = require("../utils/spinner"); const constants_1 = require("../utils/constants"); const dsymClient_1 = require("../dsyms/dsymClient"); const logger_1 = require("../utils/logger"); const iOSdSYMUtils_1 = require("../dsyms/iOSdSYMUtils"); const userFriendlyErrors_1 = require("../utils/userFriendlyErrors"); const metadataFormatUtils_1 = require("../utils/metadataFormatUtils"); const inputValidations_1 = require("../utils/inputValidations"); const program = new commander_1.Command(); exports.iOSCommand = program.command('ios'); const shortDescription = 'Upload and list iOS symbolication files (dSYMs)'; const detailedHelp = `For each respective command listed below under 'Commands', please run 'splunk-rum ios <command> --help' for an overview of its usage and options`; const iOSUploadDescription = 'This subcommand uploads dSYMs provided as either a zip file, or a dSYM or dSYMs directory.'; const iOSUploadSummary = 'Upload dSYMs, either by directory path or zip path, to the symbolication service'; const listdSYMsDescription = `This subcommand retrieves and shows a list of the uploaded dSYMs. By default, it returns the last 100 dSYMs uploaded, sorted in reverse chronological order based on the upload timestamp. `; exports.iOSCommand .description(shortDescription) .usage('[command] [options]'); exports.iOSCommand.configureHelp({ commandDescription: (cmd) => { return `${cmd.description()}\n\n${detailedHelp}`; } }); exports.iOSCommand .command('upload') .showHelpAfterError(inputValidations_1.COMMON_ERROR_MESSAGES.HELP_MESSAGE_AFTER_ERROR) .usage('--path <dSYMs directory or zip file>') .description(iOSUploadDescription) .summary(iOSUploadSummary) .requiredOption('--path <dSYMs dir or zip>', 'Path to the dSYM[s] directory or zip file.') .requiredOption('--realm <value>', 'Realm for your organization (example: us0). Can also be set using the environment variable SPLUNK_REALM', process.env.SPLUNK_REALM) .option('--token <value>', 'API access token. Can also be set using the environment variable SPLUNK_ACCESS_TOKEN') .option('--debug', 'Enable debug logs') .option('--dry-run', 'Perform a trial run with no changes made', false) .action((options) => __awaiter(void 0, void 0, void 0, function* () { const spinner = (0, spinner_1.createSpinner)(); const logger = (0, logger_1.createLogger)(options.debug ? 1 /* LogLevel.DEBUG */ : 2 /* LogLevel.INFO */, spinner); try { // Step 1: Validate and prepare the token const token = (0, inputValidations_1.validateAndPrepareToken)(options); // Step 2: Validate the input path and prepare the zipped files const { zipFiles, uploadPath } = (0, iOSdSYMUtils_1.prepareUploadFiles)(options.path, logger); // Step 3: Upload the files yield (0, dsymClient_1.uploadDSYMZipFiles)({ zipFiles, uploadPath, realm: options.realm, token, logger, spinner, }); logger.info('All dSYM files uploaded successfully.'); } catch (error) { spinner.stop(); if (error instanceof userFriendlyErrors_1.UserFriendlyError) { // UserFriendlyError.message already contains the formatted string from formatCLIErrorMessage logger.error(error.message); if (options.debug && error.originalError) { logger.debug('Original error details:', error.originalError); } } else { logger.error(error instanceof Error ? error.message : `An unexpected error occurred: ${String(error)}`); } exports.iOSCommand.error(''); // ensure error exit code. process.exit(1) would also work. } })); exports.iOSCommand .command('list') .summary('Retrieves list of metadata of all uploaded dSYM files') .showHelpAfterError(inputValidations_1.COMMON_ERROR_MESSAGES.HELP_MESSAGE_AFTER_ERROR) .description(listdSYMsDescription) .option('--debug', 'Enable debug logs') .requiredOption('--realm <value>', 'Realm for your organization (example: us0). Can also be set using the environment variable SPLUNK_REALM', process.env.SPLUNK_REALM) .option('--token <value>', 'API access token. Can also be set using the environment variable SPLUNK_ACCESS_TOKEN') .action((options) => __awaiter(void 0, void 0, void 0, function* () { const logger = (0, logger_1.createLogger)(options.debug ? 1 /* LogLevel.DEBUG */ : 2 /* LogLevel.INFO */); logger.info('Fetching dSYM file data...'); try { const token = (0, inputValidations_1.validateAndPrepareToken)(options); const url = (0, iOSdSYMUtils_1.generateUrl)({ apiPath: constants_1.IOS_CONSTANTS.PATH_FOR_METADATA, realm: options.realm }); const responseData = yield (0, dsymClient_1.listDSYMs)({ url, token: token, logger, }); logger.info((0, metadataFormatUtils_1.formatIOSdSYMMetadata)(responseData)); } catch (error) { if (error instanceof userFriendlyErrors_1.UserFriendlyError) { // The UserFriendlyError.message is already formatted by formatCLIErrorMessage // and includes both user-friendly text and technical details. // logger.error will prefix this with "ERROR " and handle colors. logger.error(error.message); if (options.debug && error.originalError) { logger.debug('Original error details:', error.originalError); } } else { // For any other unexpected errors (e.g. non-Axios, such as in token validation) logger.error('An unexpected error occurred during the iOS list command:'); if (error instanceof Error) { logger.error(error.message); if (options.debug && error.stack) { logger.debug(error.stack); } } else { logger.error(String(error)); // catchall for other error types } } exports.iOSCommand.error(''); // Error exit. Blank message because one was already logged. } }));