Lawrence  Lesch

Lawrence Lesch

1668077768

Utility-types: Collection Of Utility Types

utility-types

Collection of utility types, complementing TypeScript built-in mapped types and aliases (think "lodash" for static types).

Found it useful? Want more updates? 


What's new?

πŸŽ‰ Now updated to support TypeScript v3.7 πŸŽ‰


Features

Goals

  • Quality - thoroughly tested for type correctness with type-testing library dts-jest
  • Secure and minimal - no third-party dependencies
  • No runtime cost - it's type-level only

Installation

# NPM
npm install utility-types

# YARN
yarn add utility-types

Compatibility Notes

TypeScript support

  • v3.x.x - TypeScript v3.1+
  • v2.x.x - TypeScript v2.8.1+
  • v1.x.x - TypeScript v2.7.2+

Funding Issues

Utility-Types is an open-source project created by people investing their time for the benefit of our community.

Issues like bug fixes or feature requests can be very quickly resolved when funded through the IssueHunt platform.

I highly recommend adding a bounty to the issue that you're waiting for to attract some contributors willing to work on it.

Let's fund issues in this repository

Contributing

We are open for contributions. If you're planning to contribute please make sure to read the contributing guide as it can save you from wasting your time: CONTRIBUTING.md


  • (built-in) - types built-in TypeScript, no need to import

Table of Contents

Aliases & Type Guards

Union operators

Object operators

Special operators

Flow's Utility Types

Deprecated API (use at own risk)

  • getReturnOfExpression() - from TS v2.0 it's better to use type-level ReturnType instead

Primitive

Type representing primitive types in JavaScript, and thus TypeScript: string | number | bigint | boolean | symbol | null | undefined

You can test for singular of these types with typeof

isPrimitive

This is a TypeScript Typeguard for the Primitive type.

This can be useful to control the type of a parameter as the program flows. Example:

const consumer = (param: Primitive[] | Primitive): string => {
    if (isPrimitive(param)) {
        // typeof param === Primitive
        return String(param) + ' was Primitive';
    }
    // typeof param === Primitive[]
    const resultArray = param
        .map(consumer)
        .map(rootString => '\n\t' + rootString);
    return resultArray.reduce((comm, newV) => comm + newV, 'this was nested:');
};

Falsy

Type representing falsy values in TypeScript: false | "" | 0 | null | undefined

Except NaN which cannot be represented as a type literal

isFalsy

const consumer = (param: Falsy | string): string => {
    if (isFalsy(param)) {
        // typeof param === Falsy
        return String(param) + ' was Falsy';
    }
    // typeof param === string
    return param.toString();
};

Nullish

Type representing nullish values in TypeScript: null | undefined

isNullish

const consumer = (param: Nullish | string): string => {
    if (isNullish(param)) {
        // typeof param === Nullish
        return String(param) + ' was Nullish';
    }
    // typeof param === string
    return param.toString();
};

SetIntersection<A, B> (same as Extract)

Set intersection of given union types A and B

Usage:

import { SetIntersection } from 'utility-types';

// Expect: "2" | "3"
type ResultSet = SetIntersection<'1' | '2' | '3', '2' | '3' | '4'>;
// Expect: () => void
type ResultSetMixed = SetIntersection<string | number | (() => void), Function>;

SetDifference<A, B> (same as Exclude)

Set difference of given union types A and B

Usage:

import { SetDifference } from 'utility-types';

// Expect: "1"
type ResultSet = SetDifference<'1' | '2' | '3', '2' | '3' | '4'>;
// Expect: string | number
type ResultSetMixed = SetDifference<string | number | (() => void), Function>;

SetComplement<A, A1>

Set complement of given union types A and (it's subset) A1

Usage:

import { SetComplement } from 'utility-types';

// Expect: "1"
type ResultSet = SetComplement<'1' | '2' | '3', '2' | '3'>;

SymmetricDifference<A, B>

Set difference of union and intersection of given union types A and B

Usage:

import { SymmetricDifference } from 'utility-types';

// Expect: "1" | "4"
type ResultSet = SymmetricDifference<'1' | '2' | '3', '2' | '3' | '4'>;

NonNullable<A>

Exclude null and undefined from set A

NonUndefined<A>

Exclude undefined from set A

Exclude<A, B>

Exclude subset B from set A

Extract<A, B>

Extract subset B from set A

Operations on objects

FunctionKeys<T>

Get union type of keys that are functions in object type T

Usage:

import { FunctionKeys } from 'utility-types';

type MixedProps = { name: string; setName: (name: string) => void };

// Expect: "setName"
type Keys = FunctionKeys<MixedProps>;

NonFunctionKeys<T>

Get union type of keys that are non-functions in object type T

Usage:

import { NonFunctionKeys } from 'utility-types';

type MixedProps = { name: string; setName: (name: string) => void };

// Expect: "name"
type Keys = NonFunctionKeys<MixedProps>;

MutableKeys<T>

Get union type of keys that are mutable (not readonly) in object type T

Alias: WritableKeys<T>

Usage:

import { MutableKeys } from 'utility-types';

type Props = { readonly foo: string; bar: number };

// Expect: "bar"
type Keys = MutableKeys<Props>;

ReadonlyKeys<T>

Get union type of keys that are readonly in object type T

Usage:

import { ReadonlyKeys } from 'utility-types';

type Props = { readonly foo: string; bar: number };

// Expect: "foo"
type Keys = ReadonlyKeys<Props>;

RequiredKeys<T>

Get union type of keys that are required in object type T

Usage:

import { RequiredKeys } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; optUndef?: number | undefined; };

// Expect: "req" | "reqUndef"
type Keys = RequiredKeys<Props>;

OptionalKeys<T>

Get union type of keys that are optional in object type T

Usage:

import { OptionalKeys } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; optUndef?: number | undefined; };

// Expect: "opt" | "optUndef"
type Keys = OptionalKeys<Props>;

Optional<T, K>

From T make a set of properties by key K become optional

Usage:

import { Optional } from 'utility-types';

type Props = { name: string; age: number; visible: boolean; };

// Expect: { name?: string; age?: number; visible?: boolean; }
type Props = Optional<Props>
// Expect: { name: string; age?: number; visible?: boolean; }
type Props = Optional<Props, 'age' | 'visible'>;

Pick<T, K> (built-in)

From T pick a set of properties by key K

Usage:

type Props = { name: string; age: number; visible: boolean };

// Expect: { age: number; }
type Props = Pick<Props, 'age'>;

PickByValue<T, ValueType>

From T pick a set of properties by value matching ValueType. (Credit: Piotr Lewandowski)

Usage:

import { PickByValue } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; };

// Expect: { req: number }
type Props = PickByValue<Props, number>;
// Expect: { req: number; reqUndef: number | undefined; }
type Props = PickByValue<Props, number | undefined>;

PickByValueExact<T, ValueType>

From T pick a set of properties by value matching exact ValueType.

Usage:

import { PickByValueExact } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; };

// Expect: { req: number }
type Props = PickByValueExact<Props, number>;
// Expect: { reqUndef: number | undefined; }
type Props = PickByValueExact<Props, number | undefined>;

Omit<T, K>

From T remove a set of properties by key K

Usage:

import { Omit } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: { name: string; visible: boolean; }
type Props = Omit<Props, 'age'>;

OmitByValue<T, ValueType>

From T remove a set of properties by value matching ValueType. (Credit: Piotr Lewandowski)

Usage:

import { OmitByValue } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; };

// Expect: { reqUndef: number | undefined; opt?: string; }
type Props = OmitByValue<Props, number>;
// Expect: { opt?: string; }
type Props = OmitByValue<Props, number | undefined>;

OmitByValueExact<T, ValueType>

From T remove a set of properties by value matching exact ValueType.

Usage:

import { OmitByValueExact } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; };

// Expect: { reqUndef: number | undefined; opt?: string; }
type Props = OmitByValueExact<Props, number>;
// Expect: { req: number; opt?: string }
type Props = OmitByValueExact<Props, number | undefined>;

Intersection<T, U>

From T pick properties that exist in U

Usage:

import { Intersection } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };

// Expect: { age: number; }
type DuplicatedProps = Intersection<Props, DefaultProps>;

Diff<T, U>

From T remove properties that exist in U

Usage:

import { Diff } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };

// Expect: { name: string; visible: boolean; }
type RequiredProps = Diff<Props, DefaultProps>;

Subtract<T, T1>

From T remove properties that exist in T1 (T1 has a subset of the properties of T)

Usage:

import { Subtract } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };

// Expect: { name: string; visible: boolean; }
type RequiredProps = Subtract<Props, DefaultProps>;

Overwrite<T, U>

From U overwrite properties to T

Usage:

import { Overwrite } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type NewProps = { age: string; other: string };

// Expect: { name: string; age: string; visible: boolean; }
type ReplacedProps = Overwrite<Props, NewProps>;

Assign<T, U>

From U assign properties to T (just like object assign)

Usage:

import { Assign } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type NewProps = { age: string; other: string };

// Expect: { name: string; age: string; visible: boolean; other: string; }
type ExtendedProps = Assign<Props, NewProps>;

ValuesType<T>

Get the union type of all the values in an object, tuple, array or array-like type T.

Usage:

import { ValuesType } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
// Expect: string | number | boolean
type PropsValues = ValuesType<Props>;

type NumberArray = number[];
// Expect: number
type NumberItems = ValuesType<NumberArray>;

type ReadonlyNumberTuple = readonly [1, 2];
// Expect: 1 | 2
type AnotherNumberUnion = ValuesType<NumberTuple>;

type BinaryArray = Uint8Array;
// Expect: number
type BinaryItems = ValuesType<BinaryArray>;

Partial<T>

Make all properties of object type optional

Required<T, K>

From T make a set of properties by key K become required

Usage:

import { Required } from 'utility-types';

type Props = { name?: string; age?: number; visible?: boolean; };

// Expect: { name: string; age: number; visible: boolean; }
type Props = Required<Props>
// Expect: { name?: string; age: number; visible: boolean; }
type Props = Required<Props, 'age' | 'visible'>;

Readonly<T>

Make all properties of object type readonly

Mutable<T>

From T make all properties become mutable

Alias: Writable<T>

import { Mutable } from 'utility-types';

type Props = {
  readonly name: string;
  readonly age: number;
  readonly visible: boolean;
};

// Expect: { name: string; age: number; visible: boolean; }
Mutable<Props>;

ReturnType<T>

Obtain the return type of a function

InstanceType<T>

Obtain the instance type of a class

Unionize<T>

Disjoin object to form union of objects, each with single property

Usage:

import { Unionize } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: { name: string; } | { age: number; } | { visible: boolean; }
type UnionizedType = Unionize<Props>;

PromiseType<T>

Obtain Promise resolve type

Usage:

import { PromiseType } from 'utility-types';

// Expect: string
type Response = PromiseType<Promise<string>>;

DeepReadonly<T>

Readonly that works for deeply nested structures

Usage:

import { DeepReadonly } from 'utility-types';

type NestedProps = {
  first: {
    second: {
      name: string;
    };
  };
};

// Expect: {
//   readonly first: {
//     readonly second: {
//       readonly name: string;
//     };
//   };
// }
type ReadonlyNestedProps = DeepReadonly<NestedProps>;

DeepRequired<T>

Required that works for deeply nested structures

Usage:

import { DeepRequired } from 'utility-types';

type NestedProps = {
  first?: {
    second?: {
      name?: string;
    };
  };
};

// Expect: {
//   first: {
//     second: {
//       name: string;
//     };
//   };
// }
type RequiredNestedProps = DeepRequired<NestedProps>;

DeepNonNullable<T>

NonNullable that works for deeply nested structure

Usage:

import { DeepNonNullable } from 'utility-types';

type NestedProps = {
  first?: null | {
    second?: null | {
      name?: string | null | undefined;
    };
  };
};

// Expect: {
//   first: {
//     second: {
//       name: string;
//     };
//   };
// }
type RequiredNestedProps = DeepNonNullable<NestedProps>;

DeepPartial<T>

Partial that works for deeply nested structures

Usage:

import { DeepPartial } from 'utility-types';

type NestedProps = {
  first: {
    second: {
      name: string;
    };
  };
};

// Expect: {
//   first?: {
//     second?: {
//       name?: string;
//     };
//   };
// }
type PartialNestedProps = DeepPartial<NestedProps>;

Brand<T, U>

Define nominal type of U based on type of T. Similar to Opaque types in Flow.

Usage:

import { Brand } from 'utility-types';

type USD = Brand<number, "USD">
type EUR = Brand<number, "EUR">

const tax = 5 as USD;
const usd = 10 as USD;
const eur = 10 as EUR;

function gross(net: USD): USD {
  return (net + tax) as USD;
}

gross(usd); // ok
gross(eur); // Type '"EUR"' is not assignable to type '"USD"'.

UnionToIntersection<U>

Get intersection type given union type U

Usage:

import { UnionToIntersection } from 'utility-types';

// Expect: { name: string } & { age: number } & { visible: boolean }
UnionToIntersection<{ name: string } | { age: number } | { visible: boolean }>

Flow's Utility Types

$Keys<T>

get the union type of all the keys in an object type T
https://flow.org/en/docs/types/utilities/#toc-keys

Usage:

import { $Keys } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: "name" | "age" | "visible"
type PropsKeys = $Keys<Props>;

$Values<T>

get the union type of all the values in an object type T
https://flow.org/en/docs/types/utilities/#toc-values

Usage:

import { $Values } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: string | number | boolean
type PropsValues = $Values<Props>;

$ReadOnly<T>

get the read-only version of a given object type T
https://flow.org/en/docs/types/utilities/#toc-readonly

Usage:

import { $ReadOnly } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: Readonly<{ name: string; age: number; visible: boolean; }>
type ReadOnlyProps = $ReadOnly<Props>;

$Diff<T, U>

get the set difference of a given object types T and U (T \ U)
https://flow.org/en/docs/types/utilities/#toc-diff

Usage:

import { $Diff } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };

// Expect: { name: string; visible: boolean; }
type RequiredProps = $Diff<Props, DefaultProps>;

$PropertyType<T, K>

get the type of property of an object at a given key K
https://flow.org/en/docs/types/utilities/#toc-propertytype

Usage:

import { $PropertyType } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
// Expect: string
type NameType = $PropertyType<Props, 'name'>;

type Tuple = [boolean, number];
// Expect: boolean
type A = $PropertyType<Tuple, '0'>;
// Expect: number
type B = $PropertyType<Tuple, '1'>;

$ElementType<T, K>

get the type of elements inside of array, tuple or object of type T, that matches the given index type K
https://flow.org/en/docs/types/utilities/#toc-elementtype

Usage:

import { $ElementType } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
// Expect: string
type NameType = $ElementType<Props, 'name'>;

type Tuple = [boolean, number];
// Expect: boolean
type A = $ElementType<Tuple, 0>;
// Expect: number
type B = $ElementType<Tuple, 1>;

type Arr = boolean[];
// Expect: boolean
type ItemsType = $ElementType<Arr, number>;

type Obj = { [key: string]: number };
// Expect: number
type ValuesType = $ElementType<Obj, string>;

$Call<T>

get the return type of a given expression type
https://flow.org/en/docs/types/utilities/#toc-call

The built-in ReturnType can be used to accomplish the same goal, although it may have some subtle differences.

Usage:

import { $Call } from 'utility-types';

// Common use-case
const add = (amount: number) => ({ type: 'ADD' as 'ADD', payload: amount });
type AddAction = $Call<typeof add>; // { type: 'ADD'; payload: number }

// Examples migrated from Flow docs
type ExtractPropType<T extends { prop: any }> = (arg: T) => T['prop'];
type Obj = { prop: number };
type PropType = $Call<ExtractPropType<Obj>>; // number
// type Nope = $Call<ExtractPropType<{ nope: number }>>; // Error: argument doesn't match `Obj`.

type ExtractReturnType<T extends () => any> = (arg: T) => ReturnType<T>;
type Fn = () => number;
type FnReturnType = $Call<ExtractReturnType<Fn>>; // number

$Shape<T>

Copies the shape of the type supplied, but marks every field optional.
https://flow.org/en/docs/types/utilities/#toc-shape

Usage:

import { $Shape } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: Partial<Props>
type PartialProps = $Shape<Props>;

$NonMaybeType<T>

Converts a type T to a non-maybe type. In other words, the values of $NonMaybeType<T> are the values of T except for null and undefined.
https://flow.org/en/docs/types/utilities/#toc-nonmaybe

Usage:

import { $NonMaybeType } from 'utility-types';

type MaybeName = string | null;

// Expect: string
type Name = $NonMaybeType<MaybeName>;

Class<T>

Given a type T representing instances of a class C, the type Class is the type of the class C
https://flow.org/en/docs/types/utilities/#toc-class * Differs from original Flow's util - implements only constructor part and won't include any static members. Additionally classes in Typescript are not treated as nominal

Usage:

import { Class } from 'utility-types';


function makeStore(storeClass: Class<Store>): Store {
  return new storeClass();
}

mixed

An arbitrary type that could be anything (same as unknown)
https://flow.org/en/docs/types/mixed


Related Projects

  • ts-toolbelt - Higher type safety for TypeScript
  • $mol_type - Collection of TypeScript meta types for complex logic

Download Details:

Author: piotrwitek
Source Code: https://github.com/piotrwitek/utility-types 
License: MIT license

#typescript #utilities #static #type 

Utility-types: Collection Of Utility Types
Hermann  Frami

Hermann Frami

1668064680

Jamstack.org: The Official Jamstack Site

Jamstack

An entry-point for learning about this architectural model. A place to learn what Jamstack is, for sharing tools, tips, examples and articles. This is also a place to find a local community meetup, or to seek support in starting one of your own.

Contributing resources

We've collected a set of videos, presentation, articles and other learning resources about Jamstack. You can contribute content to that pool of resources!

We accept contributions submitted as pull requests.

Contribute links to resources

To contribute a link to a resource:

  1. Create a new yaml file in the src/site/_data/resources folder with a unique and descriptive name. Populate that file according to the structure shown below.
  2. For presentations and video, add an optional thumbnail image to the src/site/_data/resources folder. (Image should be a jpeg 600px wide and 400px tall)
  3. Submit a pull request

resource yaml reference:

title: Resource title
date: Publish date (YYYY-MM-DD)
link: the URL of this resource
thumbnailurl: /img/cms/resources/resource-thumbnail.jpg
type:
  - article (Help us group and sort the resources by type article|video|presentation)

Before submitting a pull request, or if you are suggesting/contributing code or content changes, it is wise to preview your change in a local build. We've tried to make the process of running a local build as low as possible.

Running a local build

Prerequisites

Installing and running the build

# Clone this repository to your local environment
git clone git@github.com:jamstack/jamstack.org.git

# move in to your local site folder
cd jamstack.org

# install the dependencies
npm install

# run the build and dev server locally
npm start

Styling with TailwindCSS

This site uses TailwindCSS to offer utility CSS classes and provide a rapid means to styling the site. This means that most styling can be done without writing any additional CSS. Instead, utility classes can be added directly to the HTML. This can provide some very rapid development and also offer surprising levels of familiarity for these used to working in this way (since the conventions and classes are not per site.)

While running/developing locally, the npm run start command will generate the site including the CSS pipeline from Tailwind.

Global CSS utilities.

A small number of bespoke CSS rules are provided for efficiency of repeated or global classes. These reside in src/css/tailwind.css but these should be used sparingly, with most styling taking place in the HTML via Tailwind's utility classes.

Dev vs prod

During a production build, the CSS pipeline includes a step to remove all unused CSS statements and compress the resultant CSS. For development efficiency, this step is not performed during local development via the npm run start command. You can preview an optimised production build by running these commands:


# Run a production build
npm run build

# Serve the build locally
npm run start

One-click clone and deploy

You can clone this repository and bootstrap it as a test site of your own, complete with the CI/CD build pipeline on Netlify by clicking the button below. (Requires free GitHub and Netlify accounts)

This is the repo for https://jamstack.org

Download Details:

Author: jamstack
Source Code: https://github.com/jamstack/jamstack.org 

#serverless #static #jamstack 

 Jamstack.org: The Official Jamstack Site
Rupert  Beatty

Rupert Beatty

1667598300

Tailor: Cross-platform Static analyzer and Linter for Swift

Tailor

Tailor is a cross-platform static analysis and lint tool for source code written in Apple's Swift programming language. It analyzes your code to ensure consistent styling and help avoid bugs.

Tailor. Cross-platform static analyzer and linter for Swift.

Tailor supports Swift 3.0.1 out of the box and helps enforce style guidelines outlined in the The Swift Programming Language, GitHub, Ray Wenderlich, and Coursera style guides. It supports cross-platform usage and can be run on Mac OS X via your shell or integrated with Xcode, as well as on Linux and Windows.

Tailor parses Swift source code using the primary Java target of ANTLR:

ANTLR is a powerful parser generator [ . . . ] widely used in academia and industry to build all sorts of languages, tools, and frameworks.

β€” About the ANTLR Parser Generator

Getting Started

Installation

Requires Java (JRE or JDK) Version 8 or above: Java SE Downloads

Homebrew, Linuxbrew

brew install tailor

Mac OS X (10.10+), Linux

curl -fsSL https://tailor.sh/install.sh | sh

Windows (10+)

iex (new-object net.webclient).downloadstring('https://tailor.sh/install.ps1')

Manually

You may also download Tailor via GitHub Releases, extract the archive, and symlink the tailor/bin/tailor shell script to a location in your $PATH.

Continuous Integration

If your continuous integration server supports Homebrew installation, you may use the following snippet:

before_install:
  - brew update
  - brew install tailor

In other cases, use this snippet:

Replace ${TAILOR_RELEASE_ARCHIVE} with the URL of the release you would like to install, e.g. https://github.com/sleekbyte/tailor/releases/download/v0.1.0/tailor.tar.

before_script:
  - wget ${TAILOR_RELEASE_ARCHIVE} -O /tmp/tailor.tar
  - tar -xvf /tmp/tailor.tar
  - export PATH=$PATH:$PWD/tailor/bin/

Usage

Run Tailor with a list of files and directories to analyze, or via Xcode.

$ tailor [options] [--] [[file|directory] ...]

Help for Tailor is accessible via the [-h|--help] option.

$ tailor -h
Usage: tailor [options] [--] [[file|directory] ...]

Perform static analysis on Swift source files.

Invoking Tailor with at least one file or directory will analyze all Swift files at those paths. If
no paths are provided, Tailor will analyze all Swift files found in '$SRCROOT' (if defined), which
is set by Xcode when run in a Build Phase. Tailor may be set up as an Xcode Build Phase
automatically with the --xcode option.

Options:
 -c,--config=<path/to/.tailor.yml>             specify configuration file
    --debug                                    print ANTLR error messages when parsing error occurs
    --except=<rule1,rule2,...>                 run all rules except the specified ones
 -f,--format=<xcode|json|cc|html>              select an output format
 -h,--help                                     display help
    --invert-color                             invert colorized console output
 -l,--max-line-length=<0-999>                  maximum Line length (in characters)
    --list-files                               display Swift source files to be analyzed
    --max-class-length=<0-999>                 maximum Class length (in lines)
    --max-closure-length=<0-999>               maximum Closure length (in lines)
    --max-file-length=<0-999>                  maximum File length (in lines)
    --max-function-length=<0-999>              maximum Function length (in lines)
    --max-name-length=<0-999>                  maximum Identifier name length (in characters)
    --max-severity=<error|warning (default)>   maximum severity
    --max-struct-length=<0-999>                maximum Struct length (in lines)
    --min-name-length=<1-999>                  minimum Identifier name length (in characters)
    --no-color                                 disable colorized console output
    --only=<rule1,rule2,...>                   run only the specified rules
    --purge=<1-999>                            reduce memory usage by clearing DFA cache after
                                               specified number of files are parsed
    --show-rules                               show description for each rule
 -v,--version                                  display version
    --xcode=<path/to/project.xcodeproj>        add Tailor Build Phase Run Script to Xcode Project

Features

Enabling and Disabling Rules

Rule identifiers and "preferred/not preferred" code samples may be found on the Rules page.

Rules may be individually disabled (blacklist) or enabled (whitelist) via the --except and --only command-line flags.

Except

tailor --except=brace-style,trailing-whitespace main.swift

Only

tailor --only=redundant-parentheses,terminating-semicolon main.swift

Cross-Platform

Tailor may be used on Mac OS X via your shell or integrated with Xcode, as well as on Linux and Windows.

Linux

Tailor on Ubuntu

Windows

Tailor on Windows

Automatic Xcode Integration

Tailor can be integrated with Xcode projects using the --xcode option.

tailor --xcode /path/to/demo.xcodeproj/

This adds the following Build Phase Run Script to your project's default target. Run Script

Tailor's output will be displayed inline within the Xcode Editor Area and as a list in the Log Navigator. Xcode messages

Configure Xcode to Analyze Code Natively (β‡§βŒ˜B)

Add a new configuration, say Analyze, to the project

screen shot 2016-11-30 at 12 29 34 am

Modify the active scheme's Analyze phase to use the new build configuration created above

screen shot 2016-11-30 at 12 37 08 am

Tweak the build phase run script to run Tailor only when analyzing the project (β‡§βŒ˜B)

if [ "${CONFIGURATION}" = "Analyze" ]; then
    if hash tailor 2>/dev/null; then
        tailor
    else
        echo "warning: Please install Tailor from https://tailor.sh"
    fi
fi

Colorized Output

Tailor uses the following color schemes to format CLI output:

Dark theme (enabled by default) Dark theme

Light theme (enabled via --invert-color option) Light theme

No color theme (enabled via --no-color option) No color

Warnings, Errors, and Failing the Build

--max-severity can be used to control the maximum severity of violation messages. It can be set to error or warning (by default, it is set to warning). Setting it to error allows you to distinguish between lower and higher priority messages. It also fails the build in Xcode, if any errors are reported (similar to how a compiler error fails the build in Xcode). With max-severity set to warning, all violation messages are warnings and the Xcode build will never fail.

This setting also affects Tailor's exit code on the command-line, a failing build will exit 1 whereas having warnings only will exit 0, allowing Tailor to be easily integrated into pre-commit hooks.

Disable Violations within Source Code

Violations on a specific line may be disabled with a trailing single-line comment.

import Foundation; // tailor:disable

Additionally, violations in a given block of code can be disabled by enclosing the block within tailor:off and tailor:on comments.

// tailor:off
import Foundation;
import UIKit;
import CoreData;
// tailor:on

class Demo() {
  // Define public members here
}

Note

  • // tailor:off and // tailor:on comments must be paired

Configuration

The behavior of Tailor can be customized via the .tailor.yml configuration file. It enables you to

  • include/exclude certain files and directories from analysis
  • enable and disable specific analysis rules
  • specify output format
  • specify CLI output color scheme

You can tell Tailor which configuration file to use by specifying its file path via the --config CLI option. By default, Tailor will look for the configuration file in the directory where you will run Tailor from.

The file follows the YAML 1.1 format.

Including/Excluding files

Tailor checks all files found by a recursive search starting from the directories given as command line arguments. However, it only analyzes Swift files that end in .swift. If you would like Tailor to analyze specific files and directories, you will have to add entries for them under include. Files and directories can also be ignored through exclude.

Here is an example that might be used for an iOS project:

include:
    - Source            # Inspect all Swift files under "Source/"
exclude:
    - '**Tests.swift'   # Ignore Swift files that end in "Tests"
    - Source/Carthage   # Ignore Swift files under "Source/Carthage/"
    - Source/Pods       # Ignore Swift files under "Source/Pods/"

Notes

  • Files and directories are specified relative to where tailor is run from
  • Paths to directories or Swift files provided explicitly via CLI will cause the include/exclude rules specified in .tailor.yml to be ignored
  • Exclude is given higher precedence than Include
  • Tailor recognizes the Java Glob syntax

Enabling/Disabling rules

Tailor allows you to individually disable (blacklist) or enable (whitelist) rules via the except and only labels.

Here is an example showcasing how to enable certain rules:

# Tailor will solely check for violations to the following rules
only:
    - upper-camel-case
    - trailing-closure
    - forced-type-cast
    - redundant-parentheses

Here is an example showcasing how to disable certain rules:

# Tailor will check for violations to all rules except for the following ones
except:
    - parenthesis-whitespace
    - lower-camel-case

Notes

  • only is given precedence over except
  • Rules that are explicitly included/excluded via CLI will cause the only/except rules specified in .tailor.yml to be ignored

Specifying output format

Tailor allows you to specify the output format (xcode/json) via the format label.

Here is an example showcasing how to specify the output format:

# The output format will now be in JSON
format: json

Note

  • The output format explicitly specified via CLI will cause the output format defined in .tailor.yml to be ignored

Specifying CLI output color scheme

Tailor allows you to specify the CLI output color schemes via the color label. To disable colored output, set color to disable. To invert the color scheme, set color to invert.

Here is an example showcasing how to specify the CLI output color scheme:

# The CLI output will not be colored
color: disable

Note

  • The CLI output color scheme explicitly specified via CLI will cause the output color scheme defined in .tailor.yml to be ignored

Formatters

Tailor's output format may be customized via the -f/--format option. The Xcode formatter is selected by default.

Xcode Formatter (default)

The default xcode formatter outputs violation messages according to the format expected by Xcode to be displayed inline within the Xcode Editor Area and as a list in the Log Navigator. This format is also as human-friendly as possible on the console.

$ tailor main.swift

********** /main.swift **********
/main.swift:1:    warning: [multiple-imports] Imports should be on separate lines
/main.swift:1:18: warning: [terminating-semicolon] Statements should not terminate with a semicolon
/main.swift:3:05: warning: [constant-naming] Global Constant should be either lowerCamelCase or UpperCamelCase
/main.swift:5:07: warning: [redundant-parentheses] Conditional clause should not be enclosed within parentheses
/main.swift:7:    warning: [terminating-newline] File should terminate with exactly one newline character ('\n')

Analyzed 1 file, skipped 0 files, and detected 5 violations (0 errors, 5 warnings).

JSON Formatter

The json formatter outputs an array of violation messages for each file, and a summary object indicating the parsing results and the violation counts.

$ tailor -f json main.swift
{
  "files": [
    {
      "path": "/main.swift",
      "violations": [
        {
          "severity": "warning",
          "rule": "constant-naming",
          "location": {
            "line": 1,
            "column": 5
          },
          "message": "Global Constant should be either lowerCamelCase or UpperCamelCase"
        }
      ],
      "parsed": true
    }
  ],
  "summary": {
    "violations": 1,
    "warnings": 1,
    "analyzed": 1,
    "errors": 0,
    "skipped": 0
  }
}

HTML Formatter

The html formatter outputs a complete HTML document that should be written to a file.

tailor -f html main.swift > tailor.html

HTML format

Developers

Please review the guidelines for contributing to this repository.

Development Environment

External Tools and Libraries

Development & Runtime

ToolLicense
ANTLR 4.5The BSD License
Apache Commons CLIApache License, Version 2.0
JansiApache License, Version 2.0
XcodeprojMIT
SnakeYAMLApache License, Version 2.0
GsonApache License, Version 2.0
Mustache.javaApache License, Version 2.0

Development Only

ToolLicense
GradleApache License, Version 2.0
Travis CIFree for Open Source Projects
MockitoMIT
JUnitEclipse Public License 1.0
Java HamcrestThe BSD 3-Clause License
FindBugsGNU Lesser General Public License
CheckstyleGNU Lesser General Public License
PMDBSD-style
JaCoCoEclipse Public License v1.0
CoverallsFree for Open Source
BundlerMIT
CodacyFree for Open Source
System RulesCommon Public License 1.0
RonnMIT

Download Details:

Author: Sleekbyte
Source Code: https://github.com/sleekbyte/tailor 
License: MIT license

#swift #apple #linter #static #analyzer 

Tailor: Cross-platform Static analyzer and Linter for Swift
Gordon  Matlala

Gordon Matlala

1667406120

Understand and Fix Your Static Website Trailing Slash Issues!

Trailing Slash Guide

Have trailing slash problems after deploying a static website in production?

This repo explains factually the behavior of:

We also suggest some possible solutions

Intro

Let's get more familiar with trailing slash issues.

Common problems:

  • SEO/perf issues: when browsing /myPath, your host redirects to /myPath/
  • 404 issues: relative link such as <a href="otherPath"> are resolved differently (/otherPath or /myPath/otherPath depending on the presence/absence of a trailing slash
  • UX issues: your host adds a trailing slash, and later your single-page-application frontend router removes it, leading to a confusing experience and flickering url

Causes:

  • static site generators can emit different files for the same path /myPath: /myPath.html or /myPath/index.html (the later can lead to an additional trailing slash)
  • host providers all have a different behavior when serving static files, there is no standard

Summary

Considering this static site:

static
β”‚
β”œβ”€β”€ file.html
β”‚
β”œβ”€β”€ folder
β”‚   └── index.html
β”‚
β”œβ”€β”€ both.html
└── both
    └── index.html

Behavior of various static hosting providers:

HostSettingsUrl/file/file//file.html/folder/folder//folder/index.html/both/both//both.html/both/index.html
GitHub Pages linkβœ…πŸ’’ 404βœ…βž‘οΈ /folder/βœ…βœ…βœ…βœ…βœ…βœ…
NetlifyDefaultlinkβœ…βž‘οΈ /fileβœ…βž‘οΈ /folder/βœ…βœ…βœ…βž‘οΈ /bothβœ…βœ…
NetlifyPretty Urls onlinkβœ…βž‘οΈ /fileβœ…βž‘οΈ /folder/βœ…βœ…βœ…βž‘οΈ /bothβœ…βœ…
NetlifyPretty Urls offlinkβœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…
VercelDefaultlinkπŸ’’ 404πŸ’’ 404βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…
VercelcleanUrls=false trailingSlash=undefinedlinkπŸ’’ 404πŸ’’ 404βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…
VercelcleanUrls=false trailingSlash=falselinkπŸ’’ 404πŸ’’ 404βœ…βœ…βž‘οΈ /folderβœ…βœ…βž‘οΈ /bothβœ…βœ…
VercelcleanUrls=false trailingSlash=truelinkπŸ’’ 404πŸ’’ 404βœ…βž‘οΈ /folder/βœ…βœ…βž‘οΈ /both/βœ…βœ…βœ…
VercelcleanUrls=true trailingSlash=undefinedlinkπŸ’’ 404πŸ’’ 404βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…
VercelcleanUrls=true trailingSlash=falselinkβœ…βž‘οΈ /file➑️ /fileβœ…βž‘οΈ /folder➑️ /folderβœ…βž‘οΈ /both➑️ /both➑️ /both
VercelcleanUrls=true trailingSlash=truelink➑️ /file/βœ…βž‘οΈ /file/➑️ /folder/βœ…βž‘οΈ /folder/➑️ /both/βœ…βž‘οΈ /both/➑️ /both/
Cloudflare Pages linkβœ…βž‘οΈ /file➑️ /file➑️ /folder/βœ…βž‘οΈ /folder/βœ…βœ…βž‘οΈ /both➑️ /both/
Render linkβœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…
Azure Static Web Apps linkβœ…βž‘οΈ /fileβœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…

Help Wanted

Let's keep this resource up-to-date, and make it exhaustive together.

Download Details:

Author: Slorber
Source Code: https://github.com/slorber/trailing-slash-guide 
License: MIT license

#jekyll #react #generator #nextjs #static 

Understand and Fix Your Static Website Trailing Slash Issues!
Rupert  Beatty

Rupert Beatty

1666232580

PMD: An Extensible Multilanguage Static Code Analyzer

PMD - source code analyzer

PMD is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation, and so forth. It supports many languages. It can be extended with custom rules. It uses JavaCC and Antlr to parse source files into abstract syntax trees (AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query.

It supports Java, JavaScript, Salesforce.com Apex and Visualforce, Modelica, PLSQL, Apache Velocity, XML, XSL, Scala.

Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code in C/C++, C#, Dart, Fortran, Go, Groovy, Java, JavaScript, JSP, Kotlin, Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex, Scala, Swift, Visualforce and XML.

In the future we hope to add support for data/control flow analysis and automatic (quick) fixes where it makes sense.

πŸš€ Installation and Usage

Download the latest binary zip from the releases and extract it somewhere.

Execute bin/run.sh pmd or bin\pmd.bat.

See also Getting Started

Demo:

This shows how PMD can detect for loops, that can be replaced by for-each loops.

Demo

There are plugins for Maven and Gradle as well as for various IDEs. See Tools / Integrations

ℹ️ How to get support?

🀝 Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Our latest source of PMD can be found on GitHub. Fork us!

The rule designer is developed over at pmd/pmd-designer. Please see its README for developer documentation.

πŸ’΅ Financial Contributors

Become a financial contributor and help us sustain our community. Contribute

✨ Contributors

This project follows the all-contributors specification. Contributions of any kind welcome!

See credits for the complete list.

Download Details:

Author: pmd
Source Code: https://github.com/pmd/pmd 
License: View license

#swift #java #static #code #analysis 

PMD: An Extensible Multilanguage Static Code Analyzer
Gordon  Matlala

Gordon Matlala

1665851160

Staticman: User-generated Content for Git-powered Websites

Staticman

Static sites with superpowers

Introduction

Staticman is a Node.js application that receives user-generated content and uploads it as data files to a GitHub and/or GitLab repository. In practice, this allows you to have dynamic content (e.g. blog post comments) as part of a fully static website, as long as your site automatically deploys on every push to GitHub and/or GitLab, as seen on GitHub Pages, GitLab Pages, Netlify and others.

It consists of a small web service that handles the POST requests from your forms, runs various forms of validation and manipulation defined by you and finally pushes them to your repository as data files. You can choose to enable moderation, which means files will be pushed to a separate branch and a pull request will be created for your approval, or disable it completely, meaning that files will be pushed to the main branch automatically.

You can download and run the Staticman API on your own infrastructure. The easiest way to get a personal Staticman API instance up and running is to use the free tier of Heroku. If deploying to Heroku you can simply click the button below and enter your config variables directly into Heroku as environment variables.

Requirements

  • Node.js 8.11.3+
  • npm
  • A personal access token for the GitHub and/or GitLab account you want to run Staticman with
  • An RSA key in PEM format

Setting up the server on your own infrastructure

NOTE: The below steps are not required if deploying to Heroku. To deploy to Heroku, click the above deploy button and enter your configuration variables in the Heroku Dashboard.

Clone the repository and install the dependencies via npm.

git clone git@github.com:eduardoboucas/staticman.git
cd staticman
npm install

Create a development config file from the sample file.

cp config.sample.json config.development.json

Edit the newly-created config file with your GitHub and/or GitLab access token, SSH private key and the port to run the server. Click here for the list of available configuration parameters.

Start the server.

npm start

Each environment, determined by the NODE_ENV environment variable, requires its own configuration file. When you're ready to push your Staticman API live, create a config.production.json file before deploying.

Check this guide if you're using Docker.

Setting up a repository

Staticman runs as a bot using a GitHub and/or GitLab account, as opposed to accessing your account using the traditional OAuth flow. This means that you can give it access to just the repositories you're planning on using it on, instead of exposing all your repositories.

To add Staticman to a repository, you need to add the bot as a collaborator with write access to the repository and ask the bot to accept the invite by firing a GET request to this URL:

http://your-staticman-url/v2/connect/GITHUB-USERNAME/GITHUB-REPOSITORY

Site configuration

Staticman will look for a config file. For the deprecated v1 endpoints, this is a _config.yml with a staticman property inside; for v2 endpoints, Staticman looks for a staticman.yml file at the root of the repository.

For a list of available configuration parameters, please refer to the documentation page.

Development

Would you like to contribute to Staticman? That's great! Here's how:

  1. Read the contributing guidelines
  2. Pull the repository and start hacking
  3. Make sure tests are passing by running npm test
  4. Send a pull request and celebrate

Useful links

Download Details:

Author: Eduardoboucas
Source Code: https://github.com/eduardoboucas/staticman 
License: MIT license

#jekyll #static #generator #hugo 

Staticman: User-generated Content for Git-powered Websites

Phan: A Static analyzer for PHP

Phan is a static analyzer for PHP that prefers to minimize false-positives. Phan attempts to prove incorrectness rather than correctness.

Phan looks for common issues and will verify type compatibility on various operations when type information is available or can be deduced. Phan has a good (but not comprehensive) understanding of flow control and can track values in a few use cases (e.g. arrays, integers, and strings).

Getting Started

The easiest way to use Phan is via Composer.

composer require phan/phan

With Phan installed, you'll want to create a .phan/config.php file in your project to tell Phan how to analyze your source code. Once configured, you can run it via ./vendor/bin/phan.

Phan depends on PHP 7.2+ with the php-ast extension (1.0.10+ is preferred) and supports analyzing PHP version 7.0-7.4 syntax. Installation instructions for php-ast can be found here. (Phan can be used without php-ast by using the CLI option --allow-polyfill-parser, but there are slight differences in the parsing of doc comments)

  • Alternative Installation Methods
    See Getting Started for alternative methods of using Phan and details on how to configure Phan for your project.
     
  • Incrementally Strengthening Analysis
    Take a look at Incrementally Strengthening Analysis for some tips on how to slowly ramp up the strictness of the analysis as your code becomes better equipped to be analyzed. 
     
  • Installing Dependencies
    Take a look at Installing Phan Dependencies for help getting Phan's dependencies installed on your system.

The Wiki has more information about using Phan.

Features

Phan is able to perform the following kinds of analysis:

  • Check that all methods, functions, classes, traits, interfaces, constants, properties and variables are defined and accessible.
  • Check for type safety and arity issues on method/function/closure calls.
  • Check for PHP7/PHP5 backward compatibility.
  • Check for features that weren't supported in older PHP 7.x minor releases (E.g. object, void, iterable, ?T, [$x] = ...;, negative string offsets, multiple exception catches, etc.)
  • Check for sanity with array accesses.
  • Check for type safety on binary operations.
  • Check for valid and type safe return values on methods, functions, and closures.
  • Check for No-Ops on arrays, closures, constants, properties, variables, unary operators, and binary operators.
  • Check for unused/dead/unreachable code. (Pass in --dead-code-detection)
  • Check for unused variables and parameters. (Pass in --unused-variable-detection)
  • Check for redundant or impossible conditions and pointless casts. (Pass in --redundant-condition-detection)
  • Check for unused use statements. These and a few other issue types can be automatically fixed with --automatic-fix.
  • Check for classes, functions and methods being redefined.
  • Check for sanity with class inheritance (e.g. checks method signature compatibility). Phan also checks for final classes/methods being overridden, that abstract methods are implemented, and that the implemented interface is really an interface (and so on).
  • Supports namespaces, traits and variadics.
  • Supports Union Types.
  • Supports Generic Types (i.e. @template).
  • Supports generic arrays such as int[], UserObject[], array<int,UserObject>, etc..
  • Supports array shapes such as array{key:string,otherKey:?stdClass}, etc. (internally and in PHPDoc tags) This also supports indicating that fields of an array shape are optional via array{requiredKey:string,optionalKey?:string} (useful for @param)
  • Supports phpdoc type annotations.
  • Supports inheriting phpdoc type annotations.
  • Supports checking that phpdoc type annotations are a narrowed form (E.g. subclasses/subtypes) of the real type signatures
  • Supports inferring types from assert() statements and conditionals in if elements/loops.
  • Supports @deprecated annotation for deprecating classes, methods and functions
  • Supports @internal annotation for elements (such as a constant, function, class, class constant, property or method) as internal to the package in which it's defined.
  • Supports @suppress <ISSUE_TYPE> annotations for suppressing issues.
  • Supports magic @property annotations (@property <union_type> <variable_name>)
  • Supports magic @method annotations (@method <union_type> <method_name>(<union_type> <param1_name>))
  • Supports class_alias annotations (experimental, off by default)
  • Supports indicating the class to which a closure will be bound, via @phan-closure-scope (example)
  • Supports analysis of closures and return types passed to array_map, array_filter, and other internal array functions.
  • Offers extensive configuration for weakening the analysis to make it useful on large sloppy code bases
  • Can be run on many cores. (requires pcntl)
  • Output is emitted in text, checkstyle, json, pylint, csv, or codeclimate formats.
  • Can run user plugins on source for checks specific to your code. Phan includes various plugins you may wish to enable for your project.

See Phan Issue Types for descriptions and examples of all issues that can be detected by Phan. Take a look at the \Phan\Issue to see the definition of each error type.

Take a look at the Tutorial for Analyzing a Large Sloppy Code Base to get a sense of what the process of doing ongoing analysis might look like for you.

Phan can be used from various editors and IDEs for its error checking, "go to definition" support, etc. via the Language Server Protocol. Editors and tools can also request analysis of individual files in a project using the simpler Daemon Mode.

See the tests directory for some examples of the various checks.

Phan is imperfect and shouldn't be used to prove that your PHP-based rocket guidance system is free of defects.

Features provided by plugins

Additional analysis features have been provided by plugins.

Example: Phan's plugins for self-analysis.

Usage

After installing Phan, Phan needs to be configured with details on where to find code to analyze and how to analyze it. The easiest way to tell Phan where to find source code is to create a .phan/config.php file. A simple .phan/config.php file might look something like the following.

<?php

/**
 * This configuration will be read and overlaid on top of the
 * default configuration. Command line arguments will be applied
 * after this file is read.
 */
return [

    // Supported values: `'5.6'`, `'7.0'`, `'7.1'`, `'7.2'`, `'7.3'`, `'7.4'`, `null`.
    // If this is set to `null`,
    // then Phan assumes the PHP version which is closest to the minor version
    // of the php executable used to execute Phan.
    "target_php_version" => null,

    // A list of directories that should be parsed for class and
    // method information. After excluding the directories
    // defined in exclude_analysis_directory_list, the remaining
    // files will be statically analyzed for errors.
    //
    // Thus, both first-party and third-party code being used by
    // your application should be included in this list.
    'directory_list' => [
        'src',
        'vendor/symfony/console',
    ],

    // A directory list that defines files that will be excluded
    // from static analysis, but whose class and method
    // information should be included.
    //
    // Generally, you'll want to include the directories for
    // third-party code (such as "vendor/") in this list.
    //
    // n.b.: If you'd like to parse but not analyze 3rd
    //       party code, directories containing that code
    //       should be added to the `directory_list` as
    //       to `exclude_analysis_directory_list`.
    "exclude_analysis_directory_list" => [
        'vendor/'
    ],

    // A list of plugin files to execute.
    // Plugins which are bundled with Phan can be added here by providing their name
    // (e.g. 'AlwaysReturnPlugin')
    //
    // Documentation about available bundled plugins can be found
    // at https://github.com/phan/phan/tree/master/.phan/plugins
    //
    // Alternately, you can pass in the full path to a PHP file
    // with the plugin's implementation (e.g. 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php')
    'plugins' => [
        // checks if a function, closure or method unconditionally returns.
        // can also be written as 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php'
        'AlwaysReturnPlugin',
        'DollarDollarPlugin',
        'DuplicateArrayKeyPlugin',
        'DuplicateExpressionPlugin',
        'PregRegexCheckerPlugin',
        'PrintfCheckerPlugin',
        'SleepCheckerPlugin',
        // Checks for syntactically unreachable statements in
        // the global scope or function bodies.
        'UnreachableCodePlugin',
        'UseReturnValuePlugin',
        'EmptyStatementListPlugin',
        'LoopVariableReusePlugin',
    ],
];

Take a look at Creating a Config File and Incrementally Strengthening Analysis for more details.

Running phan --help will show usage information and command-line options.

Annotating Your Source Code

Phan reads and understands most PHPDoc type annotations including Union Types (like int|MyClass|string|null) and generic array types (like int[] or string[]|MyClass[] or array<int,MyClass>).

Take a look at Annotating Your Source Code and About Union Types for some help getting started with defining types in your code.

Phan supports (int|string)[] style annotations, and represents them internally as int[]|string[] (Both annotations are treated like array which may have integers and/or strings). When you have arrays of mixed types, just use array.

The following code shows off the various annotations that are supported.

/**
 * @return void
 */
function f() {}

/** @deprecated */
class C {
    /** @var int */
    const C = 42;

    /** @var string[]|null */
    public $p = null;

    /**
     * @param int|null $p
     * @return string[]|null
     */
    public static function f($p) {
        if (is_null($p)) {
            return null;
        }

        return array_map(
            /** @param int $i */
            function($i) {
                return "thing $i";
            },
            range(0, $p)
        );
    }
}

Just like in PHP, any type can be nulled in the function declaration which also means a null is allowed to be passed in for that parameter.

Phan checks the type of every single element of arrays (Including keys and values). In practical terms, this means that [$int1=>$int2,$int3=>$int4,$int5=>$str6] is seen as array<int,int|string>, which Phan represents as array<int,int>|array<int,string>. [$strKey => new MyClass(), $strKey2 => $unknown] will be represented as array<string,MyClass>|array<string,mixed>.

  • Literals such as [12,'myString'] will be represented internally as array shapes such as array{0:12,1:'myString'}

Generating a file list

This static analyzer does not track includes or try to figure out autoloader magic. It treats all the files you throw at it as one big application. For code encapsulated in classes this works well. For code running in the global scope it gets a bit tricky because order matters. If you have an index.php including a file that sets a bunch of global variables and you then try to access those after the include(...) in index.php the static analyzer won't know anything about these.

In practical terms this simply means that you should put your entry points and any files setting things in the global scope at the top of your file list. If you have a config.php that sets global variables that everything else needs, then you should put that first in the list followed by your various entry points, then all your library files containing your classes.

Development

Take a look at Developer's Guide to Phan for help getting started hacking on Phan.

When you find an issue, please take the time to create a tiny reproducing code snippet that illustrates the bug. And once you have done that, fix it. Then turn your code snippet into a test and add it to tests then ./test and send a PR with your fix and test. Alternatively, you can open an Issue with details.

To run Phan's unit tests, just run ./test.

To run all of Phan's unit tests and integration tests, run ./tests/run_all_tests.sh

Code of Conduct

We are committed to fostering a welcoming community. Any participant and contributor is required to adhere to our Code of Conduct.

Online Demo

This requires an up to date version of Firefox/Chrome and at least 4 GB of free RAM. (this is a 10 MB download)

Run Phan entirely in your browser.

Preview of analyzing PHP

Download Details:

Author: Phan
Source Code: https://github.com/phan/phan 
License: Unknown and 3 other licenses found

#php #analysis #static

Phan: A Static analyzer for PHP

AnimatedPlots.jl: Fast Animated (and Static) Plots for Julia

AnimatedPlots

Animated plots is a package for making animated and static plots. It is built on top of [SFML.jl] (zyedidia/SFML.jl) and allows for fast plotting of functions and variables over time.

Installation

Make sure you have SFML and CSFML installed (see the SFML [installation instructions] (zyedidia/SFML.jl#installation) for more information)

julia> Pkg.clone("https://github.com/zyedidia/AnimatedPlots.jl")

Usage

The easiest way to plot a function is to use the plot function:

Static Plots

julia> plot(sin)
julia> close(current_window())

A StaticGraph object can also be passed to plot if you want to be able to modify the graph afterward (such as changing the color or line thickness)

julia> sin_graph = StaticGraph(sin, thickness=5, color=SFML.blue) # thickness and color
julia> plot(sin_graph)
julia> sin_graph.color = SFML.green
julia> plot(cos)
julia> close(current_window())

Animated Plots

You can use the AnimatedGraph to make animated plots.

julia> animated_sin = AnimatedGraph(sin)
julia> plot(animated_sin)
julia> animated_cos = AnimatedGraph(cos, color=SFML.blue, startx=-10)
julia> animated_cos.speed = 3 # Speed in units per second
julia> plot(animated_cos)
julia> follow(animated_cos) # have the camera follow the plot

See examples/double_pendulum.jl for an advanced showcase of how to integrate an animated plot into an SFML application

Output

AnimatedPlots supports creating images and gifs of your plots. Creating gifs may take a while, only close your program after it says Created gif file.gif. In addition, you must have [imagemagick] (http://www.imagemagick.org/script/binary-releases.php) installed in order to make gifs (most package managers provide it).

julia> screenshot("my_screenshot.png") # Take a screenshot and save it to my_screenshot.png
julia> make_gif(300, 300, 10, "MyGif.gif", 0.06) # Create a gif with width, height, duration (in seconds), filename, and delay (the delay between each frame in seconds)

Download Details:

Author: Zyedidia
Source Code: https://github.com/zyedidia/AnimatedPlots.jl 
License: View license

#julia #animation #static 

AnimatedPlots.jl: Fast Animated (and Static) Plots for Julia

10 Popular PHP Libraries for Static Analysis

In today's post we will learn about 10 Popular PHP Libraries for Static Analysis.

What is Static Analysis?

Static analysis is a method of debugging that is done by automatically examining the source code without having to execute the program. This provides developers with an understanding of their code base and helps ensure that it is compliant, safe, and secure.

Table of contents:

  • Exakat - A static analysis engine for PHP.
  • Deptrac - A static code analysis tool that helps to enforce rules for dependencies between software layers.
  • Mondrian - A code analysis tool using Graph Theory.
  • Phan - A static analyzer based on PHP 7+ and the php-ast extension.
  • PHP Architecture Tester - Easy to use architecture testing tool for PHP.
  • PHPCompatibility - A PHP compatibility checker for PHP CodeSniffer.
  • PHPDependencyAnalysis - A tool to create customisable dependency graphs.
  • PHP Metrics - A static metric library.
  • PHP Migration - A static analyzer for PHP version migration.
  • PHPStan - A PHP Static Analysis Tool.
  • Psalm - A static analysis tool for finding errors in PHP applications.

1 - Exakat:

A static analysis engine for PHP.

The Exakat Engine is an automated code reviewing engine for PHP.

Installation

Quick installation

Copy-paste the following code in your terminal. This was tester on OSX and Linux-debian.

mkdir exakat
cd exakat
curl -o exakat.phar https://www.exakat.io/versions/index.php?file=latest
curl -o apache-tinkerpop-gremlin-server-3.4.12-bin.zip https://www.exakat.io/versions/apache-tinkerpop-gremlin-server-3.4.12-bin.zip
unzip apache-tinkerpop-gremlin-server-3.4.12-bin.zip
mv apache-tinkerpop-gremlin-server-3.4.12 tinkergraph
rm -rf apache-tinkerpop-gremlin-server-3.4.12-bin.zip

# Optional : install neo4j engine.
cd tinkergraph
./bin/gremlin-server.sh install org.apache.tinkerpop neo4j-gremlin 3.4.12
cd ..

php exakat.phar doctor

Installation with the phar

Phar is the recommended installation process.

The Exakat engine is distributed as a phar archive. Phar contains all the needed PHP code to run it.

The rest of the installation (Gremlin-server) is detailled in the installation documentation.

The quick installation guide is the following (command line, MacOS. See docs for more options):

mkdir exakat
cd exakat
curl -o exakat.phar https://www.exakat.io/versions/index.php?file=latest
curl -o apache-tinkerpop-gremlin-server-3.4.12-bin.zip https://www.exakat.io/versions/apache-tinkerpop-gremlin-server-3.4.12-bin.zip
unzip apache-tinkerpop-gremlin-server-3.4.12-bin.zip
mv apache-tinkerpop-gremlin-server-3.4.12 tinkergraph
rm -rf apache-tinkerpop-gremlin-server-3.4.12-bin.zip

# Optional : install neo4j engine.
cd tinkergraph
./bin/gremlin-server.sh install org.apache.tinkerpop neo4j-gremlin 3.4.12
cd ..

php exakat.phar doctor

Installation with docker

The docker usage is detailled in the installation documentation.

docker pull exakat/exakat:latest

View on Github

2 - Deptrac:

A static code analysis tool that helps to enforce rules for dependencies between software layers.

Deptrac is a static code analysis tool for PHP that helps you communicate, visualize and enforce architectural decisions in your projects. You can freely define your architectural layers over classes and which rules should apply to them.

For example, you can use Deptrac to ensure that bundles/modules/extensions in your project are truly independent of each other to make them easier to reuse.

Deptrac can be used in a CI pipeline to make sure a pull request does not violate any of the architectural rules you defined. With the optional Graphviz formatter you can visualize your layers, rules and violations.

Getting Started

You can install Deptrac via Composer. We recommend using the deptrac-shim package for this:

composer require --dev qossmic/deptrac-shim

Alternatively, you can also use Phive or download the binary attached to each release on GitHub. We strongly advise against using the deptrac package directly as a composer dependency. We update dependencies regularly, which might cause disruptions in your project.

Once you have downloaded the phar file, you will need to create a configuration file, where you define your layers and communication ruleset. When you have this file, you can analyse your code by running the analyse command:

php deptrac.phar

# which is equivalent to
php deptrac.phar analyse --config-file=deptrac.yaml

In order to run Deptrac you need at least PHP 8.1.

You can analyse projects that require an older PHP version as long as nikic/php-parser can parse it.

Contribute

Deptrac is in active development. We are looking for your suggestions and help to make it better.

Feel free to open an issue if you encounter bugs, have suggestions or would like to add a new feature to Deptrac.

Please feel free to improve this documentation, fix bugs, or work on a suggested feature by making a pull request on GitHub. Don't hesitate to ask for support, if you need help at any point.

The Contribution Guide in the documentation contains some advice for making a pull request with code changes.

Code of Conduct

If you are professional and polite then everything will be alright.

Please don't be inconsiderate or mean, or anything in between.

View on Github

3 - Mondrian:

A code analysis tool using Graph Theory.

Ok guyz, you have a master degree in Graph Theory, you follow Law of Demeter and you live on S.O.L.I.D principles ?

Let's have some Fun ! (^Ο‰^)

Getting started

Download the PHAR : mondrian.phar

Try to run a simple command with a few files (or a small part of a project)

$ mondrian.phar digraph /home/dev/project

This command produces a DOT file for GraphViz. Other formats are available :

  • html : interactive graph with the d3.js awesome library
  • svg : open standard for vector graphics (requires GraphViz)
  • json : format for d3.js for example

Example with html format

$ php mondrian.php d --ignore=tests --ignore=vendor --format=html ./MyPhpProject/

html-report

Note: The generated html file does not require any dependencies nor a connection.

Ecosystem

Running unit tests with PHPUnit

$ phpunit.phar

Building the documentation with phpDocumentor

$ phpDocumentor.phar

Building mondrian.phar from the sources with box2

$ box.phar b

View on Github

3 - Phan:

A static analyzer based on PHP 7+ and the php-ast extension.

Phan is a static analyzer for PHP that prefers to minimize false-positives. Phan attempts to prove incorrectness rather than correctness.

Phan looks for common issues and will verify type compatibility on various operations when type information is available or can be deduced. Phan has a good (but not comprehensive) understanding of flow control and can track values in a few use cases (e.g. arrays, integers, and strings).

Getting Started

The easiest way to use Phan is via Composer.

composer require phan/phan

With Phan installed, you'll want to create a .phan/config.php file in your project to tell Phan how to analyze your source code. Once configured, you can run it via ./vendor/bin/phan.

Phan 5 depends on PHP 7.2+ with the php-ast extension (1.0.16+ is preferred) and supports analyzing PHP version 7.0-8.1 syntax. Installation instructions for php-ast can be found here. (Phan can be used without php-ast by using the CLI option --allow-polyfill-parser, but there are slight differences in the parsing of doc comments)

  • Alternative Installation Methods
    See Getting Started for alternative methods of using Phan and details on how to configure Phan for your project.
     
  • Incrementally Strengthening Analysis
    Take a look at Incrementally Strengthening Analysis for some tips on how to slowly ramp up the strictness of the analysis as your code becomes better equipped to be analyzed.
     
  • Installing Dependencies
    Take a look at Installing Phan Dependencies for help getting Phan's dependencies installed on your system.

The Wiki has more information about using Phan.

Features

Phan is able to perform the following kinds of analysis:

  • Check that all methods, functions, classes, traits, interfaces, constants, properties and variables are defined and accessible.
  • Check for type safety and arity issues on method/function/closure calls.
  • Check for PHP8/PHP7/PHP5 backward compatibility.
  • Check for features that weren't supported in older PHP 7.x minor releases (E.g. object, void, iterable, ?T, [$x] = ...;, negative string offsets, multiple exception catches, etc.)
  • Check for sanity with array accesses.
  • Check for type safety on binary operations.
  • Check for valid and type safe return values on methods, functions, and closures.
  • Check for No-Ops on arrays, closures, constants, properties, variables, unary operators, and binary operators.
  • Check for unused/dead/unreachable code. (Pass in --dead-code-detection)
  • Check for unused variables and parameters. (Pass in --unused-variable-detection)
  • Check for redundant or impossible conditions and pointless casts. (Pass in --redundant-condition-detection)
  • Check for unused use statements. These and a few other issue types can be automatically fixed with --automatic-fix.
  • Check for classes, functions and methods being redefined.
  • Check for sanity with class inheritance (e.g. checks method signature compatibility). Phan also checks for final classes/methods being overridden, that abstract methods are implemented, and that the implemented interface is really an interface (and so on).
  • Supports namespaces, traits and variadics.
  • Supports Union Types.
  • Supports Generic Types (i.e. @template).
  • Supports generic arrays such as int[], UserObject[], array<int,UserObject>, etc..
  • Supports array shapes such as array{key:string,otherKey:?stdClass}, etc. (internally and in PHPDoc tags) This also supports indicating that fields of an array shape are optional via array{requiredKey:string,optionalKey?:string} (useful for @param)
  • Supports phpdoc type annotations.
  • Supports inheriting phpdoc type annotations.
  • Supports checking that phpdoc type annotations are a narrowed form (E.g. subclasses/subtypes) of the real type signatures
  • Supports inferring types from assert() statements and conditionals in if elements/loops.
  • Supports @deprecated annotation for deprecating classes, methods and functions
  • Supports @internal annotation for elements (such as a constant, function, class, class constant, property or method) as internal to the package in which it's defined.
  • Supports @suppress <ISSUE_TYPE> annotations for suppressing issues.
  • Supports magic @property annotations (@property <union_type> <variable_name>)
  • Supports magic @method annotations (@method <union_type> <method_name>(<union_type> <param1_name>))
  • Supports class_alias annotations (experimental, off by default)
  • Supports indicating the class to which a closure will be bound, via @phan-closure-scope (example)
  • Supports analysis of closures and return types passed to array_map, array_filter, and other internal array functions.
  • Offers extensive configuration for weakening the analysis to make it useful on large sloppy code bases
  • Can be run on many cores. (requires pcntl)
  • Output is emitted in text, checkstyle, json, pylint, csv, or codeclimate formats.
  • Can run user plugins on source for checks specific to your code. Phan includes various plugins you may wish to enable for your project.

View on Github

4 - PHP Architecture Tester:

Easy to use architecture testing tool for PHP.

Introduction πŸ“œ

PHP Architecture Tester is a static analysis tool to verify architectural requirements.

It provides a natural language abstraction to define your own architectural rules and test them against your software. You can also integrate phpat easily into your toolchain.

There are four groups of supported assertions: Dependency, Inheritance, Composition and Mixin.

ℹ️ Check out the section WHAT TO TEST to see some examples of typical use cases.

Installation πŸ’½

Just require phpat with Composer:

composer require --dev phpat/phpat

Manual download
 

If you have dependency conflicts, you can also download the latest PHAR file from Releases.

You will have to use it executing php phpat.phar phpat.yaml and declare your tests in XML or YAML.

Configuration πŸ”§

You will need to setup a minimum configuration:

# phpat.yaml
src:
  path: src/
tests:
  path: tests/architecture/

Complete list of options
 

NameDescriptionDefault
src pathThe root path of your applicationno default
src includeFiles you want to be tested excluding the restall files
src excludeFiles you want to be excluded in the testsno files
composer $ALIAS jsonPath of your composer.json file (multiple)main json
composer $ALIAS lockPath of your composer.lock file (multiple)main lock
tests pathThe path where your tests areno default
tests baselinePath to a generated baseline fileno default
options verbosityOutput verbosity level (-1/0/1/2)0
options php-versionPHP version of the src code (x.x.x)PHP_VERSION
options ignore-docblocksIgnore relations on docblocks (T/F)false
options ignore-php-extensionsIgnore relations to core and extensions classes (T/F)true
--generate-baselineOption to generate a json baseline file (null/filename)false

View on Github

5 - PHPCompatibility:

A PHP compatibility checker for PHP CodeSniffer.

Installation in a Composer project (method 1)

  • Add the following lines to the require-dev section of your composer.json file.
"require-dev": {
    "phpcompatibility/php-compatibility": "*"
},
"prefer-stable" : true
  • Next, PHP CodeSniffer has to be informed of the location of the standard.

If PHPCompatibility is the only external PHP CodeSniffer standard you use, you can add the following to your composer.json file to automatically run the necessary command:

"scripts": {
    "post-install-cmd": "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility",
    "post-update-cmd" : "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility"
}

Alternatively - and strongly recommended if you use more than one external PHP CodeSniffer standard - you can use any of the following Composer plugins to handle this for you.

Just add the Composer plugin you prefer to the require-dev section of your composer.json file.

As a last alternative in case you use a custom ruleset, and only if you use PHP CodeSniffer version 2.6.0 or higher, you can tell PHP CodeSniffer the path to the PHPCompatibility standard by adding the following snippet to your custom ruleset:

<config name="installed_paths" value="vendor/phpcompatibility/php-compatibility" />
  • Run composer update --lock to install both PHP CodeSniffer, the PHPCompatibility coding standard and - optionally - the Composer plugin.
  • Verify that the PHPCompatibility standard is registered correctly by running ./vendor/bin/phpcs -i on the command line. PHPCompatibility should be listed as one of the available standards.
  • Now you can use the following command to inspect your code:
./vendor/bin/phpcs -p . --standard=PHPCompatibility

Installation via a git check-out to an arbitrary directory (method 2)

Install PHP CodeSniffer via your preferred method.

PHP CodeSniffer offers a variety of installation methods to suit your work-flow: Composer, PEAR, a Phar file, zipped/tarred release archives or checking the repository out using Git.

Pro-tip: Register the path to PHPCS in your system $PATH environment variable to make the phpcs command available from anywhere in your file system.

Download the latest PHPCompatibility release and unzip/untar it into an arbitrary directory.

You can also choose to clone the repository using git to easily update your install regularly.

Add the path to the directory in which you placed your copy of the PHPCompatibility repo to the PHP CodeSniffer configuration using the below command from the command line:

phpcs --config-set installed_paths /path/to/PHPCompatibility

I.e. if you placed the PHPCompatibility repository in the /my/custom/standards/PHPCompatibility directory, you will need to add that directory to the PHP CodeSniffer installed_paths configuration variable.

Warning: ⚠️ The installed_paths command overwrites any previously set installed_paths. If you have previously set installed_paths for other external standards, run phpcs --config-show first and then run the installed_paths command with all the paths you need separated by commas, i.e.:

phpcs --config-set installed_paths /path/1,/path/2,/path/3

Pro-tip: Alternatively, in case you use a custom ruleset and only if you use PHP CodeSniffer version 2.6.0 or higher, you can tell PHP CodeSniffer the path to the PHPCompatibility standard(s) by adding the following snippet to your custom ruleset:

<config name="installed_paths" value="/path/to/PHPCompatibility" />

Verify that the PHPCompatibility standard is registered correctly by running phpcs -i on the command line. PHPCompatibility should be listed as one of the available standards.

Now you can use the following command to inspect your code:

phpcs -p . --standard=PHPCompatibility

Using a custom ruleset

Like with any PHP CodeSniffer standard, you can add PHPCompatibility to a custom PHP CodeSniffer ruleset.

<?xml version="1.0"?>
<ruleset name="Custom ruleset">
    <description>My rules for PHP CodeSniffer</description>

    <!-- Run against the PHPCompatibility ruleset -->
    <rule ref="PHPCompatibility"/>

    <!-- Run against a second ruleset -->
    <rule ref="PSR2"/>

</ruleset>

You can also set the testVersion from within the ruleset:

    <!-- Check for cross-version support for PHP 5.6 and higher. -->
    <config name="testVersion" value="5.6-"/>

Other advanced options, such as changing the message type or severity of select sniffs, as described in the PHPCS Annotated ruleset wiki page are, of course, also supported.

testVersion in the ruleset versus command-line

In PHPCS 3.2.0 and lower, once you set the testVersion in the ruleset, you could not overrule it from the command-line anymore. Starting with PHPCS 3.3.0, a testVersion set via the command-line will overrule the testVersion in the ruleset.

This allows for more flexibility when, for instance, your project needs to comply with PHP 5.5-, but you have a bootstrap file which needs to be compatible with PHP 5.2-.

View on Github

6 - PHPDependencyAnalysis:

A tool to create customisable dependency graphs.

PhpDependencyAnalysis is an extendable static code analysis for object-oriented PHP-Projects to generate dependency graphs from abstract datatypes (Classes, Interfaces and Traits) based on namespaces. Dependencies can be aggregated to build graphs for several levels, like Package-Level or Layer-Level. Each dependency can be verified to a defined architecture.

Installation

As a Docker Image (recommend way)

docker pull mamuz/phpda

As a Composer Dependency

NOTE: For graph creation GraphViz is required on your machine, which is an open source graph visualization software and available for the most platforms.

$ composer require --dev mamuz/php-dependency-analysis

As a Phar

Since version 2.0.0 not supported anymore.

Features

  • High customizing level
  • Graph creation on customized levels respectively different scopes and layers
  • Supports Usage-Graph, Call-Graph and Inheritance-Graph
  • Dependencies can be aggregated such as to a package, a module or a layer
  • Detecting cycles and violations between layers in a tiered architecture
  • Verifiying dependency graph against a user-defined reference architecture
  • Collected namespaces of dependencies are modifiable to meet custom use cases
  • Printing graphs in several formats (HTML, SVG, DOT, JSON)
  • Extandable by adding user-defined plugins for collecting and displaying
  • Compatible to PHP7 Features, like Return Type Declarations and Anonymous Classes

Usage

Phpda can run out of the box by using a prepared configuration. As you can see configuration is defined by a YAML file.

To provide your own configuration create a yml file, e.g. located in ./phpda.yml:

mode: 'usage'
source: './src'
filePattern: '*.php'
ignore: 'tests'
formatter: 'PhpDA\Writer\Strategy\Svg'
target: './phpda.svg'
groupLength: 1
visitor:
  - PhpDA\Parser\Visitor\TagCollector
  - PhpDA\Parser\Visitor\SuperglobalCollector
visitorOptions:
  PhpDA\Parser\Visitor\Required\DeclaredNamespaceCollector: {minDepth: 2, sliceLength: 2}
  PhpDA\Parser\Visitor\Required\MetaNamespaceCollector: {minDepth: 2, sliceLength: 2}
  PhpDA\Parser\Visitor\Required\UsedNamespaceCollector: {minDepth: 2, sliceLength: 2}
  PhpDA\Parser\Visitor\TagCollector: {minDepth: 2, sliceLength: 2}

Perform an analysis with that configuration:

$ docker run --rm -v $PWD:/app mamuz/phpda

Read the Configuration-Chapter to get knowledge about all available options.

View on Github

7 - PHP Metrics:

A static metric library.

PhpMetrics provides metrics about PHP project and classes, with beautiful and readable HTML report.

Quick start

Follow the quick start guide to get started. composer require phpmetrics/phpmetrics --dev php ./vendor/bin/phpmetrics --report-html=myreport

Then open the generated ./myreport/index.html file in your browser.

You can use a configuration file to customize the report, add options, configure rules for Continuous Integration, etc.

Metrics

You'll find detailed list of metrics in documentation, or running php ./vendor/bin/phpmetrics --metrics

View on Github

8 - PHP Migration:

A static analyzer for PHP version migration.

This is a static analyzer for PHP version migration and compatibility checking.

It can suppose your current code running under the new version of PHP then do checking, and provide advice and treatment.

And it can simplify the process of upgrading PHP. Its goal is instead of manual checking.

Features:

  • Wide coverage, checks most of the changes which introduced in PHP 5.3 - 7.0.
  • Strict, without missing any risk.
  • Zero configuration, run directly after download.
  • Simply add custom checks.

Compare to the similar project PHP Compatibility PHP Compatibility is a set of sniffs for PHP_CodeSniffer, therefore it lacks flexibility and can not checks more changes. just objective comparison

Notice: this project is in beta stage, feel free to report any issues.

Install / Usage

You can download a executable Phar file

wget https://github.com/monque/PHP-Migration/releases/download/v0.2.2/phpmig.phar

Use the following command to check PHP file

php phpmig.phar sample.php

Suppose these code stored in sample.php

<?php
// Fatal error: Only variables can be passed by reference
array_shift(array(1, 2));
sort(array(1, 2, 3));

// __DIR__ is pre-defined
define('__DIR__', dirname(__FILE__));

// Fatal error: Cannot redeclare class_alias()
function class_alias() {}

// This is fine
if (!function_exists('class_alias')) {
    function class_alias() {}
}

// Fatal error: Call-time pass-by-reference has been removed
array_map('trim', &$_SERVER);

// Fatal error: 'break' operator with non-constant operand is no longer supported
while (true) {
    break $a;
}

// Fatal error: Cannot re-assign auto-global variable _GET
function ohno($_GET) {}

// Array keys won't be overwritten when defining an array as a property of a class via an array literal
class C {
    const ONE = 1;
    public $array = [
        self::ONE => 'foo',
        'bar',
        'quux',
    ];
}

// set_exception_handler() is no longer guaranteed to receive Exception objects
set_exception_handler(function (Exception $e) { });

// Changes to the handling of indirect variables, properties, and methods
echo $$foo['bar']['baz'];

// foreach no longer changes the internal array pointer
foreach ($list as &$row) {
    current($list);
}

Output report Each columns means: Line Number, Level, Identified, Version, Message

File: sample.php
--------------------------------------------------------------------------------
Found 11 spot(s), 10 identified
--------------------------------------------------------------------------------
    3 | FATAL      | * | 5.3.0 | Only variables can be passed by reference
    4 | FATAL      | * | 5.3.0 | Only variables can be passed by reference
    7 | WARNING    | * | 5.3.0 | Constant "__DIR__" already defined
   10 | FATAL      | * | 5.3.0 | Cannot redeclare class_alias()
   18 | FATAL      | * | 5.4.0 | Call-time pass-by-reference has been removed
   22 | FATAL      | * | 5.4.0 | break operator with non-constant operand is no longer supported
   26 | FATAL      | * | 5.4.0 | Cannot re-assign auto-global variable
   31 | WARNING    |   | 5.6.0 | Array key may be overwritten when defining as a property and using constants
   39 | WARNING    | * | 7.0.0 | set_exception_handler() is no longer guaranteed to receive Exception objects
   42 | WARNING    | * | 7.0.0 | Different behavior between PHP 5/7
   46 | NOTICE     | * | 7.0.0 | foreach no longer changes the internal array pointer
--------------------------------------------------------------------------------

The third field Identified will be explained at bottom.

View on Github

9 - PHPStan:

A PHP Static Analysis Tool.

PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs even before you write tests for the code. It moves PHP closer to compiled languages in the sense that the correctness of each line of the code can be checked before you run the actual line.

Getting Started

PHPStan requires PHP >= 7.2. You have to run it in environment with PHP 7.x but the actual code does not have to use PHP 7.x features. (Code written for PHP 5.6 and earlier can run on 7.x mostly unmodified.)

PHPStan works best with modern object-oriented code. The more strongly-typed your code is, the more information you give PHPStan to work with.

Properly annotated and typehinted code (class properties, function and method arguments, return types) helps not only static analysis tools but also other people that work with the code to understand it.

Installation 

To start performing analysis on your code, require PHPStan in Composer:

composer require --dev phpstan/phpstan

Composer will install PHPStan’s executable in its bin-dir which defaults to vendor/bin.

You can also download the latest PHAR and just use that. But without Composer, you won’t be able to install and use PHPStan extensions.

Documentation

All the documentation lives on the phpstan.org website:

View on Github

10 - Psalm:

A static analysis tool for finding errors in PHP applications.

Installation

To get started, check out the installation guide.

Live Demo

You can play around with Psalm on its website.

Documentation

Documentation is available on Psalm’s website, generated from the docs folder.

Interested in contributing?

Have a look at CONTRIBUTING.md.

View on Github

Thank you for following this article.

Related videos:

PHPLoc Lines of code static analysis to find PHP code smells

#php #static #analysis 

10 Popular PHP Libraries for Static Analysis
Lawrence  Lesch

Lawrence Lesch

1662017160

React-static: A Progressive Static Site Generator for React

This is now in maintenance only mode. No new major versions will be released.

Remix and NextJS are good alternatives.

Where is react-static 8? The state of react-static -- and its inevitable death. #1661


You are viewing the docs for v7 of React Static. You can browse all historical versions via Github branches!

React Static

A progressive static-site generator for React.

React-Static is a fast, lightweight, and powerful progressive static site generator based on React and its ecosystem. It resembles the simplicity and developer experience you're used to in tools like Create React App and has been carefully designed for performance, flexibility, and user/developer experience.

Features

  • βš›οΈ 100% React (and friends!)
  • πŸš€ Blazing fast builds and performance.
  • 🚚 Data Agnostic. Supply your site with data from anywhere, however you want!
  • βœ‚οΈ Automatic code and data splitting!
  • πŸ’₯ Instant navigation and page views
  • β˜”οΈ Progressively Enhanced and mobile-ready
  • 🎯 SEO Friendly.
  • πŸ₯‡ React-centric developer experience.
  • 😌 Painless project setup & migration.
  • πŸ’― Supports 100% of the React ecosystem. Including CSS-in-JS libraries, custom Query layers like GraphQL, and even Redux.
  • πŸ”₯ Hot Reloadable out-of-the-box. Edit React components, styles and even data in real-time.

Sites Built with React-Static

See a list of sites

Quick Start

  • Install the CLI tool:
$ npm i -g react-static
# or
$ yarn global add react-static
  • Start a new project!
$ react-static create
  • Need some help?
$ react-static --help

Documentation

Migration from a previous version?

The CHANGELOG contains information on breaking change for each major version. The latest breaking changes along with their migration tips are located here

What is a progressive static site?

A progressive static site is a website where every statically exported HTML page is an entry point to a fully-featured automatically-code-split React application. Just like a normal static site, static progressive websites are capable of loading initial landing pages very quickly, but then extend the user experience by transforming invisibly into a single-page React application.

Once a progressive static site page has loaded its React application it can then do amazing things!

  • Prefetch page assets
  • Instantly navigate between pages
  • Provide interactivity not possible in normal static sites
  • Subscribe to and display real-time and dynamic data
  • Anything you can imagine within a React application!

How does it work?

Flow Chart

React Static gathers your data, and templates together and intelligently splits them into bite-size static files using webpack and javascript. Once these files have been generated, React Static uses them to render and export a list of routes that you provide it into HTML files! After your site has been exported, the resulting data, template, and html files can be transfered to a static file server and browsed as an awesomely fast and performant static website!

But remember, a progressive static site is more than that...

Little did you know that when React Static exported your site, it also generated a tiny, optimized, and code-split version of your original React application for every page of your site! After these pages have loaded, React invisibly mounts this application to the existing HTML on the page and... πŸŽ‰πŸŽ‰πŸŽ‰ You are now using the single page React application you originally built! This application is special, though! While you browse your website, pages that you might go to next are automatically preloaded, making navigation to them instantaneous!.

That's just the beginning! With React Static, you can unleash your creativity and build anything you can imagine with speed and productivity. It even has awesome plugins that will help you on your journey!

Coming from Create React App?

React Static is also a great replacement for the ever popular Create React App CLI. It provides a similar developer experience, zero-config environment, and features, but without boxing you in. If you ever need to customize your build system in React Static, there is no need to eject! You can use existing plugins or write your own to customize anything you'd like about the build system. Not building a static site? No worries there, React Static works as an SPA too, even if there is only a single index.html file.

Articles, Videos & Tutorials

Support, Community & Chat

Need some help? Have a quick question? Click here to go to GitHub Discussions! We are constantly answering questions, discussing features and helping each other out!

Contributing, Issues & Bugs

We are always looking for people to help us grow react-static's capabilities and examples. If you have found a bug, or have a feature request let us know! Please follow CONTRIBUTING.md if you want to help out.

Download Details:

Author: React-static
Source Code: https://github.com/react-static/react-static 
License: MIT license

#react #static #javascript 

React-static: A Progressive Static Site Generator for React

CoreUI React Is A Free React Admin Template Based on Bootstrap 5

CoreUI Free React Admin Template v3

CoreUI is meant to be the UX game changer. Pure & transparent code is devoid of redundant components, so the app is light enough to offer ultimate user experience. This means mobile devices also, where the navigation is just as easy and intuitive as on a desktop or laptop. The CoreUI Layout API lets you customize your project for almost any device – be it Mobile, Web or WebApp – CoreUI covers them all!

Versions

CoreUI Pro

Only customers with Enterpise Membership Plan have access to private github CoreUI Pro repository.

Installation

Clone repo

# clone the repo
$ git clone https://github.com/coreui/coreui-free-react-admin-template.git my-project

# go into app's directory
$ cd my-project

# checkout stable version
$ git checkout master

# install app's dependencies
$ npm install

Copy and Paste

Copy all your files to your project folder and then,

# go into app's directory
$ cd my-project

# install app's dependencies
$ npm install

Create React App

This project was bootstrapped with Create React App

see also: CRA docs

Basic usage

# dev server with hot reload at http://localhost:3000
$ npm start

Navigate to http://localhost:3000. The app will automatically reload if you change any of the source files.

Build

Run build to build the project. The build artifacts will be stored in the build/ directory.

# build for production with minification
$ npm run build

What's included

Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations. You'll see something like this:

CoreUI-React#v3.0.0
β”œβ”€β”€ public/          #static files
β”‚   └── index.html   #html template
β”‚
β”œβ”€β”€ src/             #project root
β”‚   β”œβ”€β”€ assets/      #assets - js icons object
β”‚   β”œβ”€β”€ containers/  #container source - template layout
|   β”‚   β”œβ”€β”€ _nav.js  #sidebar config
|   β”‚   └── ...      
β”‚   β”œβ”€β”€ scss/        #user scss/css source
β”‚   β”œβ”€β”€ views/       #views source
β”‚   β”œβ”€β”€ App.js
β”‚   β”œβ”€β”€ App.test.js
β”‚   β”œβ”€β”€ polyfill.js
β”‚   β”œβ”€β”€ index.js
β”‚   β”œβ”€β”€ routes.js    #routes config
β”‚   └── store.js     #template state example 
β”‚
└── package.json

Documentation

The documentation for the CoreUI Admin Template is hosted at our website CoreUI for React

:film_strip: How to setup coreui react theme in laravel. Video tutorial available here

Versioning

For transparency into our release cycle and in striving to maintain backward compatibility, CoreUI Free Admin Template is maintained under the Semantic Versioning guidelines.

See the Releases section of our project for changelogs for each release version.

Creators

Łukasz Holeczek

CoreUI team

Community

Get updates on CoreUI's development and chat with the project maintainers and community members.

Copyright and License

copyright 2020 creativeLabs Łukasz Holeczek.

Code released under the MIT license. There is only one limitation you can't can’t re-distribute the CoreUI as stock. You can’t do this if you modify the CoreUI. In past we faced some problems with persons who tried to sell CoreUI based templates.

Support CoreUI Development

CoreUI is an MIT licensed open source project and completely free to use. However, the amount of effort needed to maintain and develop new features for the project is not sustainable without proper financial backing. You can support development by buying CoreUI Pro Version.

We're also open to conversations regarding custom sponsorship / consulting arrangements. Get in touch on Twitter.


Author: coreui
Source code: https://github.com/coreui/coreui-free-react-admin-template
License: MIT license

#Bootstrap #React #javascript 

CoreUI React Is A Free React Admin Template Based on Bootstrap 5
Hermann  Frami

Hermann Frami

1656889860

Serverless Static Plugin

πŸ“¦ ✨ Serverless Static Plugin

Note

Deploy functionality is in active development, it soon will be available

1.install the plugin

First, add Serverless Static to your project, be sure that you already have the serverless-offline plugin already installed

$ npm install serverless-static --save-dev

or, if serverless-offline is not already installed

$ npm install serverless-static serverless-offline --save-dev

2. add it to your serverless.yml file

Then inside your project's serverless.yml file add following entry to the plugins section: serverless-static. If there is no plugin section you will need to add it to the file.

It should look something like this:

plugins:
  - serverless-offline
  - serverless-static 

3. customize behavior (optional)

custom:
  static:
    path: ./public # select the folder you want to serve
    port: 8000 # select a specific port 

# this will overide default behavior
# it will serve the folder ./public
# it will serve it throught localhost:8000

Author: iliasbhal
Source Code: https://github.com/iliasbhal/serverless-static 
License: 

#serverless #static #s3 #lambda 

Serverless Static Plugin
Hermann  Frami

Hermann Frami

1656882420

Serverless Plugin Static

serverless-plugin-static  

A serverless framework plugin to serve static files locally

Usage requirements

Requires Node 10.

It's recommended to use this plugin along with serverless-offline.

Installation

Obviously, you should have Serverless-framework installed. If it's not, please start from this guide.

Then install the package:

npm install serverless-plugin-static -D

You can start serving the static folder by the CLI command, but probably for local development you should use serverless-offline plugin:

npm install serverless-offline -D

Quick start

Add the plugins to your serverless.yml:

plugins:
  - serverless-plugin-static
  - serverless-offline

Configure the plugin by providing folder path and server port, default values are:

custom:
  static:
    folder: ./static
    port: 8080

Start the application:

serverless offline start

You can also start serving files separately by the command:

serverless serve --folder ./static --port 8080

Or with the shortcuts:

serverless serve -f ./static -p 8080

Note: do not use CLI options with serverless-offline start command or any other plugins that create a server, since port argument will cause conflicts.

Author: Sashkopavlenko
Source Code: https://github.com/sashkopavlenko/serverless-plugin-static 
License: MIT license

#serverless #static #plugin 

Serverless Plugin Static
Vincent Lab

Vincent Lab

1605177550

Building a Static Website with Hugo

#hugo #static #site #generator #markup #static site generator

Building a Static Website with Hugo

NuxtJS Static Pages and Content API - The Latest Features

NuxtJS Static Pages and Content API is finally here! NuxtJS just released a brand new version full of awesome features for building static pages, working with content like Markdown files, and lots more. Debbie O’Brien, Head of Learning at NuxtJS, joins me to get hands-on with the latest and greatest features in NuxtJS

#api #nuxtjs #static #content api #features

NuxtJS Static Pages and Content API - The Latest Features