<commit_before>/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
import {exec} from 'shelljs';
import {parseCommitMessage, validateCommitMessage, ValidateCommitMessageOptions} from './validate';

// Whether the provided commit is a fixup commit.
const isNonFixup = (m: string) => !parseCommitMessage(m).isFixup;

/** Validate all commits in a provided git commit range. */
export function validateCommitRange(range: string) {
  // A random value is used as a string to allow for a definite split point in the git log result.
  const randomValueSeparator = `${Math.random()}`;
  // Custom git log format that provides the commit header and body, separated as expected with
  // the custom separator as the trailing value.
  const gitLogFormat = `%s%n%n%b${randomValueSeparator}`;

  // Retrieve the commits in the provided range.
  const result = exec(`git log --reverse --format=${gitLogFormat} ${range}`, {silent: true});
  if (result.code) {
    throw new Error(`Failed to get all commits in the range: \n  ${result.stderr}`);
  }

  // Separate the commits from a single string into individual commits
  const commits = result.split(randomValueSeparator).map(l => l.trim()).filter(line => !!line);

  console.info(`Examining ${commits.length} commit(s) in the provided range: ${range}`);

  // Check each commit in the commit range.  Commits are allowed to be fixup commits for other
  // commits in the provided commit range.
  const allCommitsInRangeValid = commits.every((m, i) => {
    const options: ValidateCommitMessageOptions = {
      disallowSquash: true,
      nonFixupCommitHeaders: isNonFixup(m) ? undefined : commits.slice(0, i).filter(isNonFixup)
    };
    return validateCommitMessage(m, options);
  });
  if (allCommitsInRangeValid) {
    console.info('√  All commit messages in range valid.');
  }
}<commit_msg>fix(dev-infra): exit non-zero if commit message validation failed (#36723)<commit_after>/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
import {exec} from 'shelljs';
import {parseCommitMessage, validateCommitMessage, ValidateCommitMessageOptions} from './validate';

// Whether the provided commit is a fixup commit.
const isNonFixup = (m: string) => !parseCommitMessage(m).isFixup;

/** Validate all commits in a provided git commit range. */
export function validateCommitRange(range: string) {
  // A random value is used as a string to allow for a definite split point in the git log result.
  const randomValueSeparator = `${Math.random()}`;
  // Custom git log format that provides the commit header and body, separated as expected with
  // the custom separator as the trailing value.
  const gitLogFormat = `%s%n%n%b${randomValueSeparator}`;

  // Retrieve the commits in the provided range.
  const result = exec(`git log --reverse --format=${gitLogFormat} ${range}`, {silent: true});
  if (result.code) {
    throw new Error(`Failed to get all commits in the range: \n  ${result.stderr}`);
  }

  // Separate the commits from a single string into individual commits
  const commits = result.split(randomValueSeparator).map(l => l.trim()).filter(line => !!line);

  console.info(`Examining ${commits.length} commit(s) in the provided range: ${range}`);

  // Check each commit in the commit range.  Commits are allowed to be fixup commits for other
  // commits in the provided commit range.
  const allCommitsInRangeValid = commits.every((m, i) => {
    const options: ValidateCommitMessageOptions = {
      disallowSquash: true,
      nonFixupCommitHeaders: isNonFixup(m) ? undefined : commits.slice(0, i).filter(isNonFixup)
    };
    return validateCommitMessage(m, options);
  });

  if (allCommitsInRangeValid) {
    console.info('√  All commit messages in range valid.');
  } else {
    // Exit with a non-zero exit code if invalid commit messages have
    // been discovered.
    process.exit(1);
  }
}
{'fraction_non_alphanumeric': 0.11153846153846154, 'fraction_numerical': 0.0019230769230769232, 'mean_word_length': 3.9892086330935252, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6322429', 'n_tokens_mistral': 1185, 'n_tokens_neox': 1181, 'n_words': 451}