Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ trim_trailing_whitespace=true
[makefile]
indent_style=tab

[*.{gradle,java,kt,kts,sh,xml,yaml,yml}]
[*.{cs,gradle,java,kt,kts,sh,xml,yaml,yml}]
indent_size=2
max_line_length=100

; https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/
; https://google.github.io/styleguide/csharp-style.html#whitespace-rules
[*.cs]
csharp_new_line_before_open_brace = none
dotnet_diagnostic.IDE0011.severity = error

[*.{js,jsx,ts,tsx}]
indent_size=2
max_line_length=80
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ apk add --no-cache --virtual .build-deps \
py3-pip \
python3-dev
apk add --no-cache \
dotnet8-sdk \
libxslt \
nodejs \
python3
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ shell:
# Runs tests
.PHONY: test
test:
docker run --rm -v "$${PWD}/test:/test" "$$(docker build --network=host -q .)" sh -c \
docker run --rm --init -v "$${PWD}/test:/test" "$$(docker build --network=host -q .)" sh -c \
'cd /tmp \
&& cp -r /test/before actual \
&& cp -r /test/after expected \
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This repo currently contains a single [pre-commit](https://pre-commit.com/) hook
- [xsltproc](http://www.xmlsoft.org/xslt/xsltproc.html) from libxslt v10139 for XML
- [terraform fmt](https://github.com/hashicorp/terraform) v1.9.8 for Terraform
- [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html) v18.1.8 for C++, Protobuf
- [dotnet format](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-format) v8.0.111 for C#
- [SVGO](https://github.com/svg/svgo) v3.3.2 for SVG
- [Taplo](https://taplo.tamasfe.dev/) v0.9.3 for TOML
- Custom regex transformations (basically [sed](https://en.wikipedia.org/wiki/Sed)), for example:
Expand Down
86 changes: 61 additions & 25 deletions entry.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/usr/bin/env node

import { exec } from "child_process";
import { createReadStream, readFile, writeFile } from "fs";
import { createReadStream } from "fs";
import { readFile, unlink, writeFile } from "fs/promises";
import { createInterface } from "readline";

/**
Expand Down Expand Up @@ -49,37 +50,32 @@ const run = (...args: string[]) =>
export const isTruthy = <T>(value: T): value is NonNullable<T> => !!value;

/** Reads a file, transforms its contents, and writes the result if different */
const transformFile = (path: string, transform: (before: string) => string) =>
new Promise<void>((resolve, reject) => {
readFile(path, "utf8", (err, data) => {
// File unreadable
if (err) {
reject(err);
return;
}

// File empty
if (data === "") {
resolve();
return;
}
const transformFile = async (
path: string,
transform: (before: string) => string,
) => {
const data = await readFile(path, "utf8");

// File empty
if (data === "") {
return;
}

// File unmodified
const after = transform(data);
if (data === after) {
resolve();
return;
}
// File unmodified
const after = transform(data);
if (data === after) {
return;
}

// File modified
writeFile(path, after, "utf8", err => (err ? reject(err) : resolve()));
});
});
// File modified
await writeFile(path, after, "utf8");
};

const enum HookName {
Autoflake = "autoflake",
Black = "Black",
ClangFormat = "ClangFormat",
DotnetFormat = "dotnet format",
EsLint = "ESLint",
Gofmt = "gofmt",
GoogleJavaFormat = "google-java-format",
Expand Down Expand Up @@ -191,6 +187,46 @@ const HOOKS: Record<HookName, LockableHook> = {
include: /\.(cpp|proto$)/,
runAfter: [HookName.Sed],
}),
[HookName.DotnetFormat]: createLockableHook({
action: async sources => {
// Create project file
const projectFile = `dotnet-format-${Math.random()}.csproj`;
await writeFile(
projectFile,
`<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<EnableDefaultItems>false</EnableDefaultItems>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
${sources.map(s => `<Compile Include="${s}" />`).join("")}
</ItemGroup>
</Project>`,
);
try {
await run(
"dotnet",
"format",
"style",
projectFile,
"--verbosity",
"quiet",
);
await run(
"dotnet",
"format",
"whitespace",
projectFile,
"--verbosity",
"quiet",
);
} finally {
await unlink(projectFile);
}
},
include: /\.cs$/,
runAfter: [HookName.Sed],
}),
[HookName.EsLint]: createLockableHook({
action: async sources => {
try {
Expand Down
14 changes: 14 additions & 0 deletions test/after/hello.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;

namespace HelloWorld {
public class Program {
public static void Main(string[] args) {
Console.WriteLine("Hello, World!");
var numbers = new List<int> { 1, 2, 3 };
foreach (var number in numbers) {
Console.WriteLine($"Number: {number}");
}
}
}
}
14 changes: 14 additions & 0 deletions test/before/hello.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System ;
using System.Collections.Generic;

namespace HelloWorld{
public class Program
{public static void Main(string[]args)
{
Console.WriteLine("Hello, World!");
var numbers=new List<int>{1,2,3};
foreach (var number in numbers)
Console.WriteLine($"Number: {number}");
}
}
}