diff --git a/packages/bruno-cli/src/commands/run.js b/packages/bruno-cli/src/commands/run.js index ccbfa8581..ca3e315dd 100644 --- a/packages/bruno-cli/src/commands/run.js +++ b/packages/bruno-cli/src/commands/run.js @@ -6,6 +6,7 @@ const { getRunnerSummary } = require('@usebruno/common/runner'); const { exists, isFile, isDirectory } = require('../utils/filesystem'); const { runSingleRequest } = require('../runner/run-single-request'); const { bruToEnvJson, getEnvVars } = require('../utils/bru'); +const { isRequestTagsIncluded } = require("@usebruno/common") const makeJUnitOutput = require('../reporters/junit'); const makeHtmlOutput = require('../reporters/html'); const { rpad } = require('../utils/common'); @@ -199,6 +200,14 @@ const builder = async (yargs) => { type:"number", description: "Delay between each requests (in miliseconds)" }) + .option('tags', { + type: 'string', + description: 'Tags to include in the run' + }) + .option('exclude-tags', { + type: 'string', + description: 'Tags to exclude from the run' + }) .example('$0 run request.bru', 'Run a request') .example('$0 run request.bru --env local', 'Run a request with the environment set to local') .example('$0 run request.bru --env-file env.bru', 'Run a request with the environment from env.bru file') @@ -268,7 +277,9 @@ const handler = async function (argv) { reporterSkipHeaders, clientCertConfig, noproxy, - delay + delay, + tags: includeTags, + excludeTags } = argv; const collectionPath = process.cwd(); @@ -353,7 +364,7 @@ const handler = async function (argv) { if (!match) { console.error( chalk.red(`Overridable environment variable not correct: use name=value - presented: `) + - chalk.dim(`${value}`) + chalk.dim(`${value}`) ); process.exit(constants.EXIT_STATUS.ERROR_INCORRECT_ENV_OVERRIDE); } @@ -389,6 +400,9 @@ const handler = async function (argv) { } options['ignoreTruststore'] = ignoreTruststore; + includeTags = includeTags ? includeTags.split(',') : []; + excludeTags = excludeTags ? excludeTags.split(',') : []; + if (['json', 'junit', 'html'].indexOf(format) === -1) { console.error(chalk.red(`Format must be one of "json", "junit or "html"`)); process.exit(constants.EXIT_STATUS.ERROR_INCORRECT_OUTPUT_FORMAT); @@ -444,6 +458,10 @@ const handler = async function (argv) { console.error(chalk.red(`Path not found: ${resolvedPath}`)); process.exit(constants.EXIT_STATUS.ERROR_FILE_NOT_FOUND); } + + requestItems = requestItems.filter((item) => { + return isRequestTagsIncluded(item.tags, includeTags, excludeTags); + }); } requestItems = getCallStack(resolvedPaths, collection, { recursive }); diff --git a/packages/bruno-cli/src/utils/bru.js b/packages/bruno-cli/src/utils/bru.js index 07844a455..d78c153e3 100644 --- a/packages/bruno-cli/src/utils/bru.js +++ b/packages/bruno-cli/src/utils/bru.js @@ -60,6 +60,7 @@ const bruToJson = (bru) => { type: requestType, name: _.get(json, 'meta.name'), seq: !isNaN(sequence) ? Number(sequence) : 1, + tags: _.get(json, 'tags', []), request: { method: _.upperCase(_.get(json, 'http.method')), url: _.get(json, 'http.url'), diff --git a/packages/bruno-common/src/index.ts b/packages/bruno-common/src/index.ts index c49e79d58..81f0cae72 100644 --- a/packages/bruno-common/src/index.ts +++ b/packages/bruno-common/src/index.ts @@ -1,2 +1,3 @@ export { mockDataFunctions } from './utils/faker-functions'; -export { default as interpolate } from './interpolate'; +export {default as interpolate} from './interpolate'; +export {default as isRequestTagsIncluded} from './tags'; diff --git a/packages/bruno-common/src/tags/index.spec.ts b/packages/bruno-common/src/tags/index.spec.ts new file mode 100644 index 000000000..46d307502 --- /dev/null +++ b/packages/bruno-common/src/tags/index.spec.ts @@ -0,0 +1,43 @@ +import isRequestTagsIncluded from './index'; + +describe('isRequestTagsIncluded', () => { + it('should include request when it has an included tag', () => { + const requestTags = ['tag1', 'tag2']; + const includeTags = ['tag1']; + const excludeTags: string[] = []; + const result = isRequestTagsIncluded(requestTags, includeTags, excludeTags); + expect(result).toBe(true); + }); + + it('should include request when included tags is empty', () => { + const requestTags = ['tag1', 'tag2']; + const includeTags: string[] = []; + const excludeTags: string[] = []; + const result = isRequestTagsIncluded(requestTags, includeTags, excludeTags); + expect(result).toBe(true); + }); + + it('should exclude request when it does not have an included tag', () => { + const requestTags = ['tag1']; + const includeTags = ['tag2']; + const excludeTags: string[] = []; + const result = isRequestTagsIncluded(requestTags, includeTags, excludeTags); + expect(result).toBe(false); + }); + + it('should exclude request when it has an excluded tag', () => { + const requestTags = ['tag1']; + const includeTags: string[] = []; + const excludeTags = ['tag1']; + const result = isRequestTagsIncluded(requestTags, includeTags, excludeTags); + expect(result).toBe(false); + }); + + it('should exclude request when it has both included and excluded tag', () => { + const requestTags = ['tag1', 'tag2']; + const includeTags: string[] = ['tag2']; + const excludeTags = ['tag1']; + const result = isRequestTagsIncluded(requestTags, includeTags, excludeTags); + expect(result).toBe(false); + }); +}); diff --git a/packages/bruno-common/src/tags/index.ts b/packages/bruno-common/src/tags/index.ts new file mode 100644 index 000000000..a2adfe798 --- /dev/null +++ b/packages/bruno-common/src/tags/index.ts @@ -0,0 +1,13 @@ +/** + * A request should be included if it has at least one tag that is included and no tags that are excluded + * @param requestTags Tags of the request + * @param includeTags Tags to include + * @param excludeTags Tags to exclude + */ +export const isRequestTagsIncluded = (requestTags: string[], includeTags: string[], excludeTags: string[]) => { + const shouldInclude = includeTags.length === 0 || requestTags.some((tag) => includeTags.includes(tag)); + const shouldExclude = excludeTags.length > 0 && requestTags.some((tag) => excludeTags.includes(tag)); + return shouldInclude && !shouldExclude; +}; + +export default isRequestTagsIncluded;