Skip to content

Commit

Permalink
initial implementation, coming from dflag MR and delta actually
Browse files Browse the repository at this point in the history
  • Loading branch information
ldemailly committed Feb 21, 2023
1 parent b90a539 commit 64c05b9
Show file tree
Hide file tree
Showing 9 changed files with 416 additions and 1 deletion.
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "gomod"
directory: "/" # Location of package manifests
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"
21 changes: 21 additions & 0 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: "Code Coverage"

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/setup-go@v3
with:
go-version: '1.19'
- name: Run test coverage
run: go test -race -coverprofile=coverage.out -covermode=atomic ./...
- uses: codecov/codecov-action@v3
with:
files: coverage.out
67 changes: 67 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '42 20 * * 3'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

steps:
- name: Checkout repository
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # pin@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # pin@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # pin@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # pin@v2
176 changes: 176 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# Config for golanglint-ci

# output configuration options

# all available settings of specific linters
linters-settings:
gocritic:
disabled-checks:
- ifElseChain
dupl:
# tokens count to trigger issue, 150 by default
threshold: 100
exhaustive:
# indicates that switch statements are to be considered exhaustive if a
# 'default' case is present, even if all enum members aren't listed in the
# switch
default-signifies-exhaustive: false
funlen:
lines: 140
statements: 70
gocognit:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 42
nestif:
# minimal complexity of if statements to report, 5 by default
min-complexity: 4
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 30
godot:
# check all top-level comments, not only declarations
check-all: false
govet:
# report about shadowed variables
check-shadowing: true
# settings per analyzer
settings:
printf: # analyzer name, run `go tool vet help` to see all analyzers
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Printf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).FErrf
enable-all: true
disable-all: false
depguard:
list-type: blacklist
include-go-root: false
packages:
- github.com/sirupsen/logrus
packages-with-error-message:
# specify an error message to output when a blacklisted package is used
- github.com/sirupsen/logrus: "logging is allowed only by fortio.log"
lll:
# max line length, lines longer will be reported. Default is 120.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 132
# tab width in spaces. Default to 1.
tab-width: 1
misspell:
# Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
locale: US
ignore-words:
- fortio
nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 30
nolintlint:
require-specific: true
whitespace:
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
gofumpt:
# Choose whether or not to use the extra rules that are disabled
# by default
extra-rules: false


linters:
disable:
# bad ones:
- musttag
# Deprecated ones:
- scopelint
- golint
- interfacer
- maligned
- varcheck
- structcheck
- nosnakecase
- deadcode
# Weird/bad ones:
- wsl
- nlreturn
- gochecknoinits
- gochecknoglobals
- gomnd
- testpackage
- wrapcheck
- exhaustivestruct
- tagliatelle
- nonamedreturns
- varnamelen
- exhaustruct # seems like a good idea at first but actually a pain and go does have zero values for a reason.
# TODO consider putting these back, when they stop being bugged (ifshort, wastedassign,...)
- paralleltest
- thelper
- forbidigo
- ifshort
- wastedassign
- cyclop
- forcetypeassert
- ireturn
enable-all: true
disable-all: false
# Must not use fast: true in newer golangci-lint or it'll just skip a bunch of linter instead of doing caching like before (!)
fast: false


issues:
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
- gochecknoinits
- gochecknoglobals
- forcetypeassert
- nosnakecase
- noctx

# Exclude lll issues for long lines with go:generate
- linters:
- lll
source: "^//go:generate "
- linters:
- goerr113
text: "do not define dynamic errors"
- linters:
- govet
text: "fieldalignment:"
- linters:
- godox
text: "TODO"
- linters:
- nosnakecase
text: "grpc_|_SERVING|O_"

# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-issues-per-linter: 0

# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0

severity:
# Default value is empty string.
# Set the default severity for issues. If severity rules are defined and the issues
# do not match or no severity is provided to the rule this will be the default
# severity applied. Severities should match the supported severity names of the
# selected out format.
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity
# - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
default-severity: error

# The default value is false.
# If set to true severity-rules regular expressions become case sensitive.
case-sensitive: false
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
[![Go Reference](https://pkg.go.dev/badge/fortio.org/sets.svg)](https://pkg.go.dev/fortio.org/sets)
[![Go Report Card](https://goreportcard.com/badge/fortio.org/sets)](https://goreportcard.com/report/fortio.org/sets)
[![GitHub Release](https://img.shields.io/github/release/fortio/sets.svg?style=flat)](https://github.com/fortio/sets/releases/)
[![Coverage](https://codecov.io/github/fortio/delta/branch/main/graph/badge.svg?token=LONYZDFQ7C)](https://codecov.io/github/fortio/sets)

# sets
Sets and Set operations in golang (ie map[T]struct{} but with helper/nicer names, hiding the struct{}{}...)
Sets and Set operations in golang (ie `map[T]struct{}` but with helper functions/nicer names, hiding the `struct{}{}` etc...)
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module fortio.org/sets

go 1.19

require fortio.org/assert v1.1.4
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fortio.org/assert v1.1.4 h1:Za1RaG+OjsTMpQS3J3UCvTF6wc4+IOHCz+jAOU37Y4o=
fortio.org/assert v1.1.4/go.mod h1:039mG+/iYDPO8Ibx8TrNuJCm2T2SuhwRI3uL9nHTTls=
81 changes: 81 additions & 0 deletions sets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// (Fortio) Sets.
//
// (c) 2023 Fortio Authors
// See LICENSE

// Sets and Set type and operations in go 1.18+ generics.
// (pending built in support in golang core)
package sets // import "fortio.org/sets"

import (
"fmt"
"sort"
"strings"
)

type Set[T comparable] map[T]struct{}

// SetFromSlice constructs a Set from a slice.
func FromSlice[T comparable](items []T) Set[T] {
// best pre-allocation if there are no duplicates
res := make(map[T]struct{}, len(items))
for _, item := range items {
res[item] = struct{}{}
}
return res
}

func (s Set[T]) Clone() Set[T] {
res := make(Set[T], len(s))
for k := range s {
res.Add(k)
}
return res
}

func (s Set[T]) Add(item ...T) {
for _, i := range item {
s[i] = struct{}{}
}
}

func (s Set[T]) Has(item T) bool {
_, found := s[item]
return found
}

func (s Set[T]) Remove(item ...T) {
for _, i := range item {
delete(s, i)
}
}

func New[T comparable](item ...T) Set[T] {
res := make(Set[T], len(item))
res.Add(item...)
return res
}

func (s Set[T]) String() string {
keys := make([]string, 0, len(s))
for k := range s {
keys = append(keys, fmt.Sprintf("%v", k))
}
sort.Strings(keys)
return strings.Join(keys, ",")
}

// RemoveCommon removes elements from both sets that are in both,
// leaving only the delta. Useful for Notifier on Set so that
// oldValue has what has been removed and newValue has what has been added.
func RemoveCommon[T comparable](a, b Set[T]) {
if len(a) > len(b) {
a, b = b, a
}
for e := range a {
if _, found := b[e]; found {
delete(a, e)
delete(b, e)
}
}
}
Loading

0 comments on commit 64c05b9

Please sign in to comment.