1

We are trying to set a max line change in our prs but are noticing there are some meta files that will easily exceed this limit such as yarn.lock.

does anyone know how to exclude files from the additions and deletions?

// ...

const linesAdded = danger.github.pr.additions || 0;
const linesRemoved = danger.github.pr.deletions || 0;

// ...

if (linesAdded + linesRemoved > bigPRThreshold) {
  fail(
    `This PR size is too large (Over ${bigPRThreshold} lines. Please split into separate PRs to enable faster & easier review.`
  );
}

// ...
Seth McClaine
  • 9,142
  • 6
  • 38
  • 64

3 Answers3

1

I found the following gitDSL functions to access information in individual files

//This should make it really easy to do work when specific keypaths have changed inside a JSON file.
JSONDiffForFile(filename: string) => Promise

// Provides a JSON patch (rfc6902) between the two versions of a JSON file, returns null if you don't have any changes for the file in the diff.

// Note that if you are looking to just see changes like: before, after, added or removed - you should use `JSONDiffForFile` instead, as this can be a bit unwieldy for a Dangerfile.
JSONPatchForFile(filename: string) => Promise

// Offers the diff for a specific file
diffForFile(filename: string) => Promise

// Offers the overall lines of code added/removed in the diff
linesOfCode() => Promise

// Offers the structured diff for a specific file
structuredDiffForFile(filename: string) => Promise

(Documentation on these functions: https://danger.systems/js/reference.html#GitDSL)

With danger.git.structuredDiffForFile I'm able to calculate lines I would like to exclude as so

  const file = 'yarn.lock';
  const diff1 = await danger.git.structuredDiffForFile(file);
  const excludedLines = diff1.chunks[0].changes.length
Seth McClaine
  • 9,142
  • 6
  • 38
  • 64
1

We use a glob pattern to specify the files we want to exclude:

  const linesCount = await danger.git.linesOfCode('**/*');
  // exclude fixtures and auto generated files
  const excludeLinesCount = await danger.git.linesOfCode(
    '{**/schemaTypes.ts,fixtures/**,package*.json,**/*.spec.ts,**/*.md}',
  );
  const totalLinesCount = linesCount - excludeLinesCount;

eamon0989
  • 144
  • 1
  • 2
  • 7
  • Thats a total count, not a diff count – Seth McClaine Dec 22 '22 at 14:13
  • The `linesOfCode` method offers the overall lines of code added/removed in the diff. So we first get the total count of lines added and removed, then we see how many of those lines are from files we want to exclude, and finally, we subtract the lines from files we want to exclude from the total. – eamon0989 Dec 22 '22 at 16:00
0

This works well:

import { markdown, message, danger, warn } from "danger";
import minimatch from "minimatch";

const pr = danger.github.pr;
const modifiedFiles = danger.git.modified_files;

(async function () {
    // Encourage smaller PRs
    await checkPRSize();
    
})();

async function checkPRSize() {
  const MAX_ADDITIONS_COUNT = 500;

  const ignoredLineCount = await getIgnoredLineCount();

  if (pr.additions - ignoredLineCount > MAX_ADDITIONS_COUNT) {
    warn("Its too big!");
  }
}

// Get the number of additions in files that we want to ignore
// so that we can subtract them from the total additions
// Use a glob to match multiple files in different location
async function getIgnoredLineCount(): Promise<number> {
  let ignoredLineCount = 0;
  const IGNORE_FILE_GLOB = "**/*+(.schema.json|package.lock)";
  const ignoredFiles = modifiedFiles.filter((file) =>
    minimatch(file, IGNORE_FILE_GLOB)
  );

  await Promise.all(
    ignoredFiles.map(async (file) => {
      const diff = await danger.git.structuredDiffForFile(file);
      diff.chunks.map((chunk) => {
        // Here we filter to only get the additions
        const additions = chunk.changes.filter(({ type }) => type === "add");
        ignoredLineCount = ignoredLineCount + additions.length;
      });
    })
  );

  return ignoredLineCount;
}
James
  • 431
  • 9
  • 15