Semantic Versioning (semver) library written in golang

Overview

semver for golang Build Status GoDoc Coverage Status Go Report Card

semver is a Semantic Versioning library written in golang. It fully covers spec version 2.0.0.

Versioning

Old v1-v3 versions exist in the root of the repository for compatiblity reasons and will only receive bug fixes.

The current stable version is v4 and is fully go-mod compatible.

Usage

$ go get github.com/blang/semver/v4
# Or use fixed versions
$ go get github.com/blang/semver/[email protected]

Note: Always vendor your dependencies or fix on a specific version tag.

import github.com/blang/semver/v4
v1, err := semver.Make("1.0.0-beta")
v2, err := semver.Make("2.0.0-beta")
v1.Compare(v2)

Also check the GoDocs.

Why should I use this lib?

  • Fully spec compatible
  • No reflection
  • No regex
  • Fully tested (Coverage >99%)
  • Readable parsing/validation errors
  • Fast (See Benchmarks)
  • Only Stdlib
  • Uses values instead of pointers
  • Many features, see below

Features

  • Parsing and validation at all levels
  • Comparator-like comparisons
  • Compare Helper Methods
  • InPlace manipulation
  • Ranges >=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1
  • Wildcards >=1.x, <=2.5.x
  • Sortable (implements sort.Interface)
  • database/sql compatible (sql.Scanner/Valuer)
  • encoding/json compatible (json.Marshaler/Unmarshaler)

Ranges

A Range is a set of conditions which specify which versions satisfy the range.

A condition is composed of an operator and a version. The supported operators are:

  • <1.0.0 Less than 1.0.0
  • <=1.0.0 Less than or equal to 1.0.0
  • >1.0.0 Greater than 1.0.0
  • >=1.0.0 Greater than or equal to 1.0.0
  • 1.0.0, =1.0.0, ==1.0.0 Equal to 1.0.0
  • !1.0.0, !=1.0.0 Not equal to 1.0.0. Excludes version 1.0.0.

Note that spaces between the operator and the version will be gracefully tolerated.

A Range can link multiple Ranges separated by space:

Ranges can be linked by logical AND:

  • >1.0.0 <2.0.0 would match between both ranges, so 1.1.1 and 1.8.7 but not 1.0.0 or 2.0.0
  • >1.0.0 <3.0.0 !2.0.3-beta.2 would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2

Ranges can also be linked by logical OR:

  • <2.0.0 || >=3.0.0 would match 1.x.x and 3.x.x but not 2.x.x

AND has a higher precedence than OR. It's not possible to use brackets.

Ranges can be combined by both AND and OR

  • >1.0.0 <2.0.0 || >3.0.0 !4.2.1 would match 1.2.3, 1.9.9, 3.1.1, but not 4.2.1, 2.1.1

Range usage:

v, err := semver.Parse("1.2.3")
expectedRange, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0")
if expectedRange(v) {
    //valid
}

Example

Have a look at full examples in v4/examples/main.go

import github.com/blang/semver/v4

v, err := semver.Make("0.0.1-alpha.preview+123.github")
fmt.Printf("Major: %d\n", v.Major)
fmt.Printf("Minor: %d\n", v.Minor)
fmt.Printf("Patch: %d\n", v.Patch)
fmt.Printf("Pre: %s\n", v.Pre)
fmt.Printf("Build: %s\n", v.Build)

// Prerelease versions array
if len(v.Pre) > 0 {
    fmt.Println("Prerelease versions:")
    for i, pre := range v.Pre {
        fmt.Printf("%d: %q\n", i, pre)
    }
}

// Build meta data array
if len(v.Build) > 0 {
    fmt.Println("Build meta data:")
    for i, build := range v.Build {
        fmt.Printf("%d: %q\n", i, build)
    }
}

v001, err := semver.Make("0.0.1")
// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE
v001.GT(v) == true
v.LT(v001) == true
v.GTE(v) == true
v.LTE(v) == true

// Or use v.Compare(v2) for comparisons (-1, 0, 1):
v001.Compare(v) == 1
v.Compare(v001) == -1
v.Compare(v) == 0

// Manipulate Version in place:
v.Pre[0], err = semver.NewPRVersion("beta")
if err != nil {
    fmt.Printf("Error parsing pre release version: %q", err)
}

fmt.Println("\nValidate versions:")
v.Build[0] = "?"

err = v.Validate()
if err != nil {
    fmt.Printf("Validation failed: %s\n", err)
}

Benchmarks

BenchmarkParseSimple-4           5000000    390    ns/op    48 B/op   1 allocs/op
BenchmarkParseComplex-4          1000000   1813    ns/op   256 B/op   7 allocs/op
BenchmarkParseAverage-4          1000000   1171    ns/op   163 B/op   4 allocs/op
BenchmarkStringSimple-4         20000000    119    ns/op    16 B/op   1 allocs/op
BenchmarkStringLarger-4         10000000    206    ns/op    32 B/op   2 allocs/op
BenchmarkStringComplex-4         5000000    324    ns/op    80 B/op   3 allocs/op
BenchmarkStringAverage-4         5000000    273    ns/op    53 B/op   2 allocs/op
BenchmarkValidateSimple-4      200000000      9.33 ns/op     0 B/op   0 allocs/op
BenchmarkValidateComplex-4       3000000    469    ns/op     0 B/op   0 allocs/op
BenchmarkValidateAverage-4       5000000    256    ns/op     0 B/op   0 allocs/op
BenchmarkCompareSimple-4       100000000     11.8  ns/op     0 B/op   0 allocs/op
BenchmarkCompareComplex-4       50000000     30.8  ns/op     0 B/op   0 allocs/op
BenchmarkCompareAverage-4       30000000     41.5  ns/op     0 B/op   0 allocs/op
BenchmarkSort-4                  3000000    419    ns/op   256 B/op   2 allocs/op
BenchmarkRangeParseSimple-4      2000000    850    ns/op   192 B/op   5 allocs/op
BenchmarkRangeParseAverage-4     1000000   1677    ns/op   400 B/op  10 allocs/op
BenchmarkRangeParseComplex-4      300000   5214    ns/op  1440 B/op  30 allocs/op
BenchmarkRangeMatchSimple-4     50000000     25.6  ns/op     0 B/op   0 allocs/op
BenchmarkRangeMatchAverage-4    30000000     56.4  ns/op     0 B/op   0 allocs/op
BenchmarkRangeMatchComplex-4    10000000    153    ns/op     0 B/op   0 allocs/op

See benchmark cases at semver_test.go

Motivation

I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like.

Contribution

Feel free to make a pull request. For bigger changes create a issue first to discuss about it.

License

See LICENSE file.

Issues
  • Enable go modules

    Enable go modules

    https://github.com/golang/go/wiki/Modules#gomod

    This PR is just a result of the following commands (in clean Go 1.11.5 environment):

    go mod init
    go get ./...
    go mod tidy
    

    The aim is to prevent semver from being marked as "incompatible" in go-mod-aware modules which depend on semver. This happens just because semver is >1.0.0 (currently v3.5.1) but isn't go-mod-aware. See https://forum.golangbridge.org/t/go-get-marking-go-mod-incompatible/10686 for more.

    opened by radeksimko 10
  • Make splitAndTrim parse more inteligently...

    Make splitAndTrim parse more inteligently...

    ... by making it understand that a space after a range token ('>', '<', '=') can be threated like a typo instead of like an error. Example '<= '.

    Also, remove all whitespaces instead of just leading/ending spaces, as there might be spaces between a range token and a version number. Example: '>= 2.5.2'

    opened by alexandernst 10
  • added methods to implement sql related interfaces.

    added methods to implement sql related interfaces.

    Implemented methods:

    • Version.Scan -> database/sql.Scanner
    • Version.Value -> database/sql/driver.Valuer

    Current implementation stores Version as a single string Field, which is most convenient when it is used as a struct field.

    Thx for this awesome package. Keep up the good work!

    opened by tike 10
  • remove pre-release increment constraint

    remove pre-release increment constraint

    I don't see a reason why pre-releases should not be incremented. It is very common to release early without a stable api.

    We should support incrementing 0.1.0 releases and the like. #59

    opened by lfaoro 8
  • Use of Pointers

    Use of Pointers

    I notice that lots of methods in your API (e.g., Validate, Compare) take pointer arguments. But I don't see why they should. None of these operations actually mutate the object. So it should be fine to simply pass a value.

    The reason I see this as an issue is twofold. First, it gives the impression (when looking at the API), that these things mutate the objects. But more important for me, it means I need to have pointers available in my code which keeps the door open for inadvertent mutation in my code as well.

    Is there a reason to use the pointers in the API like you have?

    opened by xogeny 8
  • Cannot install using go modules

    Cannot install using go modules

    v3.5.1 is the last tagged version that doesn’t include a go.mod file The newer has a go.mod file but is invalid since the module needs to have a /v3 suffix then

    see https://github.com/golang/go/issues/31944#issuecomment-528272174 for more

    opened by lootek 6
  • proposal: remove pre-release versions >1.0.0 increment constraint

    proposal: remove pre-release versions >1.0.0 increment constraint

    What is the motivation behind stopping pre-releases from being incremented? I read the SemVer spec and couldn't find this rule, could you point out where you've seen this constraint?

    // IncrementMinor increments the minor version
    func (v *Version) IncrementMinor() error {
            //-----
    	if v.Major == 0 { // why?
    		return fmt.Errorf("Minor version can not be incremented for %q", v.String())
    	}
            //-----
    	v.Minor += 1
    	v.Patch = 0
    	return nil
    }
    

    Would you mind me submitting a PR to remove it?

    opened by lfaoro 5
  • Support wildcards in versions

    Support wildcards in versions

    This implements #24

    The code will expand wildcards inside versions following these rules:

    * when dealing with patch wildcards:
    >= 1.2.x    will become    >= 1.2.0
    <= 1.2.x    will become    <  1.3.0
    >  1.2.x    will become    >= 1.3.0
    <  1.2.x    will become    <  1.2.0
    != 1.2.x    will become    <  1.2.0 >= 1.3.0
    * when dealing with minor wildcards:
    >= 1.x      will become    >= 1.0.0
    <= 1.x      will become    <  2.0.0
    >  1.x      will become    >= 2.0.0
    <  1.0      will become    <  1.0.0
    != 1.x      will become    <  1.0.0 >= 2.0.0
    * when dealing with wildcards without version operator:
    1.2.x       will become    >= 1.2.0 < 1.3.0
    1.x         will become    >= 1.0.0 < 2.0.0
    
    opened by alexandernst 5
  • Feature/tolerant json parse

    Feature/tolerant json parse

    See https://github.com/blang/semver/issues/16 and https://github.com/blang/semver/pull/19 for context

    I've extended the UnmarshalJSON to fall back to ParseTolerant if there is an error on Parse. If that errors too then the error is returned.

    I added test cases for this that are all passing well.

    This allows me to build a struct like this and have it parse automatically:

    type Fields struct {
    	AppVersion semver.Version `json:"app_version"`
    	OSVersion  semver.Version `json:"os_version"`
    	Foobar     string         `json:"foobar"`
    }
    

    This now works with my mobile clients, which version like 4.5 rather than 4.5.0 which there's no way for me to fix historically.

    opened by tsheaff 4
  • Coverage is lower than what readme says

    Coverage is lower than what readme says

    Fully tested (Coverage >99%)

    But it seems coverage is around 87% according to batch in readme.

    Please, don't get me wrong, it's just to increase awareness and we can make it great again. If you wish, I can even give a hand.

    opened by ferhatelmas 3
  • Start with a slice large enough for the minimum version

    Start with a slice large enough for the minimum version

    Obviously, we should make room for (at least) three digits and two dots. I considered padding a little bit more (maybe six digits is common?) but decided against it after some snooping*.

    Before:

    BenchmarkStringSimple   10000000               195 ns/op              16 B/op          1 allocs/op
    BenchmarkStringLarger    5000000               326 ns/op              40 B/op          2 allocs/op
    BenchmarkStringComplex   5000000               506 ns/op              88 B/op          3 allocs/op
    BenchmarkStringAverage   5000000               411 ns/op              56 B/op          2 allocs/op
    

    After:

    BenchmarkStringSimple   20000000               117 ns/op               5 B/op          0 allocs/op
    BenchmarkStringLarger   10000000               243 ns/op              32 B/op          2 allocs/op
    BenchmarkStringComplex   5000000               446 ns/op              80 B/op          3 allocs/op
    BenchmarkStringAverage   5000000               336 ns/op              47 B/op          2 allocs/op
    

    * 81% of the released versions on RubyGems are single digits, and more than 99% fit after one grow.

    abort "Requires Ruby 2.x" unless RUBY_VERSION.start_with? '2.'
    
    require 'rubygems/name_tuple'
    require 'rubygems/remote_fetcher'
    
    Gem::Source.new('https://rubygems.org').load_specs(:released).each do |tuple|
      puts tuple.version.to_s
    end
    
    ruby rubygems.rb | awk -e '{ print length() }' | sort -n | uniq -c
    
    opened by cbandy 3
  • Allow prereleases to contain x

    Allow prereleases to contain x

    Closes #75

    This pull request slightly alters expandWildcardVersions to use strings.Contains(.x) instead of strings.Contains(x) for trying to assess whether a range condition has a wildcard. This allows prereleases with x in the name as opposed to failing with the error documented in #75: Could not get version from string: "<".

    opened by danielhelfand 0
  • Using x in prerelease causes error

    Using x in prerelease causes error

    Given the version 0.1.0-x, ParseRange returns the following error:

    Could not get version from string: "<"
    

    Replacing the x with another character fixes the problem (e.g. 0.1.0-y).

    This appears to be related to x being used to denote wildcards as implemented in #27: https://github.com/blang/semver/blob/4487282d78122a245e413d7515e7c516b70c33fd/v4/range.go#L330

    This can be reproduced with the following test:

    func TestExpandWildcardVersion(t *testing.T) {
    	tests := []struct {
    		i [][]string
    		o [][]string
    	}{
    		{[][]string{{"foox"}}, nil},
    
                    // FAILING TEST
    		{[][]string{{"0.1.0-x"}}, [][]string{{"0.1.0-x"}}},
    
    
    		{[][]string{{">=1.2.x"}}, [][]string{{">=1.2.0"}}},
    		{[][]string{{"<=1.2.x"}}, [][]string{{"<1.3.0"}}},
    		{[][]string{{">1.2.x"}}, [][]string{{">=1.3.0"}}},
    		{[][]string{{"<1.2.x"}}, [][]string{{"<1.2.0"}}},
    		{[][]string{{"!=1.2.x"}}, [][]string{{"<1.2.0", ">=1.3.0"}}},
    		{[][]string{{">=1.x"}}, [][]string{{">=1.0.0"}}},
    		{[][]string{{"<=1.x"}}, [][]string{{"<2.0.0"}}},
    		{[][]string{{">1.x"}}, [][]string{{">=2.0.0"}}},
    		{[][]string{{"<1.x"}}, [][]string{{"<1.0.0"}}},
    		{[][]string{{"!=1.x"}}, [][]string{{"<1.0.0", ">=2.0.0"}}},
    		{[][]string{{"1.2.x"}}, [][]string{{">=1.2.0", "<1.3.0"}}},
    		{[][]string{{"1.x"}}, [][]string{{">=1.0.0", "<2.0.0"}}},
    
    	}
    
    	for _, tc := range tests {
    		o, _ := expandWildcardVersion(tc.i)
    		if !reflect.DeepEqual(tc.o, o) {
    			t.Errorf("Invalid for case %q: Expected %q, got: %q", tc.i, tc.o, o)
    		}
    	}
    }
    

    Result of this test is: Invalid for case [["0.1.0-x"]]: Expected [["0.1.0-x"]], got: [[">=0.1.0-x" "<"]]

    At the very least, it would be helpful to call out this corner case in the docs if fixing this would be challenging due to breaking changes.

    opened by danielhelfand 0
  • Major version constraint circumvented by prerelease versions

    Major version constraint circumvented by prerelease versions

    I'm trying to implement a range check that allows any major or minor version change, but never a major change. So that anything starting with 1 but never anything starting with 2 or above.

    I tried expressing that as >= 1.x, >= 1.x < 2.x, >= 1.x < 2.x.x, and >= 1.x < 2.0.0, but found that it will allow 2.x prereleases, e.g. 2.0.0-v2-5.

    package main
    
    import (
    	"fmt"
    	"github.com/blang/semver/v4"
    )
    
    func main() {
    	v, _ := semver.Parse("2.0.0-v2-5")
    	r, _ := semver.ParseRange(">= 1.x")
    	fmt.Println(r(v))
    	r, _ = semver.ParseRange(">= 1.x < 2.x")
    	fmt.Println(r(v))
    	r, _ = semver.ParseRange(">= 1.x < 2.x.x")
    	fmt.Println(r(v))
    	r, _ = semver.ParseRange(">= 1.x < 2.0.0")
    	fmt.Println(r(v))
    }
    

    This prints true four times. I know that 2.0.0-v2-5 is "less than" 2.0.0 because it is a prerelease, but this seems to be making it caught by 1.x as well.

    opened by mattolenik 0
  • ParseTolerant

    ParseTolerant "1.15-alpine3.14" returns error

    Using semver v4

    	e, err := semver.ParseTolerant("1.15-alpine3.14")
    	if err != nil {
    		fmt.Println(err)
    	}
    

    returns error Invalid character(s) found in minor number "15-alpine3"

    opened by bhaskarkc 1
  • [FEAT]: added Ranger as alternative to Range

    [FEAT]: added Ranger as alternative to Range

    Main differences between Range:

    • compiled version checker can be reverted back to string, if necessary
    • possibly, you can add support of inner comparison (in rounded brackets -> (), like in mathematical operations), as well as additional comparators, or range syntax (got a few ideas from this article)

    My main goal was to revert back parsed range, so possibly we can optimize it a bit without loosing backward compatibility.

    opened by quenbyako 0
Releases(v4.0.0)
  • v4.0.0(May 24, 2020)

    This release introduces the new v4 directory as the base for all v4 versions. This change makes all v4 versions go module compatible.

    For stability reasons, the root of the repository keeps all v1-v3 versions but will only receive bug fixes.

    If possible upgrade to v4, it is fully backward-compatible with v3, but resides in its own module.

    go get github.com/blang/semver/[email protected]
    ...
    
    import github.com/blang/semver/v4
    v1, err := semver.Make("1.0.0-beta")
    v2, err := semver.Make("2.0.0-beta")
    v1.Compare(v2)
    

    Thanks for all the contributions and the patience for this release

    Source code(tar.gz)
    Source code(zip)
Owner
Benedikt Lang
Go, AWS, Kubernetes
Benedikt Lang
A CLI which automates semver versioning.

Semverbot A CLI which automates semver versioning based on git information. Why Semverbot? There are several reasons why you should consider using sbo

null 101 Jun 19, 2022
Learning go with tests! Also setting up automated versioning via SemVer.

learn-go-with-tests The purpose of this repo is to complete the learn-go-with-test course located here. I am also interested in learning how to automa

Derek Willingham 0 Nov 23, 2021
modver - a Go package and command that helps you obey semantic versioning rules in your Go module.

Modver This is modver, a Go package and command that helps you obey semantic versioning rules in your Go module. It can read and compare two different

Bob Glickstein 2 Apr 21, 2022
Interactive prompt to set and push a semver tag

cutver For when you know what version to tag, and you want to cut a release in the annotated tag format. Installation go install github.com/roryq/cutv

Rory Quinn 7 Oct 11, 2021
🦔 semver and constraint parsing with a focus on performance

semver ?? semver and constraint parsing with a focus on performance semver provides semantic version and constraint parsing, comparison, and testing.

James Bowes 7 Dec 1, 2021
Automatically create global & local Rate Limit in Istio, support EnvoyFilter versioning!

istio-ratelimit-operator Istio ratelimit operator provide an easy way to configure Global or Local Ratelimit in Istio mesh. Istio ratelimit operator a

Zufar Dhiyaulhaq 18 Jun 27, 2022
Dud is a lightweight tool for versioning data alongside source code and building data pipelines.

Dud Website | Install | Getting Started | Source Code Dud is a lightweight tool for versioning data alongside source code and building data pipelines.

Kevin Hanselman 98 Jun 20, 2022
A boilerplate for Go fiber versioning

Fiber Versioning Boilerplate Prerequisite Make sure you have the following installed outside the current project directory and available in your GOPAT

Visarut Phusua 17 Apr 27, 2022
Git extension for versioning large files

Git Large File Storage Git LFS is a command line extension and specification for managing large files with Git. The client is written in Go, with pre-

Git LFS 10.4k Jun 23, 2022
Selected Machine Learning algorithms for natural language processing and semantic analysis in Golang

Natural Language Processing Implementations of selected machine learning algorithms for natural language processing in golang. The primary focus for t

James Bowman 367 Jun 25, 2022
Selected Machine Learning algorithms for natural language processing and semantic analysis in Golang

Natural Language Processing Implementations of selected machine learning algorithms for natural language processing in golang. The primary focus for t

James Bowman 366 Jun 15, 2022
A simple, semantic and developer-friendly golang package for datetime

Carbon 中文 | English carbon 是一个轻量级、语义化、对开发者友好的 Golang 时间处理库,支持链式调用和 gorm、xorm、zorm 等主流 orm。 如果您觉得不错,请给个 star 吧 github:github.com/golang-module/carbon g

null 2.1k Jun 23, 2022
A simple, semantic and developer-friendly golang package for encoding&decoding and encryption&decryption

A simple, semantic and developer-friendly golang package for encoding&decoding and encryption&decryption

null 243 Jun 23, 2022
Semantic version generator using git commit keywords and overrides

Semantic version generator Project created overnight, to prove that management of semantic versioning is NOT painful and do not require arguments and

Lukasz Raczylo 25 May 4, 2022
Everything a semantic desktop search engine combined with a single-user document management system

Everything will be a semantic desktop search engine combined with a single-user document management system. It will apply ideas of the semantic web and knowledge graphs to organize your data, allowing you to maintain private knowledge graphs as well as make use of public knowledge graphs, such as Wikidata.

Dominik Honnef 22 May 21, 2022
Yet another semantic version incrementor and tagger for git

git-tag-inc Increments the version number and tags it. (You will need to push) Usage ./git-tag-inc [major] [minor] [release] [test] [uat] git-tag-in

Arran Ubels 6 Apr 30, 2022
A dead simple CLI tool that prints the next semantic version based on the last tag of your git repository

nextver A dead simple CLI tool that prints the next semantic version based on the last tag of your git repository. Install go install github.com/junk1

Tom 3 Jun 4, 2022
🥄A simple generator for semantic git messages.

?? Tablespoon EXPERIMENTAL PREVIEW A simple generator for semantic git messages. Installation | Contributing Tablespoon is a simple generator which ca

Matt 4 Jun 10, 2022
A command line interface for trying out Repustate's multilingual semantic search

rcli A command line interface for trying out Repustate's multilingual semantic search. Install & Usage Download the binary for your OS. Make sure it's

Repustate 5 Nov 26, 2020
Provides simple, semantic manipulation of the operating system's signal processing.

Provides simple, semantic manipulation of the operating system's signal processing.

Jayson Wang 0 Dec 15, 2021
Bump-version - Bump a given semantic version, following a given version fragment

bump-version Bump a given semantic version, following a given version fragment.

Weslei Juan Novaes Pereira 3 Feb 7, 2022
golang feature toggle library - a library to help make golang feature toggling clean and easy

toggle supports env_variable backed toggling. It can also be updated via a pubsub interface (tested w/ redis) 2 engines for toggle backing are include

John Calabrese 24 Mar 29, 2022
An SNMP library written in GoLang.

gosnmp GoSNMP is an SNMP client library fully written in Go. It provides Get, GetNext, GetBulk, Walk, BulkWalk, Set and Traps. It supports IPv4 and IP

Go SNMP 857 Jun 28, 2022
Genetic Algorithms library written in Go / golang

Description Genetic Algorithms for Go/Golang Install $ go install git://github.com/thoj/go-galib.git Compiling examples: $ git clone git://github.com

Thomas Jager 192 May 26, 2022
Genetic Algorithms library written in Go / golang

Description Genetic Algorithms for Go/Golang Install $ go install git://github.com/thoj/go-galib.git Compiling examples: $ git clone git://github.com

Thomas Jager 192 May 26, 2022
A user friendly RabbitMQ library written in Golang.

TurboCookedRabbit A user friendly RabbitMQ library written in Golang to help use streadway/amqp. Based on my work found at CookedRabbit. Work Recently

Tristan (HouseCat) Hyams 99 Jun 10, 2022
A captcha library written in golang

gocaptcha 一个简单的Go语言实现的验证码 图片实例 简介 基于Golang实现的图片验证码生成库,可以实现随机字母个数,随机直线,随机噪点等。可以设置任意多字体,每个验证码随机选一种字体展示。 实例 使用: go get github.com/lifei6671/gocaptcha/

Minho 168 Apr 26, 2022
Terminal UI library with rich, interactive widgets — written in Golang

Rich Interactive Widgets for Terminal UIs This Go package provides commonly needed components for terminal based user interfaces. Among these componen

rivo 7k Jun 27, 2022
go-pst is a library for reading PST files (written in Go/Golang).

go-pst A library for reading PST files (written in Go/Golang). Introduction go-pst is a library for reading PST files (written in Go/Golang). The PFF

Mooij Technologies 123 Jun 7, 2022