npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sizeup-core

v0.5.0

Published

A library for estimating how difficult a diff will be to review

Downloads

10

Readme

SizeUp

SizeUp is a library for estimating how difficult a diff will be to review.

Installation

npm install sizeup-core

Usage

The most common usage of this library is via one of these wrappers:

  • sizeup-action, which provides a GitHub Action to use this library to evaluate pull requests
  • sizeup-cli, which provides a CLI to use this library to evaluate a diff locally, prior to openining a pull request

To use the library directly, you need to first retrieve a diff, and the pass it to SizeUp.evaluate (optionally also providing a custom configuration file):

import { SizeUp } from "sizeup-core"

const diff = (
  await octokit
    .rest
    .pulls
    .get({
    "lerebear",
    "sizeup",
    pull_number: 1,

    // This is the easiest way to request a diff directly, but since Octokit
    // doesn't provide the correct result type when we use the `mediaType`
    // option, we must cast the result to a string later on
    mediaType: {format: 'diff'},
  })
).data as unknown as string

const score = SizeUp.evaluate(diff)
console.log(score.toString())

The final log statement in that snippet will output a serialized Score:

{
  // The expression (written in prefix notation) used to score the diff
  "formula": "- - + additions deletions comments whitespace",

  // The values that were substituted for each variable in the formula
  "variableSubstitutions": [
    [
      "additions",
      11
    ],
    [
      "deletions",
      3
    ],
    [
      "comments",
      6
    ],
    [
      "whitespace",
      1
    ]
  ],

  // The score the diff received when evaluated according to the formula
  "value": 7,

  // The category the diff was assigned based on its score
  "category": "xs"
}

API

The public API for this library consists of the single, static SizeUp.evaluate method:

export class SizeUp {
  /**
   * Evaluates a diff for reviewability.
   *
   * @param diff A .diff formatted string containing the code to evaluate
   * @param configPath Path to a YAML configuration file containing options for how to evaluate the
   *   pull request. The YAML file should conform to the JSON schema in src/config/schema.json.
   */
  static evaluate(diff: string, configPath?: string): Score
}

Configuration

This section describes how to configure this library.

Overview

As shown above, SizeUp.evaluate accepts a YAML configuration file that can be used to customize the evaluation process. Here's an example:

categories:
  - name: xs
    lte: 10
  - name: s
    lte: 30
  - name: m
    lte: 100
  - name: l
    lte: 500
  - name: xl
ignoredFilePatterns:
  - CODEOWNERS
  - SERVICEOWNERS
testFilePatterns:
  - "*_test.rb"
scoring:
  formula: "- - + additions deletions comments whitespace"

The default configuration that is used when no configuration file is provided can be found in src/config/default.yaml.

The full specification for the configuration file is provided by the JSON schema at src/config/schema.json.

Configuring a scoring formula

sizeup is designed to allow users to experiment with different ways to evaluate a diff. You can do this my writing a custom scoring formula that you provide to the libary via the score.formula key in the configuration file.

The elements of a formula are described in more detail in each of the following sections:

Prefix notation

Each formula is written in prefix notation, which means that instead of writing a mathematical operator in between its operands (infix notation), you write it before its operands. For example:

| Traditional (infix notation) expression | Equivalent prefix notation expression | | :--- | :--- | | 1 + 2| + 1 2 | | (2 + 3) / 10 | / + 2 3 10 |

Operators

Operators are used to evaluate numerical or logical sub-expressions in a formula. This tool supports the following operators:

| Symbol | Meaning | Example | | :--- | :--- | :--- | | + | addition | + 1 2 evaluates to 3 | | - | subtraction | - 2 1 evaluates to 1 | | * | multiplication | * 1 2 evaluates to 2 | | \ | division | / 4 2 evaluates to 2 | | ^ | exponentiation | ^ 2 3 evaluates to 8 | | ? | conditional evaluation | ? 0 2 4 evaluates to 4 because 0 is considered false[^1] | | > | greater than | > 1 2 evaluates to false | | < | less than | < 1 2 evaluates to true | | >= | greater than or equal to | >= 1 2 evaluates to false | | <= | less than or equal to | <= 1 1 evaluates to true | | == | equals | == 1 1 evaluates to true | | != | not equal | != 1 1 evaluates to false | | & | logical and | & 0 1 evaluates to false[^1] | | \| | logical or | \| 0 1 evaluates to true[^1] | | ! | logical not | ! 1 evaluates to false[^1] |

[^1]: All positive numbers are considered truthy; 0 and all negative numbers are considered falsey.

Each operand can be one of three things:

  1. A numerical constant like 0.5 or 99
  2. The name of a feature
  3. The name of an alias

Features

Features describe aspects of a diff that can be computed from it automatically. This tool support the following features:

| Feature | Description | | :--- | :--- | | additions | The number of lines that were added in a diff | | comments | The number of additions in a diff that match the syntax of a comment in a supported programming language. | | deletions | The number of lines that were deleted in a diff | | single-words | The number of additions in a diff that are made up of a single word on its own line | | tests | The number of additions in a diff that were made in files that match a pattern from the testFilePatterns configuration value. | | whitespace | The number of additions in a diff that were pure whitespace |

If you have an idea for a new feature, please suggest an enhancement.

Aliases

Aliases, which are configured under the scoring.aliases key, allow you to define a shorthand for a longer expression:

scoring:
  formula: "- changes non-functional-changes"
  aliases:
    changes: "+ additions deletions"
    non-functional-changes: "+ comments whitespace"

Development

This section contains notes for how to develop this library.

Regenerating the Typescript interface for the configuration schema

We use a JSON schema to define the configuration options that this library supports. We then use the json-schema-to-typescript package to generate the TypeScript Configuration interface that we use in code.

json-schema-to-typescript has two notable shortcomings:

  • It uses outdated type definitions which are incompatible with the latest version of minimatch that we use in this package. This creates build errors if json-schema-to-typescript is added as a dependency of this package.
  • It generates a type definition for the categories array this is difficult to work with (it wraps a category object in an array e.g. [{name:}] rather than using an array suffix e.g. {name:}[]).

To work around those issues, we use the following workflow to regenerate the Configuration interface after we've made a change to the schema:

  1. Temporarily install json-schema-to-typescript:
npm install --save-dev json-schema-to-typescript
  1. Regenerate the Configuration interface using this command:
npx \
  json2ts \
  --maxItems=-1 \
  --additionalProperties=false \
  src/config/schema.json \
  src/configuration.ts
  1. Manually modify the Configuration.categories key to use an array suffix.

  2. Remove json-schema-to-typescript so that we can again build this package without errors.

npm uninstall json-schema-to-typescript