mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Use Go1.11 module (#5743)
* Migrate to go modules * make vendor * Update mvdan.cc/xurls * make vendor * Update code.gitea.io/git * make fmt-check * Update github.com/go-sql-driver/mysql * make vendor
This commit is contained in:
		
							
								
								
									
										16
									
								
								vendor/gopkg.in/alexcesaro/quotedprintable.v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/gopkg.in/alexcesaro/quotedprintable.v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
# quotedprintable
 | 
			
		||||
 | 
			
		||||
## Introduction
 | 
			
		||||
 | 
			
		||||
Package quotedprintable implements quoted-printable and message header encoding
 | 
			
		||||
as specified by RFC 2045 and RFC 2047.
 | 
			
		||||
 | 
			
		||||
It is a copy of the Go 1.5 package `mime/quotedprintable`. It also includes
 | 
			
		||||
the new functions of package `mime` concerning RFC 2047.
 | 
			
		||||
 | 
			
		||||
This code has minor changes with the standard library code in order to work
 | 
			
		||||
with Go 1.0 and newer. 
 | 
			
		||||
 | 
			
		||||
## Documentation
 | 
			
		||||
 | 
			
		||||
https://godoc.org/gopkg.in/alexcesaro/quotedprintable.v3
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/gopkg.in/asn1-ber.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/gopkg.in/asn1-ber.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
language: go
 | 
			
		||||
go:
 | 
			
		||||
    - 1.2
 | 
			
		||||
    - 1.3
 | 
			
		||||
    - 1.4
 | 
			
		||||
    - 1.5
 | 
			
		||||
    - tip
 | 
			
		||||
go_import_path: gopkg.in/asn-ber.v1
 | 
			
		||||
install:
 | 
			
		||||
    - go list -f '{{range .Imports}}{{.}} {{end}}' ./... | xargs go get -v
 | 
			
		||||
    - go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | xargs go get -v
 | 
			
		||||
    - go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover
 | 
			
		||||
    - go build -v ./...
 | 
			
		||||
script:
 | 
			
		||||
    - go test -v -cover ./...
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/gopkg.in/asn1-ber.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								vendor/gopkg.in/asn1-ber.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
[](https://godoc.org/gopkg.in/asn1-ber.v1) [](https://travis-ci.org/go-asn1-ber/asn1-ber)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ASN1 BER Encoding / Decoding Library for the GO programming language.
 | 
			
		||||
---------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Required libraries: 
 | 
			
		||||
   None
 | 
			
		||||
 | 
			
		||||
Working:
 | 
			
		||||
   Very basic encoding / decoding needed for LDAP protocol
 | 
			
		||||
 | 
			
		||||
Tests Implemented:
 | 
			
		||||
   A few
 | 
			
		||||
 | 
			
		||||
TODO:
 | 
			
		||||
   Fix all encoding / decoding to conform to ASN1 BER spec
 | 
			
		||||
   Implement Tests / Benchmarks
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
 | 
			
		||||
The design is licensed under the Creative Commons 3.0 Attributions license.
 | 
			
		||||
Read this article for more details: http://blog.golang.org/gopher
 | 
			
		||||
							
								
								
									
										11
									
								
								vendor/gopkg.in/bufio.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/gopkg.in/bufio.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
language: go
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - 1.0
 | 
			
		||||
  - 1.1
 | 
			
		||||
  - 1.2
 | 
			
		||||
  - tip
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - go get launchpad.net/gocheck
 | 
			
		||||
  - go get gopkg.in/bufio.v1
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/gopkg.in/bufio.v1/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/gopkg.in/bufio.v1/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
all:
 | 
			
		||||
	go test gopkg.in/bufio.v1
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/gopkg.in/bufio.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								vendor/gopkg.in/bufio.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
bufio
 | 
			
		||||
=====
 | 
			
		||||
 | 
			
		||||
This is a fork of the http://golang.org/pkg/bufio/ package. It adds `ReadN` method that allows reading next `n` bytes from the internal buffer without allocating intermediate buffer. This method works just like the [Buffer.Next](http://golang.org/pkg/bytes/#Buffer.Next) method, but has slightly different signature.
 | 
			
		||||
							
								
								
									
										13
									
								
								vendor/gopkg.in/editorconfig/editorconfig-core-go.v1/.editorconfig
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/gopkg.in/editorconfig/editorconfig-core-go.v1/.editorconfig
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
; http://editorconfig.org/
 | 
			
		||||
 | 
			
		||||
root = true
 | 
			
		||||
 | 
			
		||||
[*]
 | 
			
		||||
end_of_line = lf
 | 
			
		||||
insert_final_newline = true
 | 
			
		||||
charset = utf-8
 | 
			
		||||
trim_trailing_whitespace = true
 | 
			
		||||
 | 
			
		||||
[*.go]
 | 
			
		||||
indent_style = tab
 | 
			
		||||
indent_size = 4
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/gopkg.in/editorconfig/editorconfig-core-go.v1/.gitattributes
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/gopkg.in/editorconfig/editorconfig-core-go.v1/.gitattributes
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
* text eol=lf
 | 
			
		||||
*.jpg binary
 | 
			
		||||
*.jpeg binary
 | 
			
		||||
*.png binary
 | 
			
		||||
*.ico binary
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/gopkg.in/editorconfig/editorconfig-core-go.v1/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/gopkg.in/editorconfig/editorconfig-core-go.v1/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
# ---> Go
 | 
			
		||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
 | 
			
		||||
*.o
 | 
			
		||||
*.a
 | 
			
		||||
*.so
 | 
			
		||||
 | 
			
		||||
# Folders
 | 
			
		||||
_obj
 | 
			
		||||
_test
 | 
			
		||||
 | 
			
		||||
# Architecture specific extensions/prefixes
 | 
			
		||||
*.[568vq]
 | 
			
		||||
[568vq].out
 | 
			
		||||
 | 
			
		||||
*.cgo1.go
 | 
			
		||||
*.cgo2.c
 | 
			
		||||
_cgo_defun.c
 | 
			
		||||
_cgo_gotypes.go
 | 
			
		||||
_cgo_export.*
 | 
			
		||||
 | 
			
		||||
_testmain.go
 | 
			
		||||
 | 
			
		||||
*.exe
 | 
			
		||||
*.test
 | 
			
		||||
*.prof
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										121
									
								
								vendor/gopkg.in/editorconfig/editorconfig-core-go.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								vendor/gopkg.in/editorconfig/editorconfig-core-go.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
[](https://godoc.org/gopkg.in/editorconfig/editorconfig-core-go.v1)
 | 
			
		||||
[](https://goreportcard.com/report/gopkg.in/editorconfig/editorconfig-core-go.v1)
 | 
			
		||||
 | 
			
		||||
# Editorconfig Core Go
 | 
			
		||||
 | 
			
		||||
A [Editorconfig][editorconfig] file parser and manipulator for Go.
 | 
			
		||||
 | 
			
		||||
> This package is already working, but still under testing.
 | 
			
		||||
 | 
			
		||||
## Installing
 | 
			
		||||
 | 
			
		||||
We recommend the use of [gopkg.in][gopkg] for this package:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
go get -u gopkg.in/editorconfig/editorconfig-core-go.v1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Import by the same path. Tha package name you will use to access it is
 | 
			
		||||
`editorconfig`.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
import (
 | 
			
		||||
    "gopkg.in/editorconfig/editorconfig-core-go.v1"
 | 
			
		||||
)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
### Parse from file
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
editorConfig, err := editorconfig.ParseFile("path/to/.editorconfig")
 | 
			
		||||
if err != nil {
 | 
			
		||||
    log.Fatal(err)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Parse from slice of bytes
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
data := []byte("...")
 | 
			
		||||
editorConfig, err := editorconfig.ParseBytes(data)
 | 
			
		||||
if err != nil {
 | 
			
		||||
    log.Fatal(err)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Get definition to a given filename
 | 
			
		||||
 | 
			
		||||
This method builds a definition to a given filename.
 | 
			
		||||
This definition is a merge of the properties with selectors that matched the
 | 
			
		||||
given filename.
 | 
			
		||||
The lasts sections of the file have preference over the priors.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
def := editorConfig.GetDefinitionForFilename("my/file.go")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This definition have the following properties:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Definition struct {
 | 
			
		||||
	Selector string
 | 
			
		||||
 | 
			
		||||
	Charset                string
 | 
			
		||||
	IndentStyle            string
 | 
			
		||||
	IndentSize             string
 | 
			
		||||
	TabWidth               int
 | 
			
		||||
	EndOfLine              string
 | 
			
		||||
	TrimTrailingWhitespace bool
 | 
			
		||||
	InsertFinalNewline     bool
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Automatic search for `.editorconfig` files
 | 
			
		||||
 | 
			
		||||
If you want a definition of a file without having to manually
 | 
			
		||||
parse the `.editorconfig` files, you can then use the static version
 | 
			
		||||
of `GetDefinitionForFilename`:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
def, err := editorconfig.GetDefinitionForFilename("foo/bar/baz/my-file.go")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In the example above, the package will automatically search for
 | 
			
		||||
`.editorconfig` files on:
 | 
			
		||||
 | 
			
		||||
- `foo/bar/baz/.editorconfig`
 | 
			
		||||
- `foo/baz/.editorconfig`
 | 
			
		||||
- `foo/.editorconfig`
 | 
			
		||||
 | 
			
		||||
Until it reaches a file with `root = true` or the root of the filesystem.
 | 
			
		||||
 | 
			
		||||
### Generating a .editorconfig file
 | 
			
		||||
 | 
			
		||||
You can easily convert a Editorconfig struct to a compatible INI file:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// serialize to slice of bytes
 | 
			
		||||
data, err := editorConfig.Serialize()
 | 
			
		||||
if err != nil {
 | 
			
		||||
    log.Fatal(err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// save directly to file
 | 
			
		||||
err := editorConfig.Save("path/to/.editorconfig")
 | 
			
		||||
if err != nil {
 | 
			
		||||
    log.Fatal(err)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
 | 
			
		||||
To run the tests:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
go test -v
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[editorconfig]: http://editorconfig.org/
 | 
			
		||||
[gopkg]: https://gopkg.in
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/gopkg.in/gomail.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/gopkg.in/gomail.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
language: go
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - 1.2
 | 
			
		||||
  - 1.3
 | 
			
		||||
  - 1.4
 | 
			
		||||
  - 1.5
 | 
			
		||||
  - 1.6
 | 
			
		||||
  - tip
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/gopkg.in/gomail.v2/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/gopkg.in/gomail.v2/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
# Change Log
 | 
			
		||||
All notable changes to this project will be documented in this file.
 | 
			
		||||
This project adheres to [Semantic Versioning](http://semver.org/).
 | 
			
		||||
 | 
			
		||||
## [2.0.0] - 2015-09-02
 | 
			
		||||
 | 
			
		||||
- Mailer has been removed. It has been replaced by Dialer and Sender.
 | 
			
		||||
- `File` type and the `CreateFile` and `OpenFile` functions have been removed.
 | 
			
		||||
- `Message.Attach` and `Message.Embed` have a new signature.
 | 
			
		||||
- `Message.GetBodyWriter` has been removed. Use `Message.AddAlternativeWriter`
 | 
			
		||||
instead.
 | 
			
		||||
- `Message.Export` has been removed. `Message.WriteTo` can be used instead.
 | 
			
		||||
- `Message.DelHeader` has been removed.
 | 
			
		||||
- The `Bcc` header field is no longer sent. It is far more simpler and
 | 
			
		||||
efficient: the same message is sent to all recipients instead of sending a
 | 
			
		||||
different email to each Bcc address.
 | 
			
		||||
- LoginAuth has been removed. `NewPlainDialer` now implements the LOGIN
 | 
			
		||||
authentication mechanism when needed.
 | 
			
		||||
- Go 1.2 is now required instead of Go 1.3. No external dependency are used when
 | 
			
		||||
using Go 1.5.
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/gopkg.in/gomail.v2/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/gopkg.in/gomail.v2/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
Thank you for contributing to Gomail! Here are a few guidelines:
 | 
			
		||||
 | 
			
		||||
## Bugs
 | 
			
		||||
 | 
			
		||||
If you think you found a bug, create an issue and supply the minimum amount
 | 
			
		||||
of code triggering the bug so it can be reproduced.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Fixing a bug
 | 
			
		||||
 | 
			
		||||
If you want to fix a bug, you can send a pull request. It should contains a
 | 
			
		||||
new test or update an existing one to cover that bug.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## New feature proposal
 | 
			
		||||
 | 
			
		||||
If you think Gomail lacks a feature, you can open an issue or send a pull
 | 
			
		||||
request. I want to keep Gomail code and API as simple as possible so please
 | 
			
		||||
describe your needs so we can discuss whether this feature should be added to
 | 
			
		||||
Gomail or not.
 | 
			
		||||
							
								
								
									
										92
									
								
								vendor/gopkg.in/gomail.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								vendor/gopkg.in/gomail.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
# Gomail
 | 
			
		||||
[](https://travis-ci.org/go-gomail/gomail) [](http://gocover.io/gopkg.in/gomail.v2) [](https://godoc.org/gopkg.in/gomail.v2)
 | 
			
		||||
 | 
			
		||||
## Introduction
 | 
			
		||||
 | 
			
		||||
Gomail is a simple and efficient package to send emails. It is well tested and
 | 
			
		||||
documented.
 | 
			
		||||
 | 
			
		||||
Gomail can only send emails using an SMTP server. But the API is flexible and it
 | 
			
		||||
is easy to implement other methods for sending emails using a local Postfix, an
 | 
			
		||||
API, etc.
 | 
			
		||||
 | 
			
		||||
It is versioned using [gopkg.in](https://gopkg.in) so I promise
 | 
			
		||||
there will never be backward incompatible changes within each version.
 | 
			
		||||
 | 
			
		||||
It requires Go 1.2 or newer. With Go 1.5, no external dependencies are used.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
Gomail supports:
 | 
			
		||||
- Attachments
 | 
			
		||||
- Embedded images
 | 
			
		||||
- HTML and text templates
 | 
			
		||||
- Automatic encoding of special characters
 | 
			
		||||
- SSL and TLS
 | 
			
		||||
- Sending multiple emails with the same SMTP connection
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Documentation
 | 
			
		||||
 | 
			
		||||
https://godoc.org/gopkg.in/gomail.v2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Download
 | 
			
		||||
 | 
			
		||||
    go get gopkg.in/gomail.v2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Examples
 | 
			
		||||
 | 
			
		||||
See the [examples in the documentation](https://godoc.org/gopkg.in/gomail.v2#example-package).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## FAQ
 | 
			
		||||
 | 
			
		||||
### x509: certificate signed by unknown authority
 | 
			
		||||
 | 
			
		||||
If you get this error it means the certificate used by the SMTP server is not
 | 
			
		||||
considered valid by the client running Gomail. As a quick workaround you can
 | 
			
		||||
bypass the verification of the server's certificate chain and host name by using
 | 
			
		||||
`SetTLSConfig`:
 | 
			
		||||
 | 
			
		||||
    package main
 | 
			
		||||
 | 
			
		||||
    import (
 | 
			
		||||
    	"crypto/tls"
 | 
			
		||||
 | 
			
		||||
    	"gopkg.in/gomail.v2"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    func main() {
 | 
			
		||||
    	d := gomail.NewDialer("smtp.example.com", 587, "user", "123456")
 | 
			
		||||
    	d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
 | 
			
		||||
 | 
			
		||||
        // Send emails using d.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Note, however, that this is insecure and should not be used in production.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Contribute
 | 
			
		||||
 | 
			
		||||
Contributions are more than welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for
 | 
			
		||||
more info.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Change log
 | 
			
		||||
 | 
			
		||||
See [CHANGELOG.md](CHANGELOG.md).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
[MIT](LICENSE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Contact
 | 
			
		||||
 | 
			
		||||
You can ask questions on the [Gomail
 | 
			
		||||
thread](https://groups.google.com/d/topic/golang-nuts/jMxZHzvvEVg/discussion)
 | 
			
		||||
in the Go mailing-list.
 | 
			
		||||
							
								
								
									
										6
									
								
								vendor/gopkg.in/ini.v1/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								vendor/gopkg.in/ini.v1/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
testdata/conf_out.ini
 | 
			
		||||
ini.sublime-project
 | 
			
		||||
ini.sublime-workspace
 | 
			
		||||
testdata/conf_reflect.ini
 | 
			
		||||
.idea
 | 
			
		||||
/.vscode
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/gopkg.in/ini.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/gopkg.in/ini.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
sudo: false
 | 
			
		||||
language: go
 | 
			
		||||
go:
 | 
			
		||||
  - 1.5.x
 | 
			
		||||
  - 1.6.x
 | 
			
		||||
  - 1.7.x
 | 
			
		||||
  - 1.8.x
 | 
			
		||||
  - 1.9.x
 | 
			
		||||
 | 
			
		||||
script: 
 | 
			
		||||
  - go get golang.org/x/tools/cmd/cover
 | 
			
		||||
  - go get github.com/smartystreets/goconvey
 | 
			
		||||
  - mkdir -p $HOME/gopath/src/gopkg.in
 | 
			
		||||
  - ln -s $HOME/gopath/src/github.com/go-ini/ini $HOME/gopath/src/gopkg.in/ini.v1
 | 
			
		||||
  - go test -v -cover -race
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/gopkg.in/ini.v1/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/gopkg.in/ini.v1/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
.PHONY: build test bench vet coverage
 | 
			
		||||
 | 
			
		||||
build: vet bench
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	go test -v -cover -race
 | 
			
		||||
 | 
			
		||||
bench:
 | 
			
		||||
	go test -v -cover -race -test.bench=. -test.benchmem
 | 
			
		||||
 | 
			
		||||
vet:
 | 
			
		||||
	go vet
 | 
			
		||||
 | 
			
		||||
coverage:
 | 
			
		||||
	go test -coverprofile=c.out && go tool cover -html=c.out && rm c.out
 | 
			
		||||
							
								
								
									
										763
									
								
								vendor/gopkg.in/ini.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										763
									
								
								vendor/gopkg.in/ini.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,763 @@
 | 
			
		||||
INI [](https://travis-ci.org/go-ini/ini) [](https://sourcegraph.com/github.com/go-ini/ini?badge)
 | 
			
		||||
===
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Package ini provides INI file read and write functionality in Go.
 | 
			
		||||
 | 
			
		||||
[简体中文](README_ZH.md)
 | 
			
		||||
 | 
			
		||||
## Feature
 | 
			
		||||
 | 
			
		||||
- Load multiple data sources(`[]byte`, file and `io.ReadCloser`) with overwrites.
 | 
			
		||||
- Read with recursion values.
 | 
			
		||||
- Read with parent-child sections.
 | 
			
		||||
- Read with auto-increment key names.
 | 
			
		||||
- Read with multiple-line values.
 | 
			
		||||
- Read with tons of helper methods.
 | 
			
		||||
- Read and convert values to Go types.
 | 
			
		||||
- Read and **WRITE** comments of sections and keys.
 | 
			
		||||
- Manipulate sections, keys and comments with ease.
 | 
			
		||||
- Keep sections and keys in order as you parse and save.
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
To use a tagged revision:
 | 
			
		||||
 | 
			
		||||
	go get gopkg.in/ini.v1
 | 
			
		||||
 | 
			
		||||
To use with latest changes:
 | 
			
		||||
 | 
			
		||||
	go get github.com/go-ini/ini
 | 
			
		||||
 | 
			
		||||
Please add `-u` flag to update in the future.
 | 
			
		||||
 | 
			
		||||
### Testing
 | 
			
		||||
 | 
			
		||||
If you want to test on your machine, please apply `-t` flag:
 | 
			
		||||
 | 
			
		||||
	go get -t gopkg.in/ini.v1
 | 
			
		||||
 | 
			
		||||
Please add `-u` flag to update in the future.
 | 
			
		||||
 | 
			
		||||
## Getting Started
 | 
			
		||||
 | 
			
		||||
### Loading from data sources
 | 
			
		||||
 | 
			
		||||
A **Data Source** is either raw data in type `[]byte`, a file name with type `string` or `io.ReadCloser`. You can load **as many data sources as you want**. Passing other types will simply return an error.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.Load([]byte("raw data"), "filename", ioutil.NopCloser(bytes.NewReader([]byte("some other data"))))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Or start with an empty object:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg := ini.Empty()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When you cannot decide how many data sources to load at the beginning, you will still be able to **Append()** them later.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
err := cfg.Append("other file", []byte("other raw data"))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If you have a list of files with possibilities that some of them may not available at the time, and you don't know exactly which ones, you can use `LooseLoad` to ignore nonexistent files without returning error.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LooseLoad("filename", "filename_404")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The cool thing is, whenever the file is available to load while you're calling `Reload` method, it will be counted as usual.
 | 
			
		||||
 | 
			
		||||
#### Ignore cases of key name
 | 
			
		||||
 | 
			
		||||
When you do not care about cases of section and key names, you can use `InsensitiveLoad` to force all names to be lowercased while parsing.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.InsensitiveLoad("filename")
 | 
			
		||||
//...
 | 
			
		||||
 | 
			
		||||
// sec1 and sec2 are the exactly same section object
 | 
			
		||||
sec1, err := cfg.GetSection("Section")
 | 
			
		||||
sec2, err := cfg.GetSection("SecTIOn")
 | 
			
		||||
 | 
			
		||||
// key1 and key2 are the exactly same key object
 | 
			
		||||
key1, err := sec1.GetKey("Key")
 | 
			
		||||
key2, err := sec2.GetKey("KeY")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### MySQL-like boolean key 
 | 
			
		||||
 | 
			
		||||
MySQL's configuration allows a key without value as follows:
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
[mysqld]
 | 
			
		||||
...
 | 
			
		||||
skip-host-cache
 | 
			
		||||
skip-name-resolve
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
By default, this is considered as missing value. But if you know you're going to deal with those cases, you can assign advanced load options:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LoadSources(ini.LoadOptions{AllowBooleanKeys: true}, "my.cnf"))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The value of those keys are always `true`, and when you save to a file, it will keep in the same foramt as you read.
 | 
			
		||||
 | 
			
		||||
To generate such keys in your program, you could use `NewBooleanKey`:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
key, err := sec.NewBooleanKey("skip-host-cache")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Comment
 | 
			
		||||
 | 
			
		||||
Take care that following format will be treated as comment:
 | 
			
		||||
 | 
			
		||||
1. Line begins with `#` or `;`
 | 
			
		||||
2. Words after `#` or `;`
 | 
			
		||||
3. Words after section name (i.e words after `[some section name]`)
 | 
			
		||||
 | 
			
		||||
If you want to save a value with `#` or `;`, please quote them with ``` ` ``` or ``` """ ```.
 | 
			
		||||
 | 
			
		||||
Alternatively, you can use following `LoadOptions` to completely ignore inline comments:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LoadSources(ini.LoadOptions{IgnoreInlineComment: true}, "app.ini"))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Working with sections
 | 
			
		||||
 | 
			
		||||
To get a section, you would need to:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
section, err := cfg.GetSection("section name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For a shortcut for default section, just give an empty string as name:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
section, err := cfg.GetSection("")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When you're pretty sure the section exists, following code could make your life easier:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
section := cfg.Section("section name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
What happens when the section somehow does not exist? Don't panic, it automatically creates and returns a new section to you.
 | 
			
		||||
 | 
			
		||||
To create a new section:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
err := cfg.NewSection("new section")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To get a list of sections or section names:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
sections := cfg.Sections()
 | 
			
		||||
names := cfg.SectionStrings()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Working with keys
 | 
			
		||||
 | 
			
		||||
To get a key under a section:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
key, err := cfg.Section("").GetKey("key name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Same rule applies to key operations:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
key := cfg.Section("").Key("key name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To check if a key exists:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
yes := cfg.Section("").HasKey("key name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To create a new key:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
err := cfg.Section("").NewKey("name", "value")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To get a list of keys or key names:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
keys := cfg.Section("").Keys()
 | 
			
		||||
names := cfg.Section("").KeyStrings()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To get a clone hash of keys and corresponding values:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
hash := cfg.Section("").KeysHash()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Working with values
 | 
			
		||||
 | 
			
		||||
To get a string value:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
val := cfg.Section("").Key("key name").String()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To validate key value on the fly:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
val := cfg.Section("").Key("key name").Validate(func(in string) string {
 | 
			
		||||
	if len(in) == 0 {
 | 
			
		||||
		return "default"
 | 
			
		||||
	}
 | 
			
		||||
	return in
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If you do not want any auto-transformation (such as recursive read) for the values, you can get raw value directly (this way you get much better performance):
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
val := cfg.Section("").Key("key name").Value()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To check if raw value exists:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
yes := cfg.Section("").HasValue("test value")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To get value with types:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// For boolean values:
 | 
			
		||||
// true when value is: 1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On
 | 
			
		||||
// false when value is: 0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off
 | 
			
		||||
v, err = cfg.Section("").Key("BOOL").Bool()
 | 
			
		||||
v, err = cfg.Section("").Key("FLOAT64").Float64()
 | 
			
		||||
v, err = cfg.Section("").Key("INT").Int()
 | 
			
		||||
v, err = cfg.Section("").Key("INT64").Int64()
 | 
			
		||||
v, err = cfg.Section("").Key("UINT").Uint()
 | 
			
		||||
v, err = cfg.Section("").Key("UINT64").Uint64()
 | 
			
		||||
v, err = cfg.Section("").Key("TIME").TimeFormat(time.RFC3339)
 | 
			
		||||
v, err = cfg.Section("").Key("TIME").Time() // RFC3339
 | 
			
		||||
 | 
			
		||||
v = cfg.Section("").Key("BOOL").MustBool()
 | 
			
		||||
v = cfg.Section("").Key("FLOAT64").MustFloat64()
 | 
			
		||||
v = cfg.Section("").Key("INT").MustInt()
 | 
			
		||||
v = cfg.Section("").Key("INT64").MustInt64()
 | 
			
		||||
v = cfg.Section("").Key("UINT").MustUint()
 | 
			
		||||
v = cfg.Section("").Key("UINT64").MustUint64()
 | 
			
		||||
v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339)
 | 
			
		||||
v = cfg.Section("").Key("TIME").MustTime() // RFC3339
 | 
			
		||||
 | 
			
		||||
// Methods start with Must also accept one argument for default value
 | 
			
		||||
// when key not found or fail to parse value to given type.
 | 
			
		||||
// Except method MustString, which you have to pass a default value.
 | 
			
		||||
 | 
			
		||||
v = cfg.Section("").Key("String").MustString("default")
 | 
			
		||||
v = cfg.Section("").Key("BOOL").MustBool(true)
 | 
			
		||||
v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25)
 | 
			
		||||
v = cfg.Section("").Key("INT").MustInt(10)
 | 
			
		||||
v = cfg.Section("").Key("INT64").MustInt64(99)
 | 
			
		||||
v = cfg.Section("").Key("UINT").MustUint(3)
 | 
			
		||||
v = cfg.Section("").Key("UINT64").MustUint64(6)
 | 
			
		||||
v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now())
 | 
			
		||||
v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
What if my value is three-line long?
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
[advance]
 | 
			
		||||
ADDRESS = """404 road,
 | 
			
		||||
NotFound, State, 5000
 | 
			
		||||
Earth"""
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Not a problem!
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("advance").Key("ADDRESS").String()
 | 
			
		||||
 | 
			
		||||
/* --- start ---
 | 
			
		||||
404 road,
 | 
			
		||||
NotFound, State, 5000
 | 
			
		||||
Earth
 | 
			
		||||
------  end  --- */
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
That's cool, how about continuation lines?
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
[advance]
 | 
			
		||||
two_lines = how about \
 | 
			
		||||
	continuation lines?
 | 
			
		||||
lots_of_lines = 1 \
 | 
			
		||||
	2 \
 | 
			
		||||
	3 \
 | 
			
		||||
	4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Piece of cake!
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("advance").Key("two_lines").String() // how about continuation lines?
 | 
			
		||||
cfg.Section("advance").Key("lots_of_lines").String() // 1 2 3 4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Well, I hate continuation lines, how do I disable that?
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LoadSources(ini.LoadOptions{
 | 
			
		||||
	IgnoreContinuation: true,
 | 
			
		||||
}, "filename")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Holy crap! 
 | 
			
		||||
 | 
			
		||||
Note that single quotes around values will be stripped:
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
foo = "some value" // foo: some value
 | 
			
		||||
bar = 'some value' // bar: some value
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Sometimes you downloaded file from [Crowdin](https://crowdin.com/) has values like the following (value is surrounded by double quotes and quotes in the value are escaped):
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
create_repo="created repository <a href=\"%s\">%s</a>"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
How do you transform this to regular format automatically?
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LoadSources(ini.LoadOptions{UnescapeValueDoubleQuotes: true}, "en-US.ini"))
 | 
			
		||||
cfg.Section("<name of your section>").Key("create_repo").String() 
 | 
			
		||||
// You got: created repository <a href="%s">%s</a>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
That's all? Hmm, no.
 | 
			
		||||
 | 
			
		||||
#### Helper methods of working with values
 | 
			
		||||
 | 
			
		||||
To get value with given candidates:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"})
 | 
			
		||||
v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75})
 | 
			
		||||
v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30})
 | 
			
		||||
v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30})
 | 
			
		||||
v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9})
 | 
			
		||||
v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9})
 | 
			
		||||
v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3})
 | 
			
		||||
v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Default value will be presented if value of key is not in candidates you given, and default value does not need be one of candidates.
 | 
			
		||||
 | 
			
		||||
To validate value in a given range:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
vals = cfg.Section("").Key("FLOAT64").RangeFloat64(0.0, 1.1, 2.2)
 | 
			
		||||
vals = cfg.Section("").Key("INT").RangeInt(0, 10, 20)
 | 
			
		||||
vals = cfg.Section("").Key("INT64").RangeInt64(0, 10, 20)
 | 
			
		||||
vals = cfg.Section("").Key("UINT").RangeUint(0, 3, 9)
 | 
			
		||||
vals = cfg.Section("").Key("UINT64").RangeUint64(0, 3, 9)
 | 
			
		||||
vals = cfg.Section("").Key("TIME").RangeTimeFormat(time.RFC3339, time.Now(), minTime, maxTime)
 | 
			
		||||
vals = cfg.Section("").Key("TIME").RangeTime(time.Now(), minTime, maxTime) // RFC3339
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### Auto-split values into a slice
 | 
			
		||||
 | 
			
		||||
To use zero value of type for invalid inputs:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4]
 | 
			
		||||
// Input: how, 2.2, are, you -> [0.0 2.2 0.0 0.0]
 | 
			
		||||
vals = cfg.Section("").Key("STRINGS").Strings(",")
 | 
			
		||||
vals = cfg.Section("").Key("FLOAT64S").Float64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("INTS").Ints(",")
 | 
			
		||||
vals = cfg.Section("").Key("INT64S").Int64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINTS").Uints(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINT64S").Uint64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("TIMES").Times(",")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To exclude invalid values out of result slice:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4]
 | 
			
		||||
// Input: how, 2.2, are, you -> [2.2]
 | 
			
		||||
vals = cfg.Section("").Key("FLOAT64S").ValidFloat64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("INTS").ValidInts(",")
 | 
			
		||||
vals = cfg.Section("").Key("INT64S").ValidInt64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINTS").ValidUints(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINT64S").ValidUint64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("TIMES").ValidTimes(",")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Or to return nothing but error when have invalid inputs:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4]
 | 
			
		||||
// Input: how, 2.2, are, you -> error
 | 
			
		||||
vals = cfg.Section("").Key("FLOAT64S").StrictFloat64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("INTS").StrictInts(",")
 | 
			
		||||
vals = cfg.Section("").Key("INT64S").StrictInt64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINTS").StrictUints(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINT64S").StrictUint64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("TIMES").StrictTimes(",")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Save your configuration
 | 
			
		||||
 | 
			
		||||
Finally, it's time to save your configuration to somewhere.
 | 
			
		||||
 | 
			
		||||
A typical way to save configuration is writing it to a file:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// ...
 | 
			
		||||
err = cfg.SaveTo("my.ini")
 | 
			
		||||
err = cfg.SaveToIndent("my.ini", "\t")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Another way to save is writing to a `io.Writer` interface:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// ...
 | 
			
		||||
cfg.WriteTo(writer)
 | 
			
		||||
cfg.WriteToIndent(writer, "\t")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
By default, spaces are used to align "=" sign between key and values, to disable that:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
ini.PrettyFormat = false
 | 
			
		||||
``` 
 | 
			
		||||
 | 
			
		||||
## Advanced Usage
 | 
			
		||||
 | 
			
		||||
### Recursive Values
 | 
			
		||||
 | 
			
		||||
For all value of keys, there is a special syntax `%(<name>)s`, where `<name>` is the key name in same section or default section, and `%(<name>)s` will be replaced by corresponding value(empty string if key not found). You can use this syntax at most 99 level of recursions.
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
NAME = ini
 | 
			
		||||
 | 
			
		||||
[author]
 | 
			
		||||
NAME = Unknwon
 | 
			
		||||
GITHUB = https://github.com/%(NAME)s
 | 
			
		||||
 | 
			
		||||
[package]
 | 
			
		||||
FULL_NAME = github.com/go-ini/%(NAME)s
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("author").Key("GITHUB").String()		// https://github.com/Unknwon
 | 
			
		||||
cfg.Section("package").Key("FULL_NAME").String()	// github.com/go-ini/ini
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Parent-child Sections
 | 
			
		||||
 | 
			
		||||
You can use `.` in section name to indicate parent-child relationship between two or more sections. If the key not found in the child section, library will try again on its parent section until there is no parent section.
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
NAME = ini
 | 
			
		||||
VERSION = v1
 | 
			
		||||
IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s
 | 
			
		||||
 | 
			
		||||
[package]
 | 
			
		||||
CLONE_URL = https://%(IMPORT_PATH)s
 | 
			
		||||
 | 
			
		||||
[package.sub]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("package.sub").Key("CLONE_URL").String()	// https://gopkg.in/ini.v1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Retrieve parent keys available to a child section
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("package.sub").ParentKeys() // ["CLONE_URL"]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Unparseable Sections
 | 
			
		||||
 | 
			
		||||
Sometimes, you have sections that do not contain key-value pairs but raw content, to handle such case, you can use `LoadOptions.UnparsableSections`:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LoadSources(ini.LoadOptions{UnparseableSections: []string{"COMMENTS"}}, `[COMMENTS]
 | 
			
		||||
<1><L.Slide#2> This slide has the fuel listed in the wrong units <e.1>`))
 | 
			
		||||
 | 
			
		||||
body := cfg.Section("COMMENTS").Body()
 | 
			
		||||
 | 
			
		||||
/* --- start ---
 | 
			
		||||
<1><L.Slide#2> This slide has the fuel listed in the wrong units <e.1>
 | 
			
		||||
------  end  --- */
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Auto-increment Key Names
 | 
			
		||||
 | 
			
		||||
If key name is `-` in data source, then it would be seen as special syntax for auto-increment key name start from 1, and every section is independent on counter.
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
[features]
 | 
			
		||||
-: Support read/write comments of keys and sections
 | 
			
		||||
-: Support auto-increment of key names
 | 
			
		||||
-: Support load multiple files to overwrite key values
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("features").KeyStrings()	// []{"#1", "#2", "#3"}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Map To Struct
 | 
			
		||||
 | 
			
		||||
Want more objective way to play with INI? Cool.
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
Name = Unknwon
 | 
			
		||||
age = 21
 | 
			
		||||
Male = true
 | 
			
		||||
Born = 1993-01-01T20:17:05Z
 | 
			
		||||
 | 
			
		||||
[Note]
 | 
			
		||||
Content = Hi is a good man!
 | 
			
		||||
Cities = HangZhou, Boston
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Note struct {
 | 
			
		||||
	Content string
 | 
			
		||||
	Cities  []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Person struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	Age  int `ini:"age"`
 | 
			
		||||
	Male bool
 | 
			
		||||
	Born time.Time
 | 
			
		||||
	Note
 | 
			
		||||
	Created time.Time `ini:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	cfg, err := ini.Load("path/to/ini")
 | 
			
		||||
	// ...
 | 
			
		||||
	p := new(Person)
 | 
			
		||||
	err = cfg.MapTo(p)
 | 
			
		||||
	// ...
 | 
			
		||||
 | 
			
		||||
	// Things can be simpler.
 | 
			
		||||
	err = ini.MapTo(p, "path/to/ini")
 | 
			
		||||
	// ...
 | 
			
		||||
 | 
			
		||||
	// Just map a section? Fine.
 | 
			
		||||
	n := new(Note)
 | 
			
		||||
	err = cfg.Section("Note").MapTo(n)
 | 
			
		||||
	// ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Can I have default value for field? Absolutely.
 | 
			
		||||
 | 
			
		||||
Assign it before you map to struct. It will keep the value as it is if the key is not presented or got wrong type.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// ...
 | 
			
		||||
p := &Person{
 | 
			
		||||
	Name: "Joe",
 | 
			
		||||
}
 | 
			
		||||
// ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
It's really cool, but what's the point if you can't give me my file back from struct?
 | 
			
		||||
 | 
			
		||||
### Reflect From Struct
 | 
			
		||||
 | 
			
		||||
Why not?
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Embeded struct {
 | 
			
		||||
	Dates  []time.Time `delim:"|" comment:"Time data"`
 | 
			
		||||
	Places []string    `ini:"places,omitempty"`
 | 
			
		||||
	None   []int       `ini:",omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Author struct {
 | 
			
		||||
	Name      string `ini:"NAME"`
 | 
			
		||||
	Male      bool
 | 
			
		||||
	Age       int `comment:"Author's age"`
 | 
			
		||||
	GPA       float64
 | 
			
		||||
	NeverMind string `ini:"-"`
 | 
			
		||||
	*Embeded `comment:"Embeded section"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	a := &Author{"Unknwon", true, 21, 2.8, "",
 | 
			
		||||
		&Embeded{
 | 
			
		||||
			[]time.Time{time.Now(), time.Now()},
 | 
			
		||||
			[]string{"HangZhou", "Boston"},
 | 
			
		||||
			[]int{},
 | 
			
		||||
		}}
 | 
			
		||||
	cfg := ini.Empty()
 | 
			
		||||
	err = ini.ReflectFrom(cfg, a)
 | 
			
		||||
	// ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
So, what do I get?
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
NAME = Unknwon
 | 
			
		||||
Male = true
 | 
			
		||||
; Author's age
 | 
			
		||||
Age = 21
 | 
			
		||||
GPA = 2.8
 | 
			
		||||
 | 
			
		||||
; Embeded section
 | 
			
		||||
[Embeded]
 | 
			
		||||
; Time data
 | 
			
		||||
Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00
 | 
			
		||||
places = HangZhou,Boston
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Name Mapper
 | 
			
		||||
 | 
			
		||||
To save your time and make your code cleaner, this library supports [`NameMapper`](https://gowalker.org/gopkg.in/ini.v1#NameMapper) between struct field and actual section and key name.
 | 
			
		||||
 | 
			
		||||
There are 2 built-in name mappers:
 | 
			
		||||
 | 
			
		||||
- `AllCapsUnderscore`: it converts to format `ALL_CAPS_UNDERSCORE` then match section or key.
 | 
			
		||||
- `TitleUnderscore`: it converts to format `title_underscore` then match section or key.
 | 
			
		||||
 | 
			
		||||
To use them:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Info struct {
 | 
			
		||||
	PackageName string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	err = ini.MapToWithMapper(&Info{}, ini.TitleUnderscore, []byte("package_name=ini"))
 | 
			
		||||
	// ...
 | 
			
		||||
 | 
			
		||||
	cfg, err := ini.Load([]byte("PACKAGE_NAME=ini"))
 | 
			
		||||
	// ...
 | 
			
		||||
	info := new(Info)
 | 
			
		||||
	cfg.NameMapper = ini.AllCapsUnderscore
 | 
			
		||||
	err = cfg.MapTo(info)
 | 
			
		||||
	// ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Same rules of name mapper apply to `ini.ReflectFromWithMapper` function.
 | 
			
		||||
 | 
			
		||||
#### Value Mapper
 | 
			
		||||
 | 
			
		||||
To expand values (e.g. from environment variables), you can use the `ValueMapper` to transform values:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Env struct {
 | 
			
		||||
	Foo string `ini:"foo"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	cfg, err := ini.Load([]byte("[env]\nfoo = ${MY_VAR}\n")
 | 
			
		||||
	cfg.ValueMapper = os.ExpandEnv
 | 
			
		||||
	// ...
 | 
			
		||||
	env := &Env{}
 | 
			
		||||
	err = cfg.Section("env").MapTo(env)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This would set the value of `env.Foo` to the value of the environment variable `MY_VAR`.
 | 
			
		||||
 | 
			
		||||
#### Other Notes On Map/Reflect
 | 
			
		||||
 | 
			
		||||
Any embedded struct is treated as a section by default, and there is no automatic parent-child relations in map/reflect feature:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Child struct {
 | 
			
		||||
	Age string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Parent struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	Child
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Config struct {
 | 
			
		||||
	City string
 | 
			
		||||
	Parent
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Example configuration:
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
City = Boston
 | 
			
		||||
 | 
			
		||||
[Parent]
 | 
			
		||||
Name = Unknwon
 | 
			
		||||
 | 
			
		||||
[Child]
 | 
			
		||||
Age = 21
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
What if, yes, I'm paranoid, I want embedded struct to be in the same section. Well, all roads lead to Rome.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Child struct {
 | 
			
		||||
	Age string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Parent struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	Child `ini:"Parent"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Config struct {
 | 
			
		||||
	City string
 | 
			
		||||
	Parent
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Example configuration:
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
City = Boston
 | 
			
		||||
 | 
			
		||||
[Parent]
 | 
			
		||||
Name = Unknwon
 | 
			
		||||
Age = 21
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Getting Help
 | 
			
		||||
 | 
			
		||||
- [API Documentation](https://gowalker.org/gopkg.in/ini.v1)
 | 
			
		||||
- [File An Issue](https://github.com/go-ini/ini/issues/new)
 | 
			
		||||
 | 
			
		||||
## FAQs
 | 
			
		||||
 | 
			
		||||
### What does `BlockMode` field do?
 | 
			
		||||
 | 
			
		||||
By default, library lets you read and write values so we need a locker to make sure your data is safe. But in cases that you are very sure about only reading data through the library, you can set `cfg.BlockMode = false` to speed up read operations about **50-70%** faster.
 | 
			
		||||
 | 
			
		||||
### Why another INI library?
 | 
			
		||||
 | 
			
		||||
Many people are using my another INI library [goconfig](https://github.com/Unknwon/goconfig), so the reason for this one is I would like to make more Go style code. Also when you set `cfg.BlockMode = false`, this one is about **10-30%** faster.
 | 
			
		||||
 | 
			
		||||
To make those changes I have to confirm API broken, so it's safer to keep it in another place and start using `gopkg.in` to version my package at this time.(PS: shorter import path)
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text.
 | 
			
		||||
							
								
								
									
										750
									
								
								vendor/gopkg.in/ini.v1/README_ZH.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										750
									
								
								vendor/gopkg.in/ini.v1/README_ZH.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,750 @@
 | 
			
		||||
本包提供了 Go 语言中读写 INI 文件的功能。
 | 
			
		||||
 | 
			
		||||
## 功能特性
 | 
			
		||||
 | 
			
		||||
- 支持覆盖加载多个数据源(`[]byte`、文件和 `io.ReadCloser`)
 | 
			
		||||
- 支持递归读取键值
 | 
			
		||||
- 支持读取父子分区
 | 
			
		||||
- 支持读取自增键名
 | 
			
		||||
- 支持读取多行的键值
 | 
			
		||||
- 支持大量辅助方法
 | 
			
		||||
- 支持在读取时直接转换为 Go 语言类型
 | 
			
		||||
- 支持读取和 **写入** 分区和键的注释
 | 
			
		||||
- 轻松操作分区、键值和注释
 | 
			
		||||
- 在保存文件时分区和键值会保持原有的顺序
 | 
			
		||||
 | 
			
		||||
## 下载安装
 | 
			
		||||
 | 
			
		||||
使用一个特定版本:
 | 
			
		||||
 | 
			
		||||
    go get gopkg.in/ini.v1
 | 
			
		||||
 | 
			
		||||
使用最新版:
 | 
			
		||||
 | 
			
		||||
	go get github.com/go-ini/ini
 | 
			
		||||
 | 
			
		||||
如需更新请添加 `-u` 选项。
 | 
			
		||||
 | 
			
		||||
### 测试安装
 | 
			
		||||
 | 
			
		||||
如果您想要在自己的机器上运行测试,请使用 `-t` 标记:
 | 
			
		||||
 | 
			
		||||
	go get -t gopkg.in/ini.v1
 | 
			
		||||
 | 
			
		||||
如需更新请添加 `-u` 选项。
 | 
			
		||||
 | 
			
		||||
## 开始使用
 | 
			
		||||
 | 
			
		||||
### 从数据源加载
 | 
			
		||||
 | 
			
		||||
一个 **数据源** 可以是 `[]byte` 类型的原始数据,`string` 类型的文件路径或 `io.ReadCloser`。您可以加载 **任意多个** 数据源。如果您传递其它类型的数据源,则会直接返回错误。
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.Load([]byte("raw data"), "filename", ioutil.NopCloser(bytes.NewReader([]byte("some other data"))))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
或者从一个空白的文件开始:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg := ini.Empty()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
当您在一开始无法决定需要加载哪些数据源时,仍可以使用 **Append()** 在需要的时候加载它们。
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
err := cfg.Append("other file", []byte("other raw data"))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
当您想要加载一系列文件,但是不能够确定其中哪些文件是不存在的,可以通过调用函数 `LooseLoad` 来忽略它们(`Load` 会因为文件不存在而返回错误):
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LooseLoad("filename", "filename_404")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
更牛逼的是,当那些之前不存在的文件在重新调用 `Reload` 方法的时候突然出现了,那么它们会被正常加载。
 | 
			
		||||
 | 
			
		||||
#### 忽略键名的大小写
 | 
			
		||||
 | 
			
		||||
有时候分区和键的名称大小写混合非常烦人,这个时候就可以通过 `InsensitiveLoad` 将所有分区和键名在读取里强制转换为小写:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.InsensitiveLoad("filename")
 | 
			
		||||
//...
 | 
			
		||||
 | 
			
		||||
// sec1 和 sec2 指向同一个分区对象
 | 
			
		||||
sec1, err := cfg.GetSection("Section")
 | 
			
		||||
sec2, err := cfg.GetSection("SecTIOn")
 | 
			
		||||
 | 
			
		||||
// key1 和 key2 指向同一个键对象
 | 
			
		||||
key1, err := sec1.GetKey("Key")
 | 
			
		||||
key2, err := sec2.GetKey("KeY")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### 类似 MySQL 配置中的布尔值键
 | 
			
		||||
 | 
			
		||||
MySQL 的配置文件中会出现没有具体值的布尔类型的键:
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
[mysqld]
 | 
			
		||||
...
 | 
			
		||||
skip-host-cache
 | 
			
		||||
skip-name-resolve
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
默认情况下这被认为是缺失值而无法完成解析,但可以通过高级的加载选项对它们进行处理:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LoadSources(ini.LoadOptions{AllowBooleanKeys: true}, "my.cnf"))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
这些键的值永远为 `true`,且在保存到文件时也只会输出键名。
 | 
			
		||||
 | 
			
		||||
如果您想要通过程序来生成此类键,则可以使用 `NewBooleanKey`:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
key, err := sec.NewBooleanKey("skip-host-cache")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### 关于注释
 | 
			
		||||
 | 
			
		||||
下述几种情况的内容将被视为注释:
 | 
			
		||||
 | 
			
		||||
1. 所有以 `#` 或 `;` 开头的行
 | 
			
		||||
2. 所有在 `#` 或 `;` 之后的内容
 | 
			
		||||
3. 分区标签后的文字 (即 `[分区名]` 之后的内容)
 | 
			
		||||
 | 
			
		||||
如果你希望使用包含 `#` 或 `;` 的值,请使用 ``` ` ``` 或 ``` """ ``` 进行包覆。
 | 
			
		||||
 | 
			
		||||
除此之外,您还可以通过 `LoadOptions` 完全忽略行内注释:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LoadSources(ini.LoadOptions{IgnoreInlineComment: true}, "app.ini"))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 操作分区(Section)
 | 
			
		||||
 | 
			
		||||
获取指定分区:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
section, err := cfg.GetSection("section name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
如果您想要获取默认分区,则可以用空字符串代替分区名:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
section, err := cfg.GetSection("")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
当您非常确定某个分区是存在的,可以使用以下简便方法:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
section := cfg.Section("section name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
如果不小心判断错了,要获取的分区其实是不存在的,那会发生什么呢?没事的,它会自动创建并返回一个对应的分区对象给您。
 | 
			
		||||
 | 
			
		||||
创建一个分区:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
err := cfg.NewSection("new section")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
获取所有分区对象或名称:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
sections := cfg.Sections()
 | 
			
		||||
names := cfg.SectionStrings()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 操作键(Key)
 | 
			
		||||
 | 
			
		||||
获取某个分区下的键:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
key, err := cfg.Section("").GetKey("key name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
和分区一样,您也可以直接获取键而忽略错误处理:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
key := cfg.Section("").Key("key name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
判断某个键是否存在:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
yes := cfg.Section("").HasKey("key name")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
创建一个新的键:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
err := cfg.Section("").NewKey("name", "value")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
获取分区下的所有键或键名:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
keys := cfg.Section("").Keys()
 | 
			
		||||
names := cfg.Section("").KeyStrings()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
获取分区下的所有键值对的克隆:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
hash := cfg.Section("").KeysHash()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 操作键值(Value)
 | 
			
		||||
 | 
			
		||||
获取一个类型为字符串(string)的值:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
val := cfg.Section("").Key("key name").String()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
获取值的同时通过自定义函数进行处理验证:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
val := cfg.Section("").Key("key name").Validate(func(in string) string {
 | 
			
		||||
	if len(in) == 0 {
 | 
			
		||||
		return "default"
 | 
			
		||||
	}
 | 
			
		||||
	return in
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
如果您不需要任何对值的自动转变功能(例如递归读取),可以直接获取原值(这种方式性能最佳):
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
val := cfg.Section("").Key("key name").Value()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
判断某个原值是否存在:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
yes := cfg.Section("").HasValue("test value")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
获取其它类型的值:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// 布尔值的规则:
 | 
			
		||||
// true 当值为:1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On
 | 
			
		||||
// false 当值为:0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off
 | 
			
		||||
v, err = cfg.Section("").Key("BOOL").Bool()
 | 
			
		||||
v, err = cfg.Section("").Key("FLOAT64").Float64()
 | 
			
		||||
v, err = cfg.Section("").Key("INT").Int()
 | 
			
		||||
v, err = cfg.Section("").Key("INT64").Int64()
 | 
			
		||||
v, err = cfg.Section("").Key("UINT").Uint()
 | 
			
		||||
v, err = cfg.Section("").Key("UINT64").Uint64()
 | 
			
		||||
v, err = cfg.Section("").Key("TIME").TimeFormat(time.RFC3339)
 | 
			
		||||
v, err = cfg.Section("").Key("TIME").Time() // RFC3339
 | 
			
		||||
 | 
			
		||||
v = cfg.Section("").Key("BOOL").MustBool()
 | 
			
		||||
v = cfg.Section("").Key("FLOAT64").MustFloat64()
 | 
			
		||||
v = cfg.Section("").Key("INT").MustInt()
 | 
			
		||||
v = cfg.Section("").Key("INT64").MustInt64()
 | 
			
		||||
v = cfg.Section("").Key("UINT").MustUint()
 | 
			
		||||
v = cfg.Section("").Key("UINT64").MustUint64()
 | 
			
		||||
v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339)
 | 
			
		||||
v = cfg.Section("").Key("TIME").MustTime() // RFC3339
 | 
			
		||||
 | 
			
		||||
// 由 Must 开头的方法名允许接收一个相同类型的参数来作为默认值,
 | 
			
		||||
// 当键不存在或者转换失败时,则会直接返回该默认值。
 | 
			
		||||
// 但是,MustString 方法必须传递一个默认值。
 | 
			
		||||
 | 
			
		||||
v = cfg.Seciont("").Key("String").MustString("default")
 | 
			
		||||
v = cfg.Section("").Key("BOOL").MustBool(true)
 | 
			
		||||
v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25)
 | 
			
		||||
v = cfg.Section("").Key("INT").MustInt(10)
 | 
			
		||||
v = cfg.Section("").Key("INT64").MustInt64(99)
 | 
			
		||||
v = cfg.Section("").Key("UINT").MustUint(3)
 | 
			
		||||
v = cfg.Section("").Key("UINT64").MustUint64(6)
 | 
			
		||||
v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now())
 | 
			
		||||
v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
如果我的值有好多行怎么办?
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
[advance]
 | 
			
		||||
ADDRESS = """404 road,
 | 
			
		||||
NotFound, State, 5000
 | 
			
		||||
Earth"""
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
嗯哼?小 case!
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("advance").Key("ADDRESS").String()
 | 
			
		||||
 | 
			
		||||
/* --- start ---
 | 
			
		||||
404 road,
 | 
			
		||||
NotFound, State, 5000
 | 
			
		||||
Earth
 | 
			
		||||
------  end  --- */
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
赞爆了!那要是我属于一行的内容写不下想要写到第二行怎么办?
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
[advance]
 | 
			
		||||
two_lines = how about \
 | 
			
		||||
	continuation lines?
 | 
			
		||||
lots_of_lines = 1 \
 | 
			
		||||
	2 \
 | 
			
		||||
	3 \
 | 
			
		||||
	4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
简直是小菜一碟!
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("advance").Key("two_lines").String() // how about continuation lines?
 | 
			
		||||
cfg.Section("advance").Key("lots_of_lines").String() // 1 2 3 4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
可是我有时候觉得两行连在一起特别没劲,怎么才能不自动连接两行呢?
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LoadSources(ini.LoadOptions{
 | 
			
		||||
	IgnoreContinuation: true,
 | 
			
		||||
}, "filename")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
哇靠给力啊!
 | 
			
		||||
 | 
			
		||||
需要注意的是,值两侧的单引号会被自动剔除:
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
foo = "some value" // foo: some value
 | 
			
		||||
bar = 'some value' // bar: some value
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
有时您会获得像从 [Crowdin](https://crowdin.com/) 网站下载的文件那样具有特殊格式的值(值使用双引号括起来,内部的双引号被转义):
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
create_repo="创建了仓库 <a href=\"%s\">%s</a>"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
那么,怎么自动地将这类值进行处理呢?
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := ini.LoadSources(ini.LoadOptions{UnescapeValueDoubleQuotes: true}, "en-US.ini"))
 | 
			
		||||
cfg.Section("<name of your section>").Key("create_repo").String() 
 | 
			
		||||
// You got: 创建了仓库 <a href="%s">%s</a>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
这就是全部了?哈哈,当然不是。
 | 
			
		||||
 | 
			
		||||
#### 操作键值的辅助方法
 | 
			
		||||
 | 
			
		||||
获取键值时设定候选值:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"})
 | 
			
		||||
v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75})
 | 
			
		||||
v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30})
 | 
			
		||||
v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30})
 | 
			
		||||
v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9})
 | 
			
		||||
v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9})
 | 
			
		||||
v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3})
 | 
			
		||||
v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
如果获取到的值不是候选值的任意一个,则会返回默认值,而默认值不需要是候选值中的一员。
 | 
			
		||||
 | 
			
		||||
验证获取的值是否在指定范围内:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
vals = cfg.Section("").Key("FLOAT64").RangeFloat64(0.0, 1.1, 2.2)
 | 
			
		||||
vals = cfg.Section("").Key("INT").RangeInt(0, 10, 20)
 | 
			
		||||
vals = cfg.Section("").Key("INT64").RangeInt64(0, 10, 20)
 | 
			
		||||
vals = cfg.Section("").Key("UINT").RangeUint(0, 3, 9)
 | 
			
		||||
vals = cfg.Section("").Key("UINT64").RangeUint64(0, 3, 9)
 | 
			
		||||
vals = cfg.Section("").Key("TIME").RangeTimeFormat(time.RFC3339, time.Now(), minTime, maxTime)
 | 
			
		||||
vals = cfg.Section("").Key("TIME").RangeTime(time.Now(), minTime, maxTime) // RFC3339
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### 自动分割键值到切片(slice)
 | 
			
		||||
 | 
			
		||||
当存在无效输入时,使用零值代替:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4]
 | 
			
		||||
// Input: how, 2.2, are, you -> [0.0 2.2 0.0 0.0]
 | 
			
		||||
vals = cfg.Section("").Key("STRINGS").Strings(",")
 | 
			
		||||
vals = cfg.Section("").Key("FLOAT64S").Float64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("INTS").Ints(",")
 | 
			
		||||
vals = cfg.Section("").Key("INT64S").Int64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINTS").Uints(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINT64S").Uint64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("TIMES").Times(",")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
从结果切片中剔除无效输入:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4]
 | 
			
		||||
// Input: how, 2.2, are, you -> [2.2]
 | 
			
		||||
vals = cfg.Section("").Key("FLOAT64S").ValidFloat64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("INTS").ValidInts(",")
 | 
			
		||||
vals = cfg.Section("").Key("INT64S").ValidInt64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINTS").ValidUints(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINT64S").ValidUint64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("TIMES").ValidTimes(",")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
当存在无效输入时,直接返回错误:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4]
 | 
			
		||||
// Input: how, 2.2, are, you -> error
 | 
			
		||||
vals = cfg.Section("").Key("FLOAT64S").StrictFloat64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("INTS").StrictInts(",")
 | 
			
		||||
vals = cfg.Section("").Key("INT64S").StrictInt64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINTS").StrictUints(",")
 | 
			
		||||
vals = cfg.Section("").Key("UINT64S").StrictUint64s(",")
 | 
			
		||||
vals = cfg.Section("").Key("TIMES").StrictTimes(",")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 保存配置
 | 
			
		||||
 | 
			
		||||
终于到了这个时刻,是时候保存一下配置了。
 | 
			
		||||
 | 
			
		||||
比较原始的做法是输出配置到某个文件:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// ...
 | 
			
		||||
err = cfg.SaveTo("my.ini")
 | 
			
		||||
err = cfg.SaveToIndent("my.ini", "\t")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
另一个比较高级的做法是写入到任何实现 `io.Writer` 接口的对象中:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// ...
 | 
			
		||||
cfg.WriteTo(writer)
 | 
			
		||||
cfg.WriteToIndent(writer, "\t")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
默认情况下,空格将被用于对齐键值之间的等号以美化输出结果,以下代码可以禁用该功能:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
ini.PrettyFormat = false
 | 
			
		||||
``` 
 | 
			
		||||
 | 
			
		||||
## 高级用法
 | 
			
		||||
 | 
			
		||||
### 递归读取键值
 | 
			
		||||
 | 
			
		||||
在获取所有键值的过程中,特殊语法 `%(<name>)s` 会被应用,其中 `<name>` 可以是相同分区或者默认分区下的键名。字符串 `%(<name>)s` 会被相应的键值所替代,如果指定的键不存在,则会用空字符串替代。您可以最多使用 99 层的递归嵌套。
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
NAME = ini
 | 
			
		||||
 | 
			
		||||
[author]
 | 
			
		||||
NAME = Unknwon
 | 
			
		||||
GITHUB = https://github.com/%(NAME)s
 | 
			
		||||
 | 
			
		||||
[package]
 | 
			
		||||
FULL_NAME = github.com/go-ini/%(NAME)s
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("author").Key("GITHUB").String()		// https://github.com/Unknwon
 | 
			
		||||
cfg.Section("package").Key("FULL_NAME").String()	// github.com/go-ini/ini
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 读取父子分区
 | 
			
		||||
 | 
			
		||||
您可以在分区名称中使用 `.` 来表示两个或多个分区之间的父子关系。如果某个键在子分区中不存在,则会去它的父分区中再次寻找,直到没有父分区为止。
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
NAME = ini
 | 
			
		||||
VERSION = v1
 | 
			
		||||
IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s
 | 
			
		||||
 | 
			
		||||
[package]
 | 
			
		||||
CLONE_URL = https://%(IMPORT_PATH)s
 | 
			
		||||
 | 
			
		||||
[package.sub]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("package.sub").Key("CLONE_URL").String()	// https://gopkg.in/ini.v1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### 获取上级父分区下的所有键名
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("package.sub").ParentKeys() // ["CLONE_URL"]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 无法解析的分区
 | 
			
		||||
 | 
			
		||||
如果遇到一些比较特殊的分区,它们不包含常见的键值对,而是没有固定格式的纯文本,则可以使用 `LoadOptions.UnparsableSections` 进行处理:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg, err := LoadSources(ini.LoadOptions{UnparseableSections: []string{"COMMENTS"}}, `[COMMENTS]
 | 
			
		||||
<1><L.Slide#2> This slide has the fuel listed in the wrong units <e.1>`))
 | 
			
		||||
 | 
			
		||||
body := cfg.Section("COMMENTS").Body()
 | 
			
		||||
 | 
			
		||||
/* --- start ---
 | 
			
		||||
<1><L.Slide#2> This slide has the fuel listed in the wrong units <e.1>
 | 
			
		||||
------  end  --- */
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 读取自增键名
 | 
			
		||||
 | 
			
		||||
如果数据源中的键名为 `-`,则认为该键使用了自增键名的特殊语法。计数器从 1 开始,并且分区之间是相互独立的。
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
[features]
 | 
			
		||||
-: Support read/write comments of keys and sections
 | 
			
		||||
-: Support auto-increment of key names
 | 
			
		||||
-: Support load multiple files to overwrite key values
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
cfg.Section("features").KeyStrings()	// []{"#1", "#2", "#3"}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### 映射到结构
 | 
			
		||||
 | 
			
		||||
想要使用更加面向对象的方式玩转 INI 吗?好主意。
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
Name = Unknwon
 | 
			
		||||
age = 21
 | 
			
		||||
Male = true
 | 
			
		||||
Born = 1993-01-01T20:17:05Z
 | 
			
		||||
 | 
			
		||||
[Note]
 | 
			
		||||
Content = Hi is a good man!
 | 
			
		||||
Cities = HangZhou, Boston
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Note struct {
 | 
			
		||||
	Content string
 | 
			
		||||
	Cities  []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Person struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	Age  int `ini:"age"`
 | 
			
		||||
	Male bool
 | 
			
		||||
	Born time.Time
 | 
			
		||||
	Note
 | 
			
		||||
	Created time.Time `ini:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	cfg, err := ini.Load("path/to/ini")
 | 
			
		||||
	// ...
 | 
			
		||||
	p := new(Person)
 | 
			
		||||
	err = cfg.MapTo(p)
 | 
			
		||||
	// ...
 | 
			
		||||
 | 
			
		||||
	// 一切竟可以如此的简单。
 | 
			
		||||
	err = ini.MapTo(p, "path/to/ini")
 | 
			
		||||
	// ...
 | 
			
		||||
 | 
			
		||||
	// 嗯哼?只需要映射一个分区吗?
 | 
			
		||||
	n := new(Note)
 | 
			
		||||
	err = cfg.Section("Note").MapTo(n)
 | 
			
		||||
	// ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
结构的字段怎么设置默认值呢?很简单,只要在映射之前对指定字段进行赋值就可以了。如果键未找到或者类型错误,该值不会发生改变。
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// ...
 | 
			
		||||
p := &Person{
 | 
			
		||||
	Name: "Joe",
 | 
			
		||||
}
 | 
			
		||||
// ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
这样玩 INI 真的好酷啊!然而,如果不能还给我原来的配置文件,有什么卵用?
 | 
			
		||||
 | 
			
		||||
### 从结构反射
 | 
			
		||||
 | 
			
		||||
可是,我有说不能吗?
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Embeded struct {
 | 
			
		||||
	Dates  []time.Time `delim:"|" comment:"Time data"`
 | 
			
		||||
	Places []string    `ini:"places,omitempty"`
 | 
			
		||||
	None   []int       `ini:",omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Author struct {
 | 
			
		||||
	Name      string `ini:"NAME"`
 | 
			
		||||
	Male      bool
 | 
			
		||||
	Age       int `comment:"Author's age"`
 | 
			
		||||
	GPA       float64
 | 
			
		||||
	NeverMind string `ini:"-"`
 | 
			
		||||
	*Embeded `comment:"Embeded section"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	a := &Author{"Unknwon", true, 21, 2.8, "",
 | 
			
		||||
		&Embeded{
 | 
			
		||||
			[]time.Time{time.Now(), time.Now()},
 | 
			
		||||
			[]string{"HangZhou", "Boston"},
 | 
			
		||||
			[]int{},
 | 
			
		||||
		}}
 | 
			
		||||
	cfg := ini.Empty()
 | 
			
		||||
	err = ini.ReflectFrom(cfg, a)
 | 
			
		||||
	// ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
瞧瞧,奇迹发生了。
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
NAME = Unknwon
 | 
			
		||||
Male = true
 | 
			
		||||
; Author's age
 | 
			
		||||
Age = 21
 | 
			
		||||
GPA = 2.8
 | 
			
		||||
 | 
			
		||||
; Embeded section
 | 
			
		||||
[Embeded]
 | 
			
		||||
; Time data
 | 
			
		||||
Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00
 | 
			
		||||
places = HangZhou,Boston
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### 名称映射器(Name Mapper)
 | 
			
		||||
 | 
			
		||||
为了节省您的时间并简化代码,本库支持类型为 [`NameMapper`](https://gowalker.org/gopkg.in/ini.v1#NameMapper) 的名称映射器,该映射器负责结构字段名与分区名和键名之间的映射。
 | 
			
		||||
 | 
			
		||||
目前有 2 款内置的映射器:
 | 
			
		||||
 | 
			
		||||
- `AllCapsUnderscore`:该映射器将字段名转换至格式 `ALL_CAPS_UNDERSCORE` 后再去匹配分区名和键名。
 | 
			
		||||
- `TitleUnderscore`:该映射器将字段名转换至格式 `title_underscore` 后再去匹配分区名和键名。
 | 
			
		||||
 | 
			
		||||
使用方法:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Info struct{
 | 
			
		||||
	PackageName string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	err = ini.MapToWithMapper(&Info{}, ini.TitleUnderscore, []byte("package_name=ini"))
 | 
			
		||||
	// ...
 | 
			
		||||
 | 
			
		||||
	cfg, err := ini.Load([]byte("PACKAGE_NAME=ini"))
 | 
			
		||||
	// ...
 | 
			
		||||
	info := new(Info)
 | 
			
		||||
	cfg.NameMapper = ini.AllCapsUnderscore
 | 
			
		||||
	err = cfg.MapTo(info)
 | 
			
		||||
	// ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
使用函数 `ini.ReflectFromWithMapper` 时也可应用相同的规则。
 | 
			
		||||
 | 
			
		||||
#### 值映射器(Value Mapper)
 | 
			
		||||
 | 
			
		||||
值映射器允许使用一个自定义函数自动展开值的具体内容,例如:运行时获取环境变量:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Env struct {
 | 
			
		||||
	Foo string `ini:"foo"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	cfg, err := ini.Load([]byte("[env]\nfoo = ${MY_VAR}\n")
 | 
			
		||||
	cfg.ValueMapper = os.ExpandEnv
 | 
			
		||||
	// ...
 | 
			
		||||
	env := &Env{}
 | 
			
		||||
	err = cfg.Section("env").MapTo(env)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
本例中,`env.Foo` 将会是运行时所获取到环境变量 `MY_VAR` 的值。
 | 
			
		||||
 | 
			
		||||
#### 映射/反射的其它说明
 | 
			
		||||
 | 
			
		||||
任何嵌入的结构都会被默认认作一个不同的分区,并且不会自动产生所谓的父子分区关联:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Child struct {
 | 
			
		||||
	Age string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Parent struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	Child
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Config struct {
 | 
			
		||||
	City string
 | 
			
		||||
	Parent
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
示例配置文件:
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
City = Boston
 | 
			
		||||
 | 
			
		||||
[Parent]
 | 
			
		||||
Name = Unknwon
 | 
			
		||||
 | 
			
		||||
[Child]
 | 
			
		||||
Age = 21
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
很好,但是,我就是要嵌入结构也在同一个分区。好吧,你爹是李刚!
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Child struct {
 | 
			
		||||
	Age string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Parent struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	Child `ini:"Parent"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Config struct {
 | 
			
		||||
	City string
 | 
			
		||||
	Parent
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
示例配置文件:
 | 
			
		||||
 | 
			
		||||
```ini
 | 
			
		||||
City = Boston
 | 
			
		||||
 | 
			
		||||
[Parent]
 | 
			
		||||
Name = Unknwon
 | 
			
		||||
Age = 21
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 获取帮助
 | 
			
		||||
 | 
			
		||||
- [API 文档](https://gowalker.org/gopkg.in/ini.v1)
 | 
			
		||||
- [创建工单](https://github.com/go-ini/ini/issues/new)
 | 
			
		||||
 | 
			
		||||
## 常见问题
 | 
			
		||||
 | 
			
		||||
### 字段 `BlockMode` 是什么?
 | 
			
		||||
 | 
			
		||||
默认情况下,本库会在您进行读写操作时采用锁机制来确保数据时间。但在某些情况下,您非常确定只进行读操作。此时,您可以通过设置 `cfg.BlockMode = false` 来将读操作提升大约 **50-70%** 的性能。
 | 
			
		||||
 | 
			
		||||
### 为什么要写另一个 INI 解析库?
 | 
			
		||||
 | 
			
		||||
许多人都在使用我的 [goconfig](https://github.com/Unknwon/goconfig) 来完成对 INI 文件的操作,但我希望使用更加 Go 风格的代码。并且当您设置 `cfg.BlockMode = false` 时,会有大约 **10-30%** 的性能提升。
 | 
			
		||||
 | 
			
		||||
为了做出这些改变,我必须对 API 进行破坏,所以新开一个仓库是最安全的做法。除此之外,本库直接使用 `gopkg.in` 来进行版本化发布。(其实真相是导入路径更短了)
 | 
			
		||||
							
								
								
									
										0
									
								
								vendor/gopkg.in/ldap.v3/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								vendor/gopkg.in/ldap.v3/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										32
									
								
								vendor/gopkg.in/ldap.v3/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								vendor/gopkg.in/ldap.v3/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
sudo: false
 | 
			
		||||
language: go
 | 
			
		||||
go:
 | 
			
		||||
    - "1.4.x"
 | 
			
		||||
    - "1.5.x"
 | 
			
		||||
    - "1.6.x"
 | 
			
		||||
    - "1.7.x"
 | 
			
		||||
    - "1.8.x"
 | 
			
		||||
    - "1.9.x"
 | 
			
		||||
    - "1.10.x"
 | 
			
		||||
    - "1.11.x"
 | 
			
		||||
    - "1.12.x"
 | 
			
		||||
    - tip
 | 
			
		||||
 | 
			
		||||
git:
 | 
			
		||||
  depth: 1
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
    fast_finish: true
 | 
			
		||||
    allow_failures:
 | 
			
		||||
        - go: tip
 | 
			
		||||
go_import_path: gopkg.in/ldap.v3
 | 
			
		||||
install:
 | 
			
		||||
    - go get gopkg.in/asn1-ber.v1
 | 
			
		||||
    - go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover
 | 
			
		||||
    - go get github.com/golang/lint/golint || go get golang.org/x/lint/golint || true
 | 
			
		||||
    - go build -v ./...
 | 
			
		||||
script:
 | 
			
		||||
    - make test
 | 
			
		||||
    - make fmt
 | 
			
		||||
    - make vet
 | 
			
		||||
    - make lint
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/gopkg.in/ldap.v3/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/gopkg.in/ldap.v3/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
# Contribution Guidelines
 | 
			
		||||
 | 
			
		||||
We welcome contribution and improvements.
 | 
			
		||||
 | 
			
		||||
## Guiding Principles
 | 
			
		||||
 | 
			
		||||
To begin with here is a draft from an email exchange:
 | 
			
		||||
 | 
			
		||||
 * take compatibility seriously (our semvers, compatibility with older go versions, etc)
 | 
			
		||||
 * don't tag untested code for release
 | 
			
		||||
 * beware of baking in implicit behavior based on other libraries/tools choices
 | 
			
		||||
 * be as high-fidelity as possible in plumbing through LDAP data (don't mask errors or reduce power of someone using the library)
 | 
			
		||||
							
								
								
									
										82
									
								
								vendor/gopkg.in/ldap.v3/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								vendor/gopkg.in/ldap.v3/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
.PHONY: default install build test quicktest fmt vet lint 
 | 
			
		||||
 | 
			
		||||
# List of all release tags "supported" by our current Go version
 | 
			
		||||
# E.g. ":go1.1:go1.2:go1.3:go1.4:go1.5:go1.6:go1.7:go1.8:go1.9:go1.10:go1.11:go1.12:"
 | 
			
		||||
GO_RELEASE_TAGS := $(shell go list -f ':{{join (context.ReleaseTags) ":"}}:' runtime)
 | 
			
		||||
 | 
			
		||||
# Only use the `-race` flag on newer versions of Go (version 1.3 and newer)
 | 
			
		||||
ifeq (,$(findstring :go1.3:,$(GO_RELEASE_TAGS)))
 | 
			
		||||
	RACE_FLAG :=
 | 
			
		||||
else
 | 
			
		||||
	RACE_FLAG := -race -cpu 1,2,4
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Run `go vet` on Go 1.12 and newer. For Go 1.5-1.11, use `go tool vet`
 | 
			
		||||
ifneq (,$(findstring :go1.12:,$(GO_RELEASE_TAGS)))
 | 
			
		||||
	GO_VET := go vet \
 | 
			
		||||
		-atomic \
 | 
			
		||||
		-bool \
 | 
			
		||||
		-copylocks \
 | 
			
		||||
		-nilfunc \
 | 
			
		||||
		-printf \
 | 
			
		||||
		-rangeloops \
 | 
			
		||||
		-unreachable \
 | 
			
		||||
		-unsafeptr \
 | 
			
		||||
		-unusedresult \
 | 
			
		||||
		.
 | 
			
		||||
else ifneq (,$(findstring :go1.5:,$(GO_RELEASE_TAGS)))
 | 
			
		||||
	GO_VET := go tool vet \
 | 
			
		||||
		-atomic \
 | 
			
		||||
		-bool \
 | 
			
		||||
		-copylocks \
 | 
			
		||||
		-nilfunc \
 | 
			
		||||
		-printf \
 | 
			
		||||
		-shadow \
 | 
			
		||||
		-rangeloops \
 | 
			
		||||
		-unreachable \
 | 
			
		||||
		-unsafeptr \
 | 
			
		||||
		-unusedresult \
 | 
			
		||||
		.
 | 
			
		||||
else
 | 
			
		||||
	GO_VET := @echo "go vet skipped -- not supported on this version of Go"
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
default: fmt vet lint build quicktest
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
	go get -t -v ./...
 | 
			
		||||
 | 
			
		||||
build:
 | 
			
		||||
	go build -v ./...
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	go test -v $(RACE_FLAG) -cover ./...
 | 
			
		||||
 | 
			
		||||
quicktest:
 | 
			
		||||
	go test ./...
 | 
			
		||||
 | 
			
		||||
# Capture output and force failure when there is non-empty output
 | 
			
		||||
fmt:
 | 
			
		||||
	@echo gofmt -l .
 | 
			
		||||
	@OUTPUT=`gofmt -l . 2>&1`; \
 | 
			
		||||
	if [ "$$OUTPUT" ]; then \
 | 
			
		||||
		echo "gofmt must be run on the following files:"; \
 | 
			
		||||
		echo "$$OUTPUT"; \
 | 
			
		||||
		exit 1; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
vet:
 | 
			
		||||
	$(GO_VET)
 | 
			
		||||
 | 
			
		||||
# https://github.com/golang/lint
 | 
			
		||||
# go get github.com/golang/lint/golint
 | 
			
		||||
# Capture output and force failure when there is non-empty output
 | 
			
		||||
# Only run on go1.5+
 | 
			
		||||
lint:
 | 
			
		||||
	@echo golint ./...
 | 
			
		||||
	@OUTPUT=`command -v golint >/dev/null 2>&1 && golint ./... 2>&1`; \
 | 
			
		||||
	if [ "$$OUTPUT" ]; then \
 | 
			
		||||
		echo "golint errors:"; \
 | 
			
		||||
		echo "$$OUTPUT"; \
 | 
			
		||||
		exit 1; \
 | 
			
		||||
	fi
 | 
			
		||||
							
								
								
									
										54
									
								
								vendor/gopkg.in/ldap.v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								vendor/gopkg.in/ldap.v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
[](https://godoc.org/gopkg.in/ldap.v3)
 | 
			
		||||
[](https://travis-ci.org/go-ldap/ldap)
 | 
			
		||||
 | 
			
		||||
# Basic LDAP v3 functionality for the GO programming language.
 | 
			
		||||
 | 
			
		||||
## Install
 | 
			
		||||
 | 
			
		||||
For the latest version use:
 | 
			
		||||
 | 
			
		||||
    go get gopkg.in/ldap.v3
 | 
			
		||||
 | 
			
		||||
Import the latest version with:
 | 
			
		||||
 | 
			
		||||
    import "gopkg.in/ldap.v3"
 | 
			
		||||
 | 
			
		||||
## Required Libraries:
 | 
			
		||||
 | 
			
		||||
 - gopkg.in/asn1-ber.v1
 | 
			
		||||
 | 
			
		||||
## Features:
 | 
			
		||||
 | 
			
		||||
 - Connecting to LDAP server (non-TLS, TLS, STARTTLS)
 | 
			
		||||
 - Binding to LDAP server
 | 
			
		||||
 - Searching for entries
 | 
			
		||||
 - Filter Compile / Decompile
 | 
			
		||||
 - Paging Search Results
 | 
			
		||||
 - Modify Requests / Responses
 | 
			
		||||
 - Add Requests / Responses
 | 
			
		||||
 - Delete Requests / Responses
 | 
			
		||||
 - Modify DN Requests / Responses
 | 
			
		||||
 | 
			
		||||
## Examples:
 | 
			
		||||
 | 
			
		||||
 - search
 | 
			
		||||
 - modify
 | 
			
		||||
 | 
			
		||||
## Contributing:
 | 
			
		||||
 | 
			
		||||
Bug reports and pull requests are welcome!
 | 
			
		||||
 | 
			
		||||
Before submitting a pull request, please make sure tests and verification scripts pass:
 | 
			
		||||
```
 | 
			
		||||
make all
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To set up a pre-push hook to run the tests and verify scripts before pushing:
 | 
			
		||||
```
 | 
			
		||||
ln -s ../../.githooks/pre-push .git/hooks/pre-push
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
 | 
			
		||||
The design is licensed under the Creative Commons 3.0 Attributions license.
 | 
			
		||||
Read this article for more details: http://blog.golang.org/gopher
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/gopkg.in/ldap.v3/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/gopkg.in/ldap.v3/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -207,7 +207,7 @@ func GetLDAPError(packet *ber.Packet) error {
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
			return &Error{ResultCode: resultCode, MatchedDN: response.Children[1].Value.(string),
 | 
			
		||||
				Err: fmt.Errorf(response.Children[2].Value.(string))}
 | 
			
		||||
				Err: fmt.Errorf("%s", response.Children[2].Value.(string))}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/gopkg.in/macaron.v1/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/gopkg.in/macaron.v1/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
macaron.sublime-project
 | 
			
		||||
macaron.sublime-workspace
 | 
			
		||||
.idea
 | 
			
		||||
							
								
								
									
										11
									
								
								vendor/gopkg.in/macaron.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/gopkg.in/macaron.v1/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
sudo: false
 | 
			
		||||
language: go
 | 
			
		||||
go:
 | 
			
		||||
  - 1.6.x
 | 
			
		||||
  - 1.7.x
 | 
			
		||||
  - 1.8.x
 | 
			
		||||
  - 1.9.x
 | 
			
		||||
  - 1.10.x
 | 
			
		||||
  - 1.11.x
 | 
			
		||||
 | 
			
		||||
script: go test -v -cover -race
 | 
			
		||||
							
								
								
									
										93
									
								
								vendor/gopkg.in/macaron.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								vendor/gopkg.in/macaron.v1/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,93 @@
 | 
			
		||||
Macaron [](https://travis-ci.org/go-macaron/macaron)
 | 
			
		||||
=======================
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Package macaron is a high productive and modular web framework in Go.
 | 
			
		||||
 | 
			
		||||
## Getting Started
 | 
			
		||||
 | 
			
		||||
The minimum requirement of Go is **1.6**.
 | 
			
		||||
 | 
			
		||||
To install Macaron:
 | 
			
		||||
 | 
			
		||||
	go get gopkg.in/macaron.v1
 | 
			
		||||
 | 
			
		||||
The very basic usage of Macaron:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import "gopkg.in/macaron.v1"
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	m := macaron.Classic()
 | 
			
		||||
	m.Get("/", func() string {
 | 
			
		||||
		return "Hello world!"
 | 
			
		||||
	})
 | 
			
		||||
	m.Run()
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
- Powerful routing with suburl.
 | 
			
		||||
- Flexible routes combinations.
 | 
			
		||||
- Unlimited nested group routers.
 | 
			
		||||
- Directly integrate with existing services.
 | 
			
		||||
- Dynamically change template files at runtime.
 | 
			
		||||
- Allow to use in-memory template and static files.
 | 
			
		||||
- Easy to plugin/unplugin features with modular design.
 | 
			
		||||
- Handy dependency injection powered by [inject](https://github.com/codegangsta/inject).
 | 
			
		||||
- Better router layer and less reflection make faster speed.
 | 
			
		||||
 | 
			
		||||
## Middlewares
 | 
			
		||||
 | 
			
		||||
Middlewares allow you easily plugin/unplugin features for your Macaron applications.
 | 
			
		||||
 | 
			
		||||
There are already many [middlewares](https://github.com/go-macaron) to simplify your work:
 | 
			
		||||
 | 
			
		||||
- render - Go template engine
 | 
			
		||||
- static - Serves static files
 | 
			
		||||
- [gzip](https://github.com/go-macaron/gzip) - Gzip compression to all responses
 | 
			
		||||
- [binding](https://github.com/go-macaron/binding) - Request data binding and validation
 | 
			
		||||
- [i18n](https://github.com/go-macaron/i18n) - Internationalization and Localization
 | 
			
		||||
- [cache](https://github.com/go-macaron/cache) - Cache manager
 | 
			
		||||
- [session](https://github.com/go-macaron/session) - Session manager
 | 
			
		||||
- [csrf](https://github.com/go-macaron/csrf) - Generates and validates csrf tokens
 | 
			
		||||
- [captcha](https://github.com/go-macaron/captcha) - Captcha service
 | 
			
		||||
- [pongo2](https://github.com/go-macaron/pongo2) - Pongo2 template engine support
 | 
			
		||||
- [sockets](https://github.com/go-macaron/sockets) - WebSockets channels binding
 | 
			
		||||
- [bindata](https://github.com/go-macaron/bindata) - Embed binary data as static and template files
 | 
			
		||||
- [toolbox](https://github.com/go-macaron/toolbox) - Health check, pprof, profile and statistic services
 | 
			
		||||
- [oauth2](https://github.com/go-macaron/oauth2) - OAuth 2.0 backend
 | 
			
		||||
- [authz](https://github.com/go-macaron/authz) - ACL/RBAC/ABAC authorization based on Casbin
 | 
			
		||||
- [switcher](https://github.com/go-macaron/switcher) - Multiple-site support
 | 
			
		||||
- [method](https://github.com/go-macaron/method) - HTTP method override
 | 
			
		||||
- [permissions2](https://github.com/xyproto/permissions2) - Cookies, users and permissions
 | 
			
		||||
- [renders](https://github.com/go-macaron/renders) - Beego-like render engine(Macaron has built-in template engine, this is another option)
 | 
			
		||||
- [piwik](https://github.com/veecue/piwik-middleware) - Server-side piwik analytics
 | 
			
		||||
 | 
			
		||||
## Use Cases
 | 
			
		||||
 | 
			
		||||
- [Gogs](https://gogs.io): A painless self-hosted Git Service
 | 
			
		||||
- [Grafana](http://grafana.org/): The open platform for beautiful analytics and monitoring
 | 
			
		||||
- [Peach](https://peachdocs.org): A modern web documentation server
 | 
			
		||||
- [Go Walker](https://gowalker.org): Go online API documentation
 | 
			
		||||
- [Switch](https://gopm.io): Gopm registry
 | 
			
		||||
- [Critical Stack Intel](https://intel.criticalstack.com/): A 100% free intel marketplace from Critical Stack, Inc.
 | 
			
		||||
 | 
			
		||||
## Getting Help
 | 
			
		||||
 | 
			
		||||
- [API Reference](https://gowalker.org/gopkg.in/macaron.v1)
 | 
			
		||||
- [Documentation](https://go-macaron.com)
 | 
			
		||||
- [FAQs](https://go-macaron.com/docs/faqs)
 | 
			
		||||
 | 
			
		||||
## Credits
 | 
			
		||||
 | 
			
		||||
- Basic design of [Martini](https://github.com/go-martini/martini).
 | 
			
		||||
- Logo is modified by [@insionng](https://github.com/insionng) based on [Tribal Dragon](http://xtremeyamazaki.deviantart.com/art/Tribal-Dragon-27005087).
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/gopkg.in/macaron.v1/fixtures/symlink
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/gopkg.in/macaron.v1/fixtures/symlink
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
basic
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								vendor/gopkg.in/macaron.v1/macaronlogo.png
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								vendor/gopkg.in/macaron.v1/macaronlogo.png
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 87 KiB  | 
							
								
								
									
										19
									
								
								vendor/gopkg.in/redis.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/gopkg.in/redis.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
language: go
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
- redis-server
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - 1.1
 | 
			
		||||
  - 1.2
 | 
			
		||||
  - 1.3
 | 
			
		||||
  - tip
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - go get gopkg.in/bufio.v1
 | 
			
		||||
  - go get gopkg.in/check.v1
 | 
			
		||||
  - mkdir -p $HOME/gopath/src/gopkg.in
 | 
			
		||||
  - ln -s `pwd` $HOME/gopath/src/gopkg.in/redis.v2
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - redis-server testdata/sentinel.conf --sentinel &
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/gopkg.in/redis.v2/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/gopkg.in/redis.v2/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
all:
 | 
			
		||||
	go test gopkg.in/redis.v2 -cpu=1,2,4
 | 
			
		||||
	go test gopkg.in/redis.v2 -short -race
 | 
			
		||||
							
								
								
									
										46
									
								
								vendor/gopkg.in/redis.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/gopkg.in/redis.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
Redis client for Golang [](https://travis-ci.org/go-redis/redis)
 | 
			
		||||
=======================
 | 
			
		||||
 | 
			
		||||
Supports:
 | 
			
		||||
 | 
			
		||||
- Redis 2.8 commands except QUIT, MONITOR, SLOWLOG and SYNC.
 | 
			
		||||
- Pub/sub.
 | 
			
		||||
- Transactions.
 | 
			
		||||
- Pipelining.
 | 
			
		||||
- Connection pool.
 | 
			
		||||
- TLS connections.
 | 
			
		||||
- Thread safety.
 | 
			
		||||
- Timeouts.
 | 
			
		||||
- Redis Sentinel.
 | 
			
		||||
 | 
			
		||||
API docs: http://godoc.org/gopkg.in/redis.v2.
 | 
			
		||||
Examples: http://godoc.org/gopkg.in/redis.v2#pkg-examples.
 | 
			
		||||
 | 
			
		||||
Installation
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
Install:
 | 
			
		||||
 | 
			
		||||
    go get gopkg.in/redis.v2
 | 
			
		||||
 | 
			
		||||
Look and feel
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
Some corner cases:
 | 
			
		||||
 | 
			
		||||
    SORT list LIMIT 0 2 ASC
 | 
			
		||||
    vals, err := client.Sort("list", redis.Sort{Offset: 0, Count: 2, Order: "ASC"}).Result()
 | 
			
		||||
 | 
			
		||||
    ZRANGEBYSCORE zset -inf +inf WITHSCORES LIMIT 0 2
 | 
			
		||||
    vals, err := client.ZRangeByScoreWithScores("zset", redis.ZRangeByScore{
 | 
			
		||||
        Min: "-inf",
 | 
			
		||||
        Max: "+inf",
 | 
			
		||||
        Offset: 0,
 | 
			
		||||
        Count: 2,
 | 
			
		||||
    }).Result()
 | 
			
		||||
 | 
			
		||||
    ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3 AGGREGATE SUM
 | 
			
		||||
    vals, err := client.ZInterStore("out", redis.ZStore{Weights: []int64{2, 3}}, "zset1", "zset2").Result()
 | 
			
		||||
 | 
			
		||||
    EVAL "return {KEYS[1],ARGV[1]}" 1 "key" "hello"
 | 
			
		||||
    vals, err := client.Eval("return {KEYS[1],ARGV[1]}", []string{"key"}, []string{"hello"}).Result()
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/gopkg.in/src-d/go-billy.v4/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/gopkg.in/src-d/go-billy.v4/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
/coverage.txt
 | 
			
		||||
/vendor
 | 
			
		||||
Gopkg.lock
 | 
			
		||||
Gopkg.toml
 | 
			
		||||
go.sum
 | 
			
		||||
							
								
								
									
										16
									
								
								vendor/gopkg.in/src-d/go-billy.v4/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/gopkg.in/src-d/go-billy.v4/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
language: go
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - 1.9.x
 | 
			
		||||
  - 1.10.x
 | 
			
		||||
 | 
			
		||||
go_import_path: gopkg.in/src-d/go-billy.v4
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - go get -v -t ./...
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
  - make test-coverage
 | 
			
		||||
 | 
			
		||||
after_success:
 | 
			
		||||
  - bash <(curl -s https://codecov.io/bash)
 | 
			
		||||
							
								
								
									
										25
									
								
								vendor/gopkg.in/src-d/go-billy.v4/DCO
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/gopkg.in/src-d/go-billy.v4/DCO
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
    Developer's Certificate of Origin 1.1
 | 
			
		||||
 | 
			
		||||
    By making a contribution to this project, I certify that:
 | 
			
		||||
 | 
			
		||||
    (a) The contribution was created in whole or in part by me and I
 | 
			
		||||
        have the right to submit it under the open source license
 | 
			
		||||
        indicated in the file; or
 | 
			
		||||
 | 
			
		||||
    (b) The contribution is based upon previous work that, to the best
 | 
			
		||||
        of my knowledge, is covered under an appropriate open source
 | 
			
		||||
        license and I have the right under that license to submit that
 | 
			
		||||
        work with modifications, whether created in whole or in part
 | 
			
		||||
        by me, under the same open source license (unless I am
 | 
			
		||||
        permitted to submit under a different license), as indicated
 | 
			
		||||
        in the file; or
 | 
			
		||||
 | 
			
		||||
    (c) The contribution was provided directly to me by some other
 | 
			
		||||
        person who certified (a), (b) or (c) and I have not modified
 | 
			
		||||
        it.
 | 
			
		||||
 | 
			
		||||
    (d) I understand and agree that this project and the contribution
 | 
			
		||||
	are public and that a record of the contribution (including all
 | 
			
		||||
	personal information I submit with it, including my sign-off) is
 | 
			
		||||
	maintained indefinitely and may be redistributed consistent with
 | 
			
		||||
	this project or the open source license(s) involved.
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/gopkg.in/src-d/go-billy.v4/MAINTAINERS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/gopkg.in/src-d/go-billy.v4/MAINTAINERS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
Máximo Cuadros <mcuadros@gmail.com> (@mcuadros)
 | 
			
		||||
							
								
								
									
										25
									
								
								vendor/gopkg.in/src-d/go-billy.v4/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/gopkg.in/src-d/go-billy.v4/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
# General
 | 
			
		||||
WORKDIR = $(PWD)
 | 
			
		||||
 | 
			
		||||
# Go parameters
 | 
			
		||||
GOCMD = go
 | 
			
		||||
GOTEST = $(GOCMD) test -v
 | 
			
		||||
 | 
			
		||||
# Coverage
 | 
			
		||||
COVERAGE_REPORT = coverage.txt
 | 
			
		||||
COVERAGE_PROFILE = profile.out
 | 
			
		||||
COVERAGE_MODE = atomic
 | 
			
		||||
 | 
			
		||||
test-coverage:
 | 
			
		||||
	cd $(WORKDIR); \
 | 
			
		||||
	echo "" > $(COVERAGE_REPORT); \
 | 
			
		||||
	for dir in `find . -name "*.go" | grep -o '.*/' | sort | uniq`; do \
 | 
			
		||||
		$(GOTEST) $$dir -coverprofile=$(COVERAGE_PROFILE) -covermode=$(COVERAGE_MODE); \
 | 
			
		||||
		if [ $$? != 0 ]; then \
 | 
			
		||||
			exit 2; \
 | 
			
		||||
		fi; \
 | 
			
		||||
		if [ -f $(COVERAGE_PROFILE) ]; then \
 | 
			
		||||
			cat $(COVERAGE_PROFILE) >> $(COVERAGE_REPORT); \
 | 
			
		||||
			rm $(COVERAGE_PROFILE); \
 | 
			
		||||
		fi; \
 | 
			
		||||
	done; \
 | 
			
		||||
							
								
								
									
										72
									
								
								vendor/gopkg.in/src-d/go-billy.v4/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								vendor/gopkg.in/src-d/go-billy.v4/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
# go-billy [](https://godoc.org/gopkg.in/src-d/go-billy.v4) [](https://travis-ci.org/src-d/go-billy) [](https://ci.appveyor.com/project/mcuadros/go-billy) [](https://codecov.io/gh/src-d/go-billy)
 | 
			
		||||
 | 
			
		||||
The missing interface filesystem abstraction for Go.
 | 
			
		||||
Billy implements an interface based on the `os` standard library, allowing to develop applications without dependency on the underlying storage. Makes it virtually free to implement mocks and testing over filesystem operations.
 | 
			
		||||
 | 
			
		||||
Billy was born as part of [src-d/go-git](https://github.com/src-d/go-git) project.
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
go get -u gopkg.in/src-d/go-billy.v4/...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
Billy exposes filesystems using the
 | 
			
		||||
[`Filesystem` interface](https://godoc.org/github.com/src-d/go-billy#Filesystem).
 | 
			
		||||
Each filesystem implementation gives you a `New` method, whose arguments depend on
 | 
			
		||||
the implementation itself, that returns a new `Filesystem`.
 | 
			
		||||
 | 
			
		||||
The following example caches in memory all readable files in a directory from any
 | 
			
		||||
billy's filesystem implementation.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
func LoadToMemory(origin billy.Filesystem, path string) (*memory.Memory, error) {
 | 
			
		||||
	memory := memory.New()
 | 
			
		||||
 | 
			
		||||
	files, err := origin.ReadDir("/")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, file := range files {
 | 
			
		||||
		if file.IsDir() {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		src, err := origin.Open(file.Name())
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		dst, err := memory.Create(file.Name())
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if _, err = io.Copy(dst, src); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err := dst.Close(); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err := src.Close(); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return memory, nil
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Why billy?
 | 
			
		||||
 | 
			
		||||
The library billy deals with storage systems and Billy is the name of a well-known, IKEA
 | 
			
		||||
bookcase. That's it.
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
Apache License Version 2.0, see [LICENSE](LICENSE)
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/gopkg.in/src-d/go-billy.v4/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/gopkg.in/src-d/go-billy.v4/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
version: "{build}"
 | 
			
		||||
platform: x64
 | 
			
		||||
 | 
			
		||||
clone_folder: c:\gopath\src\gopkg.in\src-d\go-billy.v4
 | 
			
		||||
 | 
			
		||||
environment:
 | 
			
		||||
  GOPATH: c:\gopath
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
 | 
			
		||||
  - go version
 | 
			
		||||
  - go get -v -t ./...
 | 
			
		||||
 | 
			
		||||
build_script:
 | 
			
		||||
  - go test -v ./...
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/gopkg.in/src-d/go-billy.v4/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/gopkg.in/src-d/go-billy.v4/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
module gopkg.in/src-d/go-billy.v4
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/kr/pretty v0.1.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9
 | 
			
		||||
	gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/gopkg.in/src-d/go-billy.v4/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/gopkg.in/src-d/go-billy.v4/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 | 
			
		||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
			
		||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
			
		||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 | 
			
		||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 | 
			
		||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/gopkg.in/src-d/go-git.v4/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								vendor/gopkg.in/src-d/go-git.v4/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
coverage.out
 | 
			
		||||
*~
 | 
			
		||||
coverage.txt
 | 
			
		||||
profile.out
 | 
			
		||||
							
								
								
									
										37
									
								
								vendor/gopkg.in/src-d/go-git.v4/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								vendor/gopkg.in/src-d/go-git.v4/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
language: go
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - "1.10"
 | 
			
		||||
  - "1.11"
 | 
			
		||||
 | 
			
		||||
go_import_path: gopkg.in/src-d/go-git.v4
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  - GIT_VERSION=master
 | 
			
		||||
  - GIT_VERSION=v1.9.3
 | 
			
		||||
  - GIT_VERSION=v2.11.0
 | 
			
		||||
 | 
			
		||||
cache:
 | 
			
		||||
  directories:
 | 
			
		||||
  - $HOME/.git-dist
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - export GIT_DIST_PATH=$HOME/.git-dist
 | 
			
		||||
  - make build-git
 | 
			
		||||
 | 
			
		||||
before_install:
 | 
			
		||||
  - git config --global user.email "travis@example.com"
 | 
			
		||||
  - git config --global user.name "Travis CI"
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - go get -v -t ./...
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
  - export GIT_EXEC_PATH=$GIT_DIST_PATH
 | 
			
		||||
  - export PATH=$GIT_DIST_PATH:$PATH
 | 
			
		||||
  - git version
 | 
			
		||||
  - make test-coverage
 | 
			
		||||
  - go vet ./...
 | 
			
		||||
 | 
			
		||||
after_success:
 | 
			
		||||
  - bash <(curl -s https://codecov.io/bash)
 | 
			
		||||
							
								
								
									
										74
									
								
								vendor/gopkg.in/src-d/go-git.v4/CODE_OF_CONDUCT.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								vendor/gopkg.in/src-d/go-git.v4/CODE_OF_CONDUCT.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
# Contributor Covenant Code of Conduct
 | 
			
		||||
 | 
			
		||||
## Our Pledge
 | 
			
		||||
 | 
			
		||||
In the interest of fostering an open and welcoming environment, we as
 | 
			
		||||
contributors and maintainers pledge to making participation in our project and
 | 
			
		||||
our community a harassment-free experience for everyone, regardless of age, body
 | 
			
		||||
size, disability, ethnicity, gender identity and expression, level of experience,
 | 
			
		||||
education, socio-economic status, nationality, personal appearance, race,
 | 
			
		||||
religion, or sexual identity and orientation.
 | 
			
		||||
 | 
			
		||||
## Our Standards
 | 
			
		||||
 | 
			
		||||
Examples of behavior that contributes to creating a positive environment
 | 
			
		||||
include:
 | 
			
		||||
 | 
			
		||||
* Using welcoming and inclusive language
 | 
			
		||||
* Being respectful of differing viewpoints and experiences
 | 
			
		||||
* Gracefully accepting constructive criticism
 | 
			
		||||
* Focusing on what is best for the community
 | 
			
		||||
* Showing empathy towards other community members
 | 
			
		||||
 | 
			
		||||
Examples of unacceptable behavior by participants include:
 | 
			
		||||
 | 
			
		||||
* The use of sexualized language or imagery and unwelcome sexual attention or
 | 
			
		||||
  advances
 | 
			
		||||
* Trolling, insulting/derogatory comments, and personal or political attacks
 | 
			
		||||
* Public or private harassment
 | 
			
		||||
* Publishing others' private information, such as a physical or electronic
 | 
			
		||||
  address, without explicit permission
 | 
			
		||||
* Other conduct which could reasonably be considered inappropriate in a
 | 
			
		||||
  professional setting
 | 
			
		||||
 | 
			
		||||
## Our Responsibilities
 | 
			
		||||
 | 
			
		||||
Project maintainers are responsible for clarifying the standards of acceptable
 | 
			
		||||
behavior and are expected to take appropriate and fair corrective action in
 | 
			
		||||
response to any instances of unacceptable behavior.
 | 
			
		||||
 | 
			
		||||
Project maintainers have the right and responsibility to remove, edit, or
 | 
			
		||||
reject comments, commits, code, wiki edits, issues, and other contributions
 | 
			
		||||
that are not aligned to this Code of Conduct, or to ban temporarily or
 | 
			
		||||
permanently any contributor for other behaviors that they deem inappropriate,
 | 
			
		||||
threatening, offensive, or harmful.
 | 
			
		||||
 | 
			
		||||
## Scope
 | 
			
		||||
 | 
			
		||||
This Code of Conduct applies both within project spaces and in public spaces
 | 
			
		||||
when an individual is representing the project or its community. Examples of
 | 
			
		||||
representing a project or community include using an official project e-mail
 | 
			
		||||
address, posting via an official social media account, or acting as an appointed
 | 
			
		||||
representative at an online or offline event. Representation of a project may be
 | 
			
		||||
further defined and clarified by project maintainers.
 | 
			
		||||
 | 
			
		||||
## Enforcement
 | 
			
		||||
 | 
			
		||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
 | 
			
		||||
reported by contacting the project team at conduct@sourced.tech. All
 | 
			
		||||
complaints will be reviewed and investigated and will result in a response that
 | 
			
		||||
is deemed necessary and appropriate to the circumstances. The project team is
 | 
			
		||||
obligated to maintain confidentiality with regard to the reporter of an incident.
 | 
			
		||||
Further details of specific enforcement policies may be posted separately.
 | 
			
		||||
 | 
			
		||||
Project maintainers who do not follow or enforce the Code of Conduct in good
 | 
			
		||||
faith may face temporary or permanent repercussions as determined by other
 | 
			
		||||
members of the project's leadership.
 | 
			
		||||
 | 
			
		||||
## Attribution
 | 
			
		||||
 | 
			
		||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
 | 
			
		||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
 | 
			
		||||
 | 
			
		||||
[homepage]: https://www.contributor-covenant.org
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										111
									
								
								vendor/gopkg.in/src-d/go-git.v4/COMPATIBILITY.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								vendor/gopkg.in/src-d/go-git.v4/COMPATIBILITY.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
Supported Capabilities
 | 
			
		||||
======================
 | 
			
		||||
 | 
			
		||||
Here is a non-comprehensive table of git commands and features whose equivalent
 | 
			
		||||
is supported by go-git.
 | 
			
		||||
 | 
			
		||||
| Feature                               | Status | Notes |
 | 
			
		||||
|---------------------------------------|--------|-------|
 | 
			
		||||
| **config**                            |
 | 
			
		||||
| config                                | ✔ | Reading and modifying per-repository configuration (`.git/config`) is supported. Global configuration (`$HOME/.gitconfig`) is not. |
 | 
			
		||||
| **getting and creating repositories** |
 | 
			
		||||
| init                                  | ✔ | Plain init and `--bare` are supported. Flags `--template`, `--separate-git-dir` and `--shared` are not. |
 | 
			
		||||
| clone                                 | ✔ | Plain clone and equivalents to `--progress`,  `--single-branch`, `--depth`, `--origin`, `--recurse-submodules` are supported. Others are not. |
 | 
			
		||||
| **basic snapshotting** |
 | 
			
		||||
| add                                   | ✔ | Plain add is supported. Any other flag aren't supported |
 | 
			
		||||
| status                                | ✔ |
 | 
			
		||||
| commit                                | ✔ |
 | 
			
		||||
| reset                                 | ✔ |
 | 
			
		||||
| rm                                    | ✔ |
 | 
			
		||||
| mv                                    | ✔ |
 | 
			
		||||
| **branching and merging** |
 | 
			
		||||
| branch                                | ✔ |
 | 
			
		||||
| checkout                              | ✔ | Basic usages of checkout are supported. |
 | 
			
		||||
| merge                                 | ✖ |
 | 
			
		||||
| mergetool                             | ✖ |
 | 
			
		||||
| stash                                 | ✖ |
 | 
			
		||||
| tag                                   | ✔ |
 | 
			
		||||
| **sharing and updating projects** |
 | 
			
		||||
| fetch                                 | ✔ |
 | 
			
		||||
| pull                                  | ✔ | Only supports merges where the merge can be resolved as a fast-forward. |
 | 
			
		||||
| push                                  | ✔ |
 | 
			
		||||
| remote                                | ✔ |
 | 
			
		||||
| submodule                             | ✔ |
 | 
			
		||||
| **inspection and comparison** |
 | 
			
		||||
| show                                  | ✔ |
 | 
			
		||||
| log                                   | ✔ |
 | 
			
		||||
| shortlog                              | (see log) |
 | 
			
		||||
| describe                              | |
 | 
			
		||||
| **patching** |
 | 
			
		||||
| apply                                 | ✖ |
 | 
			
		||||
| cherry-pick                           | ✖ |
 | 
			
		||||
| diff                                  | ✔ | Patch object with UnifiedDiff output representation |
 | 
			
		||||
| rebase                                | ✖ |
 | 
			
		||||
| revert                                | ✖ |
 | 
			
		||||
| **debugging** |
 | 
			
		||||
| bisect                                | ✖ |
 | 
			
		||||
| blame                                 | ✔ |
 | 
			
		||||
| grep                                  | ✔ |
 | 
			
		||||
| **email** ||
 | 
			
		||||
| am                                    | ✖ |
 | 
			
		||||
| apply                                 | ✖ |
 | 
			
		||||
| format-patch                          | ✖ |
 | 
			
		||||
| send-email                            | ✖ |
 | 
			
		||||
| request-pull                          | ✖ |
 | 
			
		||||
| **external systems** |
 | 
			
		||||
| svn                                   | ✖ |
 | 
			
		||||
| fast-import                           | ✖ |
 | 
			
		||||
| **administration** |
 | 
			
		||||
| clean                                 | ✔ |
 | 
			
		||||
| gc                                    | ✖ |
 | 
			
		||||
| fsck                                  | ✖ |
 | 
			
		||||
| reflog                                | ✖ |
 | 
			
		||||
| filter-branch                         | ✖ |
 | 
			
		||||
| instaweb                              | ✖ |
 | 
			
		||||
| archive                               | ✖ |
 | 
			
		||||
| bundle                                | ✖ |
 | 
			
		||||
| prune                                 | ✖ |
 | 
			
		||||
| repack                                | ✖ |
 | 
			
		||||
| **server admin** |
 | 
			
		||||
| daemon                                | |
 | 
			
		||||
| update-server-info                    | |
 | 
			
		||||
| **advanced** |
 | 
			
		||||
| notes                                 | ✖ |
 | 
			
		||||
| replace                               | ✖ |
 | 
			
		||||
| worktree                              | ✖ |
 | 
			
		||||
| annotate                              | (see blame) |
 | 
			
		||||
| **gpg** |
 | 
			
		||||
| git-verify-commit                     | ✔ |
 | 
			
		||||
| git-verify-tag                        | ✔ |
 | 
			
		||||
| **plumbing commands** |
 | 
			
		||||
| cat-file                              | ✔ |
 | 
			
		||||
| check-ignore                          | |
 | 
			
		||||
| commit-tree                           | |
 | 
			
		||||
| count-objects                         | |
 | 
			
		||||
| diff-index                            | |
 | 
			
		||||
| for-each-ref                          | ✔ |
 | 
			
		||||
| hash-object                           | ✔ |
 | 
			
		||||
| ls-files                              | ✔ |
 | 
			
		||||
| merge-base                            | |
 | 
			
		||||
| read-tree                             | |
 | 
			
		||||
| rev-list                              | ✔ |
 | 
			
		||||
| rev-parse                             | |
 | 
			
		||||
| show-ref                              | ✔ |
 | 
			
		||||
| symbolic-ref                          | ✔ |
 | 
			
		||||
| update-index                          | |
 | 
			
		||||
| update-ref                            | |
 | 
			
		||||
| verify-pack                           | |
 | 
			
		||||
| write-tree                            | |
 | 
			
		||||
| **protocols** |
 | 
			
		||||
| http(s):// (dumb)                     | ✖ |
 | 
			
		||||
| http(s):// (smart)                    | ✔ |
 | 
			
		||||
| git://                                | ✔ |
 | 
			
		||||
| ssh://                                | ✔ |
 | 
			
		||||
| file://                               | ✔ |
 | 
			
		||||
| custom                                | ✔ |
 | 
			
		||||
| **other features** |
 | 
			
		||||
| gitignore                             | ✔ |
 | 
			
		||||
| gitattributes                         | ✖ |
 | 
			
		||||
| index version                         | |
 | 
			
		||||
| packfile version                      | |
 | 
			
		||||
| push-certs                            | ✖ |
 | 
			
		||||
							
								
								
									
										59
									
								
								vendor/gopkg.in/src-d/go-git.v4/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/gopkg.in/src-d/go-git.v4/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
# Contributing Guidelines
 | 
			
		||||
 | 
			
		||||
source{d} go-git project is [Apache 2.0 licensed](LICENSE) and accepts
 | 
			
		||||
contributions via GitHub pull requests.  This document outlines some of the
 | 
			
		||||
conventions on development workflow, commit message formatting, contact points,
 | 
			
		||||
and other resources to make it easier to get your contribution accepted.
 | 
			
		||||
 | 
			
		||||
## Certificate of Origin
 | 
			
		||||
 | 
			
		||||
By contributing to this project you agree to the [Developer Certificate of
 | 
			
		||||
Origin (DCO)](DCO). This document was created by the Linux Kernel community and is a
 | 
			
		||||
simple statement that you, as a contributor, have the legal right to make the
 | 
			
		||||
contribution.
 | 
			
		||||
 | 
			
		||||
In order to show your agreement with the DCO you should include at the end of commit message,
 | 
			
		||||
the following line: `Signed-off-by: John Doe <john.doe@example.com>`, using your real name.
 | 
			
		||||
 | 
			
		||||
This can be done easily using the [`-s`](https://github.com/git/git/blob/b2c150d3aa82f6583b9aadfecc5f8fa1c74aca09/Documentation/git-commit.txt#L154-L161) flag on the `git commit`.
 | 
			
		||||
 | 
			
		||||
## Support Channels
 | 
			
		||||
 | 
			
		||||
The official support channels, for both users and contributors, are:
 | 
			
		||||
 | 
			
		||||
- [StackOverflow go-git tag](https://stackoverflow.com/questions/tagged/go-git) for user questions.
 | 
			
		||||
- GitHub [Issues](https://github.com/src-d/go-git/issues)* for bug reports and feature requests.
 | 
			
		||||
- Slack: #go-git room in the [source{d} Slack](https://join.slack.com/t/sourced-community/shared_invite/enQtMjc4Njk5MzEyNzM2LTFjNzY4NjEwZGEwMzRiNTM4MzRlMzQ4MmIzZjkwZmZlM2NjODUxZmJjNDI1OTcxNDAyMmZlNmFjODZlNTg0YWM)
 | 
			
		||||
 | 
			
		||||
*Before opening a new issue or submitting a new pull request, it's helpful to
 | 
			
		||||
search the project - it's likely that another user has already reported the
 | 
			
		||||
issue you're facing, or it's a known issue that we're already aware of.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## How to Contribute
 | 
			
		||||
 | 
			
		||||
Pull Requests (PRs) are the main and exclusive way to contribute to the official go-git project.
 | 
			
		||||
In order for a PR to be accepted it needs to pass a list of requirements:
 | 
			
		||||
 | 
			
		||||
- You should be able to run the same query using `git`. We don't accept features that are not implemented in the official git implementation.
 | 
			
		||||
- The expected behavior must match the [official git implementation](https://github.com/git/git).
 | 
			
		||||
- The actual behavior must be correctly explained with natural language and providing a minimum working example in Go that reproduces it.
 | 
			
		||||
- All PRs must be written in idiomatic Go, formatted according to [gofmt](https://golang.org/cmd/gofmt/), and without any warnings from [go lint](https://github.com/golang/lint) nor [go vet](https://golang.org/cmd/vet/).
 | 
			
		||||
- They should in general include tests, and those shall pass.
 | 
			
		||||
- If the PR is a bug fix, it has to include a suite of unit tests for the new functionality.
 | 
			
		||||
- If the PR is a new feature, it has to come with a suite of unit tests, that tests the new functionality.
 | 
			
		||||
- In any case, all the PRs have to pass the personal evaluation of at least one of the [maintainers](MAINTAINERS) of go-git.
 | 
			
		||||
 | 
			
		||||
### Format of the commit message
 | 
			
		||||
 | 
			
		||||
Every commit message should describe what was changed, under which context and, if applicable, the GitHub issue it relates to:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
plumbing: packp, Skip argument validations for unknown capabilities. Fixes #623
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The format can be described more formally as follows:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
<package>: <subpackage>, <what changed>. [Fixes #<issue-number>]
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										36
									
								
								vendor/gopkg.in/src-d/go-git.v4/DCO
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								vendor/gopkg.in/src-d/go-git.v4/DCO
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
Developer Certificate of Origin
 | 
			
		||||
Version 1.1
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
 | 
			
		||||
660 York Street, Suite 102,
 | 
			
		||||
San Francisco, CA 94110 USA
 | 
			
		||||
 | 
			
		||||
Everyone is permitted to copy and distribute verbatim copies of this
 | 
			
		||||
license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Developer's Certificate of Origin 1.1
 | 
			
		||||
 | 
			
		||||
By making a contribution to this project, I certify that:
 | 
			
		||||
 | 
			
		||||
(a) The contribution was created in whole or in part by me and I
 | 
			
		||||
    have the right to submit it under the open source license
 | 
			
		||||
    indicated in the file; or
 | 
			
		||||
 | 
			
		||||
(b) The contribution is based upon previous work that, to the best
 | 
			
		||||
    of my knowledge, is covered under an appropriate open source
 | 
			
		||||
    license and I have the right under that license to submit that
 | 
			
		||||
    work with modifications, whether created in whole or in part
 | 
			
		||||
    by me, under the same open source license (unless I am
 | 
			
		||||
    permitted to submit under a different license), as indicated
 | 
			
		||||
    in the file; or
 | 
			
		||||
 | 
			
		||||
(c) The contribution was provided directly to me by some other
 | 
			
		||||
    person who certified (a), (b) or (c) and I have not modified
 | 
			
		||||
    it.
 | 
			
		||||
 | 
			
		||||
(d) I understand and agree that this project and the contribution
 | 
			
		||||
    are public and that a record of the contribution (including all
 | 
			
		||||
    personal information I submit with it, including my sign-off) is
 | 
			
		||||
    maintained indefinitely and may be redistributed consistent with
 | 
			
		||||
    this project or the open source license(s) involved.
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/gopkg.in/src-d/go-git.v4/MAINTAINERS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/gopkg.in/src-d/go-git.v4/MAINTAINERS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Máximo Cuadros <mcuadros@gmail.com> (@mcuadros)
 | 
			
		||||
Jeremy Stribling <strib@alum.mit.edu> (@strib)
 | 
			
		||||
Ori Rawlings <orirawlings@gmail.com> (@orirawlings)
 | 
			
		||||
							
								
								
									
										52
									
								
								vendor/gopkg.in/src-d/go-git.v4/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/gopkg.in/src-d/go-git.v4/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
# General
 | 
			
		||||
WORKDIR = $(PWD)
 | 
			
		||||
 | 
			
		||||
# Go parameters
 | 
			
		||||
GOCMD = go
 | 
			
		||||
GOTEST = $(GOCMD) test -v
 | 
			
		||||
 | 
			
		||||
# Git config
 | 
			
		||||
GIT_VERSION ?=
 | 
			
		||||
GIT_DIST_PATH ?= $(PWD)/.git-dist
 | 
			
		||||
GIT_REPOSITORY = http://github.com/git/git.git
 | 
			
		||||
 | 
			
		||||
# Coverage
 | 
			
		||||
COVERAGE_REPORT = coverage.txt
 | 
			
		||||
COVERAGE_PROFILE = profile.out
 | 
			
		||||
COVERAGE_MODE = atomic
 | 
			
		||||
 | 
			
		||||
ifneq ($(origin CI), undefined)
 | 
			
		||||
	WORKDIR := $(GOPATH)/src/gopkg.in/src-d/go-git.v4
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
build-git:
 | 
			
		||||
	@if [ -f $(GIT_DIST_PATH)/git ]; then \
 | 
			
		||||
		echo "nothing to do, using cache $(GIT_DIST_PATH)"; \
 | 
			
		||||
	else \
 | 
			
		||||
		git clone $(GIT_REPOSITORY) -b $(GIT_VERSION) --depth 1 --single-branch $(GIT_DIST_PATH); \
 | 
			
		||||
		cd $(GIT_DIST_PATH); \
 | 
			
		||||
		make configure; \
 | 
			
		||||
		./configure; \
 | 
			
		||||
		make all; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	@cd $(WORKDIR); \
 | 
			
		||||
	$(GOTEST) ./...
 | 
			
		||||
 | 
			
		||||
test-coverage:
 | 
			
		||||
	@cd $(WORKDIR); \
 | 
			
		||||
	echo "" > $(COVERAGE_REPORT); \
 | 
			
		||||
	for dir in `find . -name "*.go" | grep -o '.*/' | sort | uniq`; do \
 | 
			
		||||
		$(GOTEST) $$dir -coverprofile=$(COVERAGE_PROFILE) -covermode=$(COVERAGE_MODE); \
 | 
			
		||||
		if [ $$? != 0 ]; then \
 | 
			
		||||
			exit 2; \
 | 
			
		||||
		fi; \
 | 
			
		||||
		if [ -f $(COVERAGE_PROFILE) ]; then \
 | 
			
		||||
			cat $(COVERAGE_PROFILE) >> $(COVERAGE_REPORT); \
 | 
			
		||||
			rm $(COVERAGE_PROFILE); \
 | 
			
		||||
		fi; \
 | 
			
		||||
	done; \
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -rf $(GIT_DIST_PATH)
 | 
			
		||||
							
								
								
									
										123
									
								
								vendor/gopkg.in/src-d/go-git.v4/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								vendor/gopkg.in/src-d/go-git.v4/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||

 | 
			
		||||
[](https://godoc.org/github.com/src-d/go-git) [](https://travis-ci.org/src-d/go-git) [](https://ci.appveyor.com/project/mcuadros/go-git) [](https://codecov.io/github/src-d/go-git) [](https://goreportcard.com/report/github.com/src-d/go-git)
 | 
			
		||||
 | 
			
		||||
*go-git* is a highly extensible git implementation library written in **pure Go**.
 | 
			
		||||
 | 
			
		||||
It can be used to manipulate git repositories at low level *(plumbing)* or high level *(porcelain)*, through an idiomatic Go API. It also supports several types of storage, such as in-memory filesystems, or custom implementations thanks to the [`Storer`](https://godoc.org/gopkg.in/src-d/go-git.v4/plumbing/storer) interface.
 | 
			
		||||
 | 
			
		||||
It's being actively developed since 2015 and is being used extensively by [source{d}](https://sourced.tech/) and [Keybase](https://keybase.io/blog/encrypted-git-for-everyone), and by many other libraries and tools.
 | 
			
		||||
 | 
			
		||||
Comparison with git
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
*go-git* aims to be fully compatible with [git](https://github.com/git/git), all the *porcelain* operations are implemented to work exactly as *git* does.
 | 
			
		||||
 | 
			
		||||
*git* is a humongous project with years of development by thousands of contributors, making it challenging for *go-git* to implement all the features. You can find a comparison of *go-git* vs *git* in the [compatibility documentation](COMPATIBILITY.md).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Installation
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
The recommended way to install *go-git* is:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
go get -u gopkg.in/src-d/go-git.v4/...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> We use [gopkg.in](http://labix.org/gopkg.in) to version the API, this means that when `go get` clones the package, it's the latest tag matching `v4.*` that is cloned and not the master branch.
 | 
			
		||||
 | 
			
		||||
Examples
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
> Please note that the `CheckIfError` and `Info` functions  used in the examples are from the [examples package](https://github.com/src-d/go-git/blob/master/_examples/common.go#L17) just to be used in the examples.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Basic example
 | 
			
		||||
 | 
			
		||||
A basic example that mimics the standard `git clone` command
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Clone the given repository to the given directory
 | 
			
		||||
Info("git clone https://github.com/src-d/go-git")
 | 
			
		||||
 | 
			
		||||
_, err := git.PlainClone("/tmp/foo", false, &git.CloneOptions{
 | 
			
		||||
    URL:      "https://github.com/src-d/go-git",
 | 
			
		||||
    Progress: os.Stdout,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
CheckIfError(err)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Outputs:
 | 
			
		||||
```
 | 
			
		||||
Counting objects: 4924, done.
 | 
			
		||||
Compressing objects: 100% (1333/1333), done.
 | 
			
		||||
Total 4924 (delta 530), reused 6 (delta 6), pack-reused 3533
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### In-memory example
 | 
			
		||||
 | 
			
		||||
Cloning a repository into memory and printing the history of HEAD, just like `git log` does
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
// Clones the given repository in memory, creating the remote, the local
 | 
			
		||||
// branches and fetching the objects, exactly as:
 | 
			
		||||
Info("git clone https://github.com/src-d/go-siva")
 | 
			
		||||
 | 
			
		||||
r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
 | 
			
		||||
    URL: "https://github.com/src-d/go-siva",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
CheckIfError(err)
 | 
			
		||||
 | 
			
		||||
// Gets the HEAD history from HEAD, just like this command:
 | 
			
		||||
Info("git log")
 | 
			
		||||
 | 
			
		||||
// ... retrieves the branch pointed by HEAD
 | 
			
		||||
ref, err := r.Head()
 | 
			
		||||
CheckIfError(err)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ... retrieves the commit history
 | 
			
		||||
cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
 | 
			
		||||
CheckIfError(err)
 | 
			
		||||
 | 
			
		||||
// ... just iterates over the commits, printing it
 | 
			
		||||
err = cIter.ForEach(func(c *object.Commit) error {
 | 
			
		||||
	fmt.Println(c)
 | 
			
		||||
	return nil
 | 
			
		||||
})
 | 
			
		||||
CheckIfError(err)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Outputs:
 | 
			
		||||
```
 | 
			
		||||
commit ded8054fd0c3994453e9c8aacaf48d118d42991e
 | 
			
		||||
Author: Santiago M. Mola <santi@mola.io>
 | 
			
		||||
Date:   Sat Nov 12 21:18:41 2016 +0100
 | 
			
		||||
 | 
			
		||||
    index: ReadFrom/WriteTo returns IndexReadError/IndexWriteError. (#9)
 | 
			
		||||
 | 
			
		||||
commit df707095626f384ce2dc1a83b30f9a21d69b9dfc
 | 
			
		||||
Author: Santiago M. Mola <santi@mola.io>
 | 
			
		||||
Date:   Fri Nov 11 13:23:22 2016 +0100
 | 
			
		||||
 | 
			
		||||
    readwriter: fix bug when writing index. (#10)
 | 
			
		||||
 | 
			
		||||
    When using ReadWriter on an existing siva file, absolute offset for
 | 
			
		||||
    index entries was not being calculated correctly.
 | 
			
		||||
...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You can find this [example](_examples/log/main.go) and many others in the [examples](_examples) folder.
 | 
			
		||||
 | 
			
		||||
Contribute
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
[Contributions](https://github.com/src-d/go-git/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) are more than welcome, if you are interested please take a look to
 | 
			
		||||
our [Contributing Guidelines](CONTRIBUTING.md).
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
-------
 | 
			
		||||
Apache License Version 2.0, see [LICENSE](LICENSE)
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/gopkg.in/src-d/go-git.v4/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/gopkg.in/src-d/go-git.v4/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
version: "{build}"
 | 
			
		||||
platform: x64
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
  allow_failures:
 | 
			
		||||
    - platform: x64
 | 
			
		||||
    
 | 
			
		||||
clone_folder: c:\gopath\src\gopkg.in\src-d\go-git.v4
 | 
			
		||||
 | 
			
		||||
environment:
 | 
			
		||||
  GOPATH: c:\gopath
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - set PATH=%GOPATH%\bin;c:\go\bin;"C:\Program Files\Git\mingw64\bin";%PATH%
 | 
			
		||||
  - go version
 | 
			
		||||
  - go get -v -t ./...
 | 
			
		||||
  - git config --global user.email "travis@example.com"
 | 
			
		||||
  - git config --global user.name "Travis CI
 | 
			
		||||
 | 
			
		||||
build_script:
 | 
			
		||||
  - go test -v ./...
 | 
			
		||||
							
								
								
									
										29
									
								
								vendor/gopkg.in/src-d/go-git.v4/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/gopkg.in/src-d/go-git.v4/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
module gopkg.in/src-d/go-git.v4
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 // indirect
 | 
			
		||||
	github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect
 | 
			
		||||
	github.com/davecgh/go-spew v1.1.1 // indirect
 | 
			
		||||
	github.com/emirpasic/gods v1.9.0
 | 
			
		||||
	github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
 | 
			
		||||
	github.com/gliderlabs/ssh v0.1.1
 | 
			
		||||
	github.com/google/go-cmp v0.2.0
 | 
			
		||||
	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
 | 
			
		||||
	github.com/jessevdk/go-flags v1.4.0
 | 
			
		||||
	github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e
 | 
			
		||||
	github.com/mitchellh/go-homedir v1.0.0
 | 
			
		||||
	github.com/pelletier/go-buffruneio v0.2.0 // indirect
 | 
			
		||||
	github.com/pkg/errors v0.8.0 // indirect
 | 
			
		||||
	github.com/pmezard/go-difflib v1.0.0 // indirect
 | 
			
		||||
	github.com/sergi/go-diff v1.0.0
 | 
			
		||||
	github.com/src-d/gcfg v1.4.0
 | 
			
		||||
	github.com/stretchr/testify v1.2.2 // indirect
 | 
			
		||||
	github.com/xanzy/ssh-agent v0.2.0
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20180904163835-0709b304e793
 | 
			
		||||
	golang.org/x/net v0.0.0-20180906233101-161cd47e91fd // indirect
 | 
			
		||||
	golang.org/x/text v0.3.0
 | 
			
		||||
	gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127
 | 
			
		||||
	gopkg.in/src-d/go-billy.v4 v4.2.1
 | 
			
		||||
	gopkg.in/src-d/go-git-fixtures.v3 v3.1.1
 | 
			
		||||
	gopkg.in/warnings.v0 v0.1.2 // indirect
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										59
									
								
								vendor/gopkg.in/src-d/go-git.v4/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/gopkg.in/src-d/go-git.v4/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
 | 
			
		||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
 | 
			
		||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
 | 
			
		||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 | 
			
		||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
			
		||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
			
		||||
github.com/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo=
 | 
			
		||||
github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
 | 
			
		||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
 | 
			
		||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
 | 
			
		||||
github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw=
 | 
			
		||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
 | 
			
		||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
 | 
			
		||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 | 
			
		||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
 | 
			
		||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
 | 
			
		||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
 | 
			
		||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
 | 
			
		||||
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8=
 | 
			
		||||
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
 | 
			
		||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 | 
			
		||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
			
		||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
			
		||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 | 
			
		||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
			
		||||
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
 | 
			
		||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 | 
			
		||||
github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
 | 
			
		||||
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
 | 
			
		||||
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
 | 
			
		||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
			
		||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
 | 
			
		||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 | 
			
		||||
github.com/src-d/gcfg v1.3.0 h1:2BEDr8r0I0b8h/fOqwtxCEiq2HJu8n2JGZJQFGXWLjg=
 | 
			
		||||
github.com/src-d/gcfg v1.3.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
 | 
			
		||||
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
 | 
			
		||||
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
 | 
			
		||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 | 
			
		||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 | 
			
		||||
github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro=
 | 
			
		||||
github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
			
		||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
 | 
			
		||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 | 
			
		||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/src-d/go-billy.v4 v4.2.1 h1:omN5CrMrMcQ+4I8bJ0wEhOBPanIRWzFC953IiXKdYzo=
 | 
			
		||||
gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
 | 
			
		||||
gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45iOf1dKJs=
 | 
			
		||||
gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
 | 
			
		||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
 | 
			
		||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/gopkg.in/testfixtures.v2/.editorconfig
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/gopkg.in/testfixtures.v2/.editorconfig
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
# http://editorconfig.org/
 | 
			
		||||
 | 
			
		||||
root = true
 | 
			
		||||
 | 
			
		||||
[*]
 | 
			
		||||
end_of_line = lf
 | 
			
		||||
insert_final_newline = true
 | 
			
		||||
charset = utf-8
 | 
			
		||||
trim_trailing_whitespace = true
 | 
			
		||||
indent_style = tab
 | 
			
		||||
indent_size = 8
 | 
			
		||||
 | 
			
		||||
[*.{yml,md}]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 2
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/gopkg.in/testfixtures.v2/.gitattributes
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/gopkg.in/testfixtures.v2/.gitattributes
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
* text eol=lf
 | 
			
		||||
							
								
								
									
										29
									
								
								vendor/gopkg.in/testfixtures.v2/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/gopkg.in/testfixtures.v2/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
 | 
			
		||||
*.o
 | 
			
		||||
*.a
 | 
			
		||||
*.so
 | 
			
		||||
 | 
			
		||||
# Folders
 | 
			
		||||
_obj
 | 
			
		||||
_test
 | 
			
		||||
 | 
			
		||||
# Architecture specific extensions/prefixes
 | 
			
		||||
*.[568vq]
 | 
			
		||||
[568vq].out
 | 
			
		||||
 | 
			
		||||
*.cgo1.go
 | 
			
		||||
*.cgo2.c
 | 
			
		||||
_cgo_defun.c
 | 
			
		||||
_cgo_gotypes.go
 | 
			
		||||
_cgo_export.*
 | 
			
		||||
 | 
			
		||||
_testmain.go
 | 
			
		||||
 | 
			
		||||
*.exe
 | 
			
		||||
*.test
 | 
			
		||||
*.prof
 | 
			
		||||
 | 
			
		||||
# SQLite databases
 | 
			
		||||
*.sqlite3
 | 
			
		||||
 | 
			
		||||
.env
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/gopkg.in/testfixtures.v2/.sample.env
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/gopkg.in/testfixtures.v2/.sample.env
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
PG_CONN_STRING="user=postgres dbname=testfixtures_test sslmode=disable"
 | 
			
		||||
MYSQL_CONN_STRING="root:@/testfixtures_test?multiStatements=true"
 | 
			
		||||
SQLITE_CONN_STRING="testdb.sqlite3"
 | 
			
		||||
SQLSERVER_CONN_STRING="server=localhost\SQLExpress;database=testfixtures_test;user id=sa;password=sqlserver;encrypt=disable"
 | 
			
		||||
ORACLE_CONN_STRING="testfixtures/testfixtures@localhost/XE"
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/gopkg.in/testfixtures.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/gopkg.in/testfixtures.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
language: go
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - '1.9'
 | 
			
		||||
  - '1.10'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  - postgresql
 | 
			
		||||
  - mysql
 | 
			
		||||
 | 
			
		||||
addons:
 | 
			
		||||
  postgresql: "9.4"
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - mysql -e 'CREATE DATABASE testfixtures_test;'
 | 
			
		||||
  - psql -c 'CREATE DATABASE testfixtures_test;' -U postgres
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - go get -t -tags 'sqlite postgresql mysql' ./...
 | 
			
		||||
  - curl -s https://raw.githubusercontent.com/go-task/task/master/install-task.sh | sh
 | 
			
		||||
  - bin/task dl-deps
 | 
			
		||||
  - cp .sample.env .env
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
  - bin/task lint
 | 
			
		||||
  - bin/task test-free
 | 
			
		||||
							
								
								
									
										358
									
								
								vendor/gopkg.in/testfixtures.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										358
									
								
								vendor/gopkg.in/testfixtures.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,358 @@
 | 
			
		||||
# Go Test Fixtures
 | 
			
		||||
 | 
			
		||||
[](https://godoc.org/gopkg.in/testfixtures.v2)
 | 
			
		||||
[](https://goreportcard.com/report/github.com/go-testfixtures/testfixtures)
 | 
			
		||||
[](https://travis-ci.org/go-testfixtures/testfixtures)
 | 
			
		||||
[](https://ci.appveyor.com/project/andreynering/testfixtures)
 | 
			
		||||
 | 
			
		||||
> ***Warning***: this package will wipe the database data before loading the
 | 
			
		||||
fixtures! It is supposed to be used on a test database. Please, double check
 | 
			
		||||
if you are running it against the correct database.
 | 
			
		||||
 | 
			
		||||
Writing tests is hard, even more when you have to deal with an SQL database.
 | 
			
		||||
This package aims to make writing functional tests for web apps written in
 | 
			
		||||
Go easier.
 | 
			
		||||
 | 
			
		||||
Basically this package mimics the ["Rails' way"][railstests] of writing tests
 | 
			
		||||
for database applications, where sample data is kept in fixtures files. Before
 | 
			
		||||
the execution of every test, the test database is cleaned and the fixture data
 | 
			
		||||
is loaded into the database.
 | 
			
		||||
 | 
			
		||||
The idea is running tests against a real database, instead of relying in mocks,
 | 
			
		||||
which is boring to setup and may lead to production bugs not being caught in
 | 
			
		||||
the tests.
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
First, get it:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
go get -u -v gopkg.in/testfixtures.v2
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
Create a folder for the fixture files. Each file should contain data for a
 | 
			
		||||
single table and have the name `<table_name>.yml`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
myapp/
 | 
			
		||||
  myapp.go
 | 
			
		||||
  myapp_test.go
 | 
			
		||||
  ...
 | 
			
		||||
  fixtures/
 | 
			
		||||
    posts.yml
 | 
			
		||||
    comments.yml
 | 
			
		||||
    tags.yml
 | 
			
		||||
    posts_tags.yml
 | 
			
		||||
    ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The file would look like this (it can have as many record you want):
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
# comments.yml
 | 
			
		||||
- id: 1
 | 
			
		||||
  post_id: 1
 | 
			
		||||
  content: A comment...
 | 
			
		||||
  author_name: John Doe
 | 
			
		||||
  author_email: john@doe.com
 | 
			
		||||
  created_at: 2016-01-01 12:30:12
 | 
			
		||||
  updated_at: 2016-01-01 12:30:12
 | 
			
		||||
 | 
			
		||||
- id: 2
 | 
			
		||||
  post_id: 2
 | 
			
		||||
  content: Another comment...
 | 
			
		||||
  author_name: John Doe
 | 
			
		||||
  author_email: john@doe.com
 | 
			
		||||
  created_at: 2016-01-01 12:30:12
 | 
			
		||||
  updated_at: 2016-01-01 12:30:12
 | 
			
		||||
 | 
			
		||||
# ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
An YAML object or array will be converted to JSON. It can be stored on a native
 | 
			
		||||
JSON type like JSONB on PostgreSQL or as a TEXT or VARCHAR column on other
 | 
			
		||||
databases.
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
- id: 1
 | 
			
		||||
  post_attributes:
 | 
			
		||||
    author: John Due
 | 
			
		||||
    author_email: john@due.com
 | 
			
		||||
    title: "..."
 | 
			
		||||
    tags:
 | 
			
		||||
      - programming
 | 
			
		||||
      - go
 | 
			
		||||
      - testing
 | 
			
		||||
    post: "..."
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If you need to write raw SQL, probably to call a function, prefix the value
 | 
			
		||||
of the column with `RAW=`:
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
- id: 1
 | 
			
		||||
  uuid_column: RAW=uuid_generate_v4()
 | 
			
		||||
  postgis_type_column: RAW=ST_GeomFromText('params...')
 | 
			
		||||
  created_at: RAW=NOW()
 | 
			
		||||
  updated_at: RAW=NOW()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Your tests would look like this:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
package myapp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
    "database/sql"
 | 
			
		||||
    "log"
 | 
			
		||||
 | 
			
		||||
    _ "github.com/lib/pq"
 | 
			
		||||
    "gopkg.in/testfixtures.v2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
    db *sql.DB
 | 
			
		||||
    fixtures *testfixtures.Context
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestMain(m *testing.M) {
 | 
			
		||||
    var err error
 | 
			
		||||
 | 
			
		||||
    // Open connection with the test database.
 | 
			
		||||
    // Do NOT import fixtures in a production database!
 | 
			
		||||
    // Existing data would be deleted
 | 
			
		||||
    db, err = sql.Open("postgres", "dbname=myapp_test")
 | 
			
		||||
    if err != nil {
 | 
			
		||||
        log.Fatal(err)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // creating the context that hold the fixtures
 | 
			
		||||
    // see about all compatible databases in this page below
 | 
			
		||||
    fixtures, err = testfixtures.NewFolder(db, &testfixtures.PostgreSQL{}, "testdata/fixtures")
 | 
			
		||||
    if err != nil {
 | 
			
		||||
        log.Fatal(err)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    os.Exit(m.Run())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func prepareTestDatabase() {
 | 
			
		||||
    if err := fixtures.Load(); err != nil {
 | 
			
		||||
        log.Fatal(err)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestX(t *testing.T) {
 | 
			
		||||
    prepareTestDatabase()
 | 
			
		||||
    // your test here ...
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestY(t *testing.T) {
 | 
			
		||||
    prepareTestDatabase()
 | 
			
		||||
    // your test here ...
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestZ(t *testing.T) {
 | 
			
		||||
    prepareTestDatabase()
 | 
			
		||||
    // your test here ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Alternatively, you can use the `NewFiles` function, to specify which
 | 
			
		||||
files you want to load into the database:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
fixtures, err := testfixtures.NewFiles(db, &testfixtures.PostgreSQL{},
 | 
			
		||||
    "fixtures/orders.yml",
 | 
			
		||||
    "fixtures/customers.yml",
 | 
			
		||||
    // add as many files you want
 | 
			
		||||
)
 | 
			
		||||
if err != nil {
 | 
			
		||||
    log.Fatal(err)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Security check
 | 
			
		||||
 | 
			
		||||
In order to prevent you from accidentally wiping the wrong database, this
 | 
			
		||||
package will refuse to load fixtures if the database name (or database
 | 
			
		||||
filename for SQLite) doesn't contains "test". If you want to disable this
 | 
			
		||||
check, use:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
testfixtures.SkipDatabaseNameCheck(true)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Sequences
 | 
			
		||||
 | 
			
		||||
For PostgreSQL or Oracle, this package also resets all sequences to a high
 | 
			
		||||
number to prevent duplicated primary keys while running the tests.
 | 
			
		||||
The default is 10000, but you can change that with:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
testfixtures.ResetSequencesTo(10000)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Compatible databases
 | 
			
		||||
 | 
			
		||||
### PostgreSQL
 | 
			
		||||
 | 
			
		||||
This package has two approaches to disable foreign keys while importing fixtures
 | 
			
		||||
in PostgreSQL databases:
 | 
			
		||||
 | 
			
		||||
#### With `DISABLE TRIGGER`
 | 
			
		||||
 | 
			
		||||
This is the default approach. For that use:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
&testfixtures.PostgreSQL{}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
With the above snippet this package will use `DISABLE TRIGGER` to temporarily
 | 
			
		||||
disabling foreign key constraints while loading fixtures. This work with any
 | 
			
		||||
version of PostgreSQL, but it is **required** to be connected in the database
 | 
			
		||||
as a SUPERUSER. You can make a PostgreSQL user a SUPERUSER with:
 | 
			
		||||
 | 
			
		||||
```sql
 | 
			
		||||
ALTER USER your_user SUPERUSER;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### With `ALTER CONSTRAINT`
 | 
			
		||||
 | 
			
		||||
This approach don't require to be connected as a SUPERUSER, but only work with
 | 
			
		||||
PostgreSQL versions >= 9.4. Try this if you are getting foreign key violation
 | 
			
		||||
errors with the previous approach. It is as simple as using:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
&testfixtures.PostgreSQL{UseAlterConstraint: true}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### MySQL / MariaDB
 | 
			
		||||
 | 
			
		||||
Just make sure the connection string have
 | 
			
		||||
[the multistatement parameter](https://github.com/go-sql-driver/mysql#multistatements)
 | 
			
		||||
set to true, and use:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
&testfixtures.MySQL{}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### SQLite
 | 
			
		||||
 | 
			
		||||
SQLite is also supported. It is recommended to create foreign keys as
 | 
			
		||||
`DEFERRABLE` (the default) to prevent problems. See more
 | 
			
		||||
[on the SQLite documentation](https://www.sqlite.org/foreignkeys.html#fk_deferred).
 | 
			
		||||
(Foreign key constraints are no-op by default on SQLite, but enabling it is
 | 
			
		||||
recommended).
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
&testfixtures.SQLite{}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Microsoft SQL Server
 | 
			
		||||
 | 
			
		||||
SQL Server support requires SQL Server >= 2008. Inserting on `IDENTITY` columns
 | 
			
		||||
are handled as well. Just make sure you are logged in with a user with
 | 
			
		||||
`ALTER TABLE` permission.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
&testfixtures.SQLServer{}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Oracle
 | 
			
		||||
 | 
			
		||||
Oracle is supported as well. Use:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
&testfixtures.Oracle{}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Generating fixtures for a existing database (experimental)
 | 
			
		||||
 | 
			
		||||
The following code will generate a YAML file for each table of the database in
 | 
			
		||||
the given folder. It may be useful to boostrap a test scenario from a sample
 | 
			
		||||
database of your app.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
err := testfixtures.GenerateFixtures(db, &testfixtures.PostgreSQL{}, "testdata/fixtures")
 | 
			
		||||
if err != nil {
 | 
			
		||||
    log.Fatalf("Error generating fixtures: %v", err)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Or
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
err := testfixtures.GenerateFixturesForTables(
 | 
			
		||||
    db,
 | 
			
		||||
    []*TableInfo{
 | 
			
		||||
        &TableInfo{Name: "table_name", Where: "foo = 'bar'"},
 | 
			
		||||
        // ...
 | 
			
		||||
    },
 | 
			
		||||
    &testfixtures.PostgreSQL{},
 | 
			
		||||
    "testdata/fixtures",
 | 
			
		||||
)
 | 
			
		||||
if err != nil {
 | 
			
		||||
    log.Fatalf("Error generating fixtures: %v", err)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
> This was thought to run in small sample databases. It will likely break
 | 
			
		||||
if run in a production/big database.
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
 | 
			
		||||
Tests were written to ensure everything work as expected. You can run the tests
 | 
			
		||||
with:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# running tests for PostgreSQL
 | 
			
		||||
go test -tags postgresql
 | 
			
		||||
 | 
			
		||||
# running test for MySQL
 | 
			
		||||
go test -tags mysql
 | 
			
		||||
 | 
			
		||||
# running tests for SQLite
 | 
			
		||||
go test -tags sqlite
 | 
			
		||||
 | 
			
		||||
# running tests for SQL Server
 | 
			
		||||
go test -tags sqlserver
 | 
			
		||||
 | 
			
		||||
# running tests for Oracle
 | 
			
		||||
go test -tags oracle
 | 
			
		||||
 | 
			
		||||
# running test for multiple databases at once
 | 
			
		||||
go test -tags 'sqlite postgresql mysql'
 | 
			
		||||
 | 
			
		||||
# running tests + benchmark
 | 
			
		||||
go test -v -bench=. -tags postgresql
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Travis runs tests for PostgreSQL, MySQL and SQLite. AppVeyor run for all
 | 
			
		||||
these and also Microsoft SQL Server.
 | 
			
		||||
 | 
			
		||||
To set the connection string of tests for each database, copy the `.sample.env`
 | 
			
		||||
file as `.env` and edit it according to your environment.
 | 
			
		||||
 | 
			
		||||
## Alternatives
 | 
			
		||||
 | 
			
		||||
If you don't think using fixtures is a good idea, you can try one of these
 | 
			
		||||
packages instead:
 | 
			
		||||
 | 
			
		||||
- [factory-go][factorygo]: Factory for Go. Inspired by Python's Factory Boy
 | 
			
		||||
and Ruby's Factory Girl
 | 
			
		||||
- [go-txdb (Single transaction SQL driver for Go)][gotxdb]: Use a single
 | 
			
		||||
database transaction for each functional test, so you can rollback to
 | 
			
		||||
previous state between tests to have the same database state in all tests
 | 
			
		||||
- [go-sqlmock][gosqlmock]: A mock for the sql.DB interface. This allow you to
 | 
			
		||||
unit test database code without having to connect to a real database
 | 
			
		||||
- [dbcleaner][dbcleaner] - Clean database for testing, inspired by
 | 
			
		||||
database_cleaner for Ruby
 | 
			
		||||
 | 
			
		||||
[railstests]: http://guides.rubyonrails.org/testing.html#the-test-database
 | 
			
		||||
[gotxdb]: https://github.com/DATA-DOG/go-txdb
 | 
			
		||||
[gosqlmock]: https://github.com/DATA-DOG/go-sqlmock
 | 
			
		||||
[factorygo]: https://github.com/bluele/factory-go
 | 
			
		||||
[dbcleaner]: https://github.com/khaiql/dbcleaner
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/gopkg.in/testfixtures.v2/Taskfile.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/gopkg.in/testfixtures.v2/Taskfile.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
# github.com/go-task/task
 | 
			
		||||
 | 
			
		||||
version: '2'
 | 
			
		||||
 | 
			
		||||
tasks:
 | 
			
		||||
  dl-deps:
 | 
			
		||||
    desc: Download cli deps
 | 
			
		||||
    cmds:
 | 
			
		||||
      - go get -u github.com/golang/lint/golint
 | 
			
		||||
 | 
			
		||||
  lint:
 | 
			
		||||
    desc: Runs golint
 | 
			
		||||
    cmds:
 | 
			
		||||
      - golint .
 | 
			
		||||
 | 
			
		||||
  test-free:
 | 
			
		||||
    desc: Test free databases (PG, MySQL and SQLite)
 | 
			
		||||
    cmds:
 | 
			
		||||
      - task: test-pg
 | 
			
		||||
      - task: test-mysql
 | 
			
		||||
      - task: test-sqlite
 | 
			
		||||
 | 
			
		||||
  test-all:
 | 
			
		||||
    desc: Test all databases (PG, MySQL, SQLite, SQLServer and Oracle)
 | 
			
		||||
    cmds:
 | 
			
		||||
      - task: test-pg
 | 
			
		||||
      - task: test-mysql
 | 
			
		||||
      - task: test-sqlite
 | 
			
		||||
      - task: test-sqlserver
 | 
			
		||||
      - task: test-oracle
 | 
			
		||||
 | 
			
		||||
  test-pg:
 | 
			
		||||
    desc: Test PostgreSQL
 | 
			
		||||
    cmds:
 | 
			
		||||
      - task: test-db
 | 
			
		||||
        vars: {DATABASE: postgresql}
 | 
			
		||||
 | 
			
		||||
  test-mysql:
 | 
			
		||||
    desc: Test MySQL
 | 
			
		||||
    cmds:
 | 
			
		||||
      - task: test-db
 | 
			
		||||
        vars: {DATABASE: mysql}
 | 
			
		||||
 | 
			
		||||
  test-sqlite:
 | 
			
		||||
    desc: Test SQLite
 | 
			
		||||
    cmds:
 | 
			
		||||
      - task: test-db
 | 
			
		||||
        vars: {DATABASE: sqlite}
 | 
			
		||||
 | 
			
		||||
  test-sqlserver:
 | 
			
		||||
    desc: Test SQLServer
 | 
			
		||||
    cmds:
 | 
			
		||||
      - task: test-db
 | 
			
		||||
        vars: {DATABASE: sqlserver}
 | 
			
		||||
 | 
			
		||||
  test-oracle:
 | 
			
		||||
    desc: Test Oracle
 | 
			
		||||
    cmds:
 | 
			
		||||
      - task: test-db
 | 
			
		||||
        vars: {DATABASE: oracle}
 | 
			
		||||
 | 
			
		||||
  test-db:
 | 
			
		||||
    cmds:
 | 
			
		||||
      - go test -v -tags {{.DATABASE}}
 | 
			
		||||
							
								
								
									
										51
									
								
								vendor/gopkg.in/testfixtures.v2/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								vendor/gopkg.in/testfixtures.v2/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
version: '{build}'
 | 
			
		||||
 | 
			
		||||
clone_folder: C:\GOPATH\src\gopkg.in\testfixtures.v2
 | 
			
		||||
 | 
			
		||||
build: false
 | 
			
		||||
deploy: false
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  - postgresql96
 | 
			
		||||
  - mysql
 | 
			
		||||
  - mssql2017
 | 
			
		||||
 | 
			
		||||
environment:
 | 
			
		||||
  POSTGRES_PATH: C:\Program Files\PostgreSQL\9.6
 | 
			
		||||
  PGUSER: postgres
 | 
			
		||||
  PGPASSWORD: Password12!
 | 
			
		||||
  PG_CONN_STRING: 'user=postgres password=Password12! dbname=testfixtures_test sslmode=disable'
 | 
			
		||||
 | 
			
		||||
  MYSQL_PATH: C:\Program Files\MySql\MySQL Server 5.7
 | 
			
		||||
  MYSQL_PWD: Password12!
 | 
			
		||||
  MYSQL_CONN_STRING: 'root:Password12!@/testfixtures_test?multiStatements=true'
 | 
			
		||||
 | 
			
		||||
  SQLITE_CONN_STRING: 'testdb.sqlite3'
 | 
			
		||||
 | 
			
		||||
  SQLSERVER_CONN_STRING: 'server=localhost;database=testfixtures_test;user id=sa;password=Password12!;encrypt=disable'
 | 
			
		||||
 | 
			
		||||
  MINGW_PATH: C:\MinGW
 | 
			
		||||
 | 
			
		||||
  GOPATH: C:\GOPATH
 | 
			
		||||
  GOVERSION: 1.10.3
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - SET PATH=%POSTGRES_PATH%\bin;%MYSQL_PATH%\bin;%MINGW_PATH%\bin;%PATH%
 | 
			
		||||
 | 
			
		||||
  - rmdir C:\go /s /q
 | 
			
		||||
  - appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-386.msi
 | 
			
		||||
  - msiexec /i go%GOVERSION%.windows-386.msi /q
 | 
			
		||||
  - go version
 | 
			
		||||
 | 
			
		||||
build_script:
 | 
			
		||||
  - createdb testfixtures_test
 | 
			
		||||
  - mysql -e "CREATE DATABASE testfixtures_test;" --user=root
 | 
			
		||||
  - sqlcmd -S localhost,1433 -U sa -P Password12! -Q "CREATE DATABASE testfixtures_test" -d "master"
 | 
			
		||||
 | 
			
		||||
test_script:
 | 
			
		||||
  - go get -t -tags "sqlite postgresql mysql sqlserver" ./...
 | 
			
		||||
  - go install -v ./...
 | 
			
		||||
  - go test -v -tags postgresql
 | 
			
		||||
  - go test -v -tags mysql
 | 
			
		||||
  - go test -v -tags sqlserver
 | 
			
		||||
  - go test -v -tags sqlite
 | 
			
		||||
							
								
								
									
										77
									
								
								vendor/gopkg.in/warnings.v0/README
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								vendor/gopkg.in/warnings.v0/README
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
Package warnings implements error handling with non-fatal errors (warnings).
 | 
			
		||||
 | 
			
		||||
import path:   "gopkg.in/warnings.v0"
 | 
			
		||||
package docs:  https://godoc.org/gopkg.in/warnings.v0 
 | 
			
		||||
issues:        https://github.com/go-warnings/warnings/issues
 | 
			
		||||
pull requests: https://github.com/go-warnings/warnings/pulls
 | 
			
		||||
 | 
			
		||||
A recurring pattern in Go programming is the following:
 | 
			
		||||
 | 
			
		||||
 func myfunc(params) error {
 | 
			
		||||
     if err := doSomething(...); err != nil {
 | 
			
		||||
         return err
 | 
			
		||||
     }
 | 
			
		||||
     if err := doSomethingElse(...); err != nil {
 | 
			
		||||
         return err
 | 
			
		||||
     }
 | 
			
		||||
     if ok := doAnotherThing(...); !ok {
 | 
			
		||||
         return errors.New("my error")
 | 
			
		||||
     }
 | 
			
		||||
     ...
 | 
			
		||||
     return nil
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
This pattern allows interrupting the flow on any received error. But what if
 | 
			
		||||
there are errors that should be noted but still not fatal, for which the flow
 | 
			
		||||
should not be interrupted? Implementing such logic at each if statement would
 | 
			
		||||
make the code complex and the flow much harder to follow.
 | 
			
		||||
 | 
			
		||||
Package warnings provides the Collector type and a clean and simple pattern
 | 
			
		||||
for achieving such logic. The Collector takes care of deciding when to break
 | 
			
		||||
the flow and when to continue, collecting any non-fatal errors (warnings)
 | 
			
		||||
along the way. The only requirement is that fatal and non-fatal errors can be
 | 
			
		||||
distinguished programmatically; that is a function such as
 | 
			
		||||
 | 
			
		||||
 IsFatal(error) bool
 | 
			
		||||
 | 
			
		||||
must be implemented. The following is an example of what the above snippet
 | 
			
		||||
could look like using the warnings package:
 | 
			
		||||
 | 
			
		||||
 import "gopkg.in/warnings.v0"
 | 
			
		||||
 | 
			
		||||
 func isFatal(err error) bool {
 | 
			
		||||
     _, ok := err.(WarningType)
 | 
			
		||||
     return !ok
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 func myfunc(params) error {
 | 
			
		||||
     c := warnings.NewCollector(isFatal)
 | 
			
		||||
     c.FatalWithWarnings = true
 | 
			
		||||
     if err := c.Collect(doSomething()); err != nil {
 | 
			
		||||
         return err
 | 
			
		||||
     }
 | 
			
		||||
     if err := c.Collect(doSomethingElse(...)); err != nil {
 | 
			
		||||
         return err
 | 
			
		||||
     }
 | 
			
		||||
     if ok := doAnotherThing(...); !ok {
 | 
			
		||||
         if err := c.Collect(errors.New("my error")); err != nil {
 | 
			
		||||
             return err
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
     ...
 | 
			
		||||
     return c.Done()
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
For an example of a non-trivial code base using this library, see
 | 
			
		||||
gopkg.in/gcfg.v1
 | 
			
		||||
 | 
			
		||||
Rules for using warnings
 | 
			
		||||
 | 
			
		||||
 - ensure that warnings are programmatically distinguishable from fatal
 | 
			
		||||
   errors (i.e. implement an isFatal function and any necessary error types)
 | 
			
		||||
 - ensure that there is a single Collector instance for a call of each
 | 
			
		||||
   exported function
 | 
			
		||||
 - ensure that all errors (fatal or warning) are fed through Collect
 | 
			
		||||
 - ensure that every time an error is returned, it is one returned by a
 | 
			
		||||
   Collector (from Collect or Done)
 | 
			
		||||
 - ensure that Collect is never called after Done
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/gopkg.in/yaml.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/gopkg.in/yaml.v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
language: go
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
    - 1.4
 | 
			
		||||
    - 1.5
 | 
			
		||||
    - 1.6
 | 
			
		||||
    - 1.7
 | 
			
		||||
    - 1.8
 | 
			
		||||
    - 1.9
 | 
			
		||||
    - tip
 | 
			
		||||
 | 
			
		||||
go_import_path: gopkg.in/yaml.v2
 | 
			
		||||
							
								
								
									
										208
									
								
								vendor/gopkg.in/yaml.v2/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										208
									
								
								vendor/gopkg.in/yaml.v2/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,13 +1,201 @@
 | 
			
		||||
Copyright 2011-2016 Canonical Ltd.
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright {yyyy} {name of copyright owner}
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								vendor/gopkg.in/yaml.v2/NOTICE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/gopkg.in/yaml.v2/NOTICE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
Copyright 2011-2016 Canonical Ltd.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
							
								
								
									
										133
									
								
								vendor/gopkg.in/yaml.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								vendor/gopkg.in/yaml.v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
# YAML support for the Go language
 | 
			
		||||
 | 
			
		||||
Introduction
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
The yaml package enables Go programs to comfortably encode and decode YAML
 | 
			
		||||
values. It was developed within [Canonical](https://www.canonical.com) as
 | 
			
		||||
part of the [juju](https://juju.ubuntu.com) project, and is based on a
 | 
			
		||||
pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
 | 
			
		||||
C library to parse and generate YAML data quickly and reliably.
 | 
			
		||||
 | 
			
		||||
Compatibility
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
The yaml package supports most of YAML 1.1 and 1.2, including support for
 | 
			
		||||
anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
 | 
			
		||||
implemented, and base-60 floats from YAML 1.1 are purposefully not
 | 
			
		||||
supported since they're a poor design and are gone in YAML 1.2.
 | 
			
		||||
 | 
			
		||||
Installation and usage
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
The import path for the package is *gopkg.in/yaml.v2*.
 | 
			
		||||
 | 
			
		||||
To install it, run:
 | 
			
		||||
 | 
			
		||||
    go get gopkg.in/yaml.v2
 | 
			
		||||
 | 
			
		||||
API documentation
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
If opened in a browser, the import path itself leads to the API documentation:
 | 
			
		||||
 | 
			
		||||
  * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
 | 
			
		||||
 | 
			
		||||
API stability
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Example
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
```Go
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
        "fmt"
 | 
			
		||||
        "log"
 | 
			
		||||
 | 
			
		||||
        "gopkg.in/yaml.v2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var data = `
 | 
			
		||||
a: Easy!
 | 
			
		||||
b:
 | 
			
		||||
  c: 2
 | 
			
		||||
  d: [3, 4]
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
// Note: struct fields must be public in order for unmarshal to
 | 
			
		||||
// correctly populate the data.
 | 
			
		||||
type T struct {
 | 
			
		||||
        A string
 | 
			
		||||
        B struct {
 | 
			
		||||
                RenamedC int   `yaml:"c"`
 | 
			
		||||
                D        []int `yaml:",flow"`
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
        t := T{}
 | 
			
		||||
    
 | 
			
		||||
        err := yaml.Unmarshal([]byte(data), &t)
 | 
			
		||||
        if err != nil {
 | 
			
		||||
                log.Fatalf("error: %v", err)
 | 
			
		||||
        }
 | 
			
		||||
        fmt.Printf("--- t:\n%v\n\n", t)
 | 
			
		||||
    
 | 
			
		||||
        d, err := yaml.Marshal(&t)
 | 
			
		||||
        if err != nil {
 | 
			
		||||
                log.Fatalf("error: %v", err)
 | 
			
		||||
        }
 | 
			
		||||
        fmt.Printf("--- t dump:\n%s\n\n", string(d))
 | 
			
		||||
    
 | 
			
		||||
        m := make(map[interface{}]interface{})
 | 
			
		||||
    
 | 
			
		||||
        err = yaml.Unmarshal([]byte(data), &m)
 | 
			
		||||
        if err != nil {
 | 
			
		||||
                log.Fatalf("error: %v", err)
 | 
			
		||||
        }
 | 
			
		||||
        fmt.Printf("--- m:\n%v\n\n", m)
 | 
			
		||||
    
 | 
			
		||||
        d, err = yaml.Marshal(&m)
 | 
			
		||||
        if err != nil {
 | 
			
		||||
                log.Fatalf("error: %v", err)
 | 
			
		||||
        }
 | 
			
		||||
        fmt.Printf("--- m dump:\n%s\n\n", string(d))
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This example will generate the following output:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
--- t:
 | 
			
		||||
{Easy! {2 [3 4]}}
 | 
			
		||||
 | 
			
		||||
--- t dump:
 | 
			
		||||
a: Easy!
 | 
			
		||||
b:
 | 
			
		||||
  c: 2
 | 
			
		||||
  d: [3, 4]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--- m:
 | 
			
		||||
map[a:Easy! b:map[c:2 d:[3 4]]]
 | 
			
		||||
 | 
			
		||||
--- m dump:
 | 
			
		||||
a: Easy!
 | 
			
		||||
b:
 | 
			
		||||
  c: 2
 | 
			
		||||
  d:
 | 
			
		||||
  - 3
 | 
			
		||||
  - 4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								vendor/gopkg.in/yaml.v2/apic.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										55
									
								
								vendor/gopkg.in/yaml.v2/apic.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,7 +2,6 @@ package yaml
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
 | 
			
		||||
@@ -48,9 +47,9 @@ func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err
 | 
			
		||||
	return n, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// File read handler.
 | 
			
		||||
func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
 | 
			
		||||
	return parser.input_file.Read(buffer)
 | 
			
		||||
// Reader read handler.
 | 
			
		||||
func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
 | 
			
		||||
	return parser.input_reader.Read(buffer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set a string input.
 | 
			
		||||
@@ -64,12 +63,12 @@ func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set a file input.
 | 
			
		||||
func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) {
 | 
			
		||||
func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
 | 
			
		||||
	if parser.read_handler != nil {
 | 
			
		||||
		panic("must set the input source only once")
 | 
			
		||||
	}
 | 
			
		||||
	parser.read_handler = yaml_file_read_handler
 | 
			
		||||
	parser.input_file = file
 | 
			
		||||
	parser.read_handler = yaml_reader_read_handler
 | 
			
		||||
	parser.input_reader = r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set the source encoding.
 | 
			
		||||
@@ -81,14 +80,13 @@ func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create a new emitter object.
 | 
			
		||||
func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
 | 
			
		||||
func yaml_emitter_initialize(emitter *yaml_emitter_t) {
 | 
			
		||||
	*emitter = yaml_emitter_t{
 | 
			
		||||
		buffer:     make([]byte, output_buffer_size),
 | 
			
		||||
		raw_buffer: make([]byte, 0, output_raw_buffer_size),
 | 
			
		||||
		states:     make([]yaml_emitter_state_t, 0, initial_stack_size),
 | 
			
		||||
		events:     make([]yaml_event_t, 0, initial_queue_size),
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Destroy an emitter object.
 | 
			
		||||
@@ -102,9 +100,10 @@ func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// File write handler.
 | 
			
		||||
func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
 | 
			
		||||
	_, err := emitter.output_file.Write(buffer)
 | 
			
		||||
// yaml_writer_write_handler uses emitter.output_writer to write the
 | 
			
		||||
// emitted text.
 | 
			
		||||
func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
 | 
			
		||||
	_, err := emitter.output_writer.Write(buffer)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -118,12 +117,12 @@ func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]by
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set a file output.
 | 
			
		||||
func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
 | 
			
		||||
func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
 | 
			
		||||
	if emitter.write_handler != nil {
 | 
			
		||||
		panic("must set the output target only once")
 | 
			
		||||
	}
 | 
			
		||||
	emitter.write_handler = yaml_file_write_handler
 | 
			
		||||
	emitter.output_file = file
 | 
			
		||||
	emitter.write_handler = yaml_writer_write_handler
 | 
			
		||||
	emitter.output_writer = w
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set the output encoding.
 | 
			
		||||
@@ -252,41 +251,41 @@ func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Create STREAM-START.
 | 
			
		||||
func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
 | 
			
		||||
func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
 | 
			
		||||
	*event = yaml_event_t{
 | 
			
		||||
		typ:      yaml_STREAM_START_EVENT,
 | 
			
		||||
		encoding: encoding,
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create STREAM-END.
 | 
			
		||||
func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
 | 
			
		||||
func yaml_stream_end_event_initialize(event *yaml_event_t) {
 | 
			
		||||
	*event = yaml_event_t{
 | 
			
		||||
		typ: yaml_STREAM_END_EVENT,
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create DOCUMENT-START.
 | 
			
		||||
func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
 | 
			
		||||
	tag_directives []yaml_tag_directive_t, implicit bool) bool {
 | 
			
		||||
func yaml_document_start_event_initialize(
 | 
			
		||||
	event *yaml_event_t,
 | 
			
		||||
	version_directive *yaml_version_directive_t,
 | 
			
		||||
	tag_directives []yaml_tag_directive_t,
 | 
			
		||||
	implicit bool,
 | 
			
		||||
) {
 | 
			
		||||
	*event = yaml_event_t{
 | 
			
		||||
		typ:               yaml_DOCUMENT_START_EVENT,
 | 
			
		||||
		version_directive: version_directive,
 | 
			
		||||
		tag_directives:    tag_directives,
 | 
			
		||||
		implicit:          implicit,
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create DOCUMENT-END.
 | 
			
		||||
func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
 | 
			
		||||
func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
 | 
			
		||||
	*event = yaml_event_t{
 | 
			
		||||
		typ:      yaml_DOCUMENT_END_EVENT,
 | 
			
		||||
		implicit: implicit,
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///*
 | 
			
		||||
@@ -348,7 +347,7 @@ func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create MAPPING-START.
 | 
			
		||||
func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
 | 
			
		||||
func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
 | 
			
		||||
	*event = yaml_event_t{
 | 
			
		||||
		typ:      yaml_MAPPING_START_EVENT,
 | 
			
		||||
		anchor:   anchor,
 | 
			
		||||
@@ -356,15 +355,13 @@ func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte
 | 
			
		||||
		implicit: implicit,
 | 
			
		||||
		style:    yaml_style_t(style),
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create MAPPING-END.
 | 
			
		||||
func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
 | 
			
		||||
func yaml_mapping_end_event_initialize(event *yaml_event_t) {
 | 
			
		||||
	*event = yaml_event_t{
 | 
			
		||||
		typ: yaml_MAPPING_END_EVENT,
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Destroy an event object.
 | 
			
		||||
@@ -471,7 +468,7 @@ func yaml_event_delete(event *yaml_event_t) {
 | 
			
		||||
//    } context
 | 
			
		||||
//    tag_directive *yaml_tag_directive_t
 | 
			
		||||
//
 | 
			
		||||
//    context.error = YAML_NO_ERROR // Eliminate a compliler warning.
 | 
			
		||||
//    context.error = YAML_NO_ERROR // Eliminate a compiler warning.
 | 
			
		||||
//
 | 
			
		||||
//    assert(document) // Non-NULL document object is expected.
 | 
			
		||||
//
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										250
									
								
								vendor/gopkg.in/yaml.v2/decode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										250
									
								
								vendor/gopkg.in/yaml.v2/decode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"encoding"
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"math"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strconv"
 | 
			
		||||
@@ -22,19 +23,22 @@ type node struct {
 | 
			
		||||
	kind         int
 | 
			
		||||
	line, column int
 | 
			
		||||
	tag          string
 | 
			
		||||
	value        string
 | 
			
		||||
	implicit     bool
 | 
			
		||||
	children     []*node
 | 
			
		||||
	anchors      map[string]*node
 | 
			
		||||
	// For an alias node, alias holds the resolved alias.
 | 
			
		||||
	alias    *node
 | 
			
		||||
	value    string
 | 
			
		||||
	implicit bool
 | 
			
		||||
	children []*node
 | 
			
		||||
	anchors  map[string]*node
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
// Parser, produces a node tree out of a libyaml event stream.
 | 
			
		||||
 | 
			
		||||
type parser struct {
 | 
			
		||||
	parser yaml_parser_t
 | 
			
		||||
	event  yaml_event_t
 | 
			
		||||
	doc    *node
 | 
			
		||||
	parser   yaml_parser_t
 | 
			
		||||
	event    yaml_event_t
 | 
			
		||||
	doc      *node
 | 
			
		||||
	doneInit bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newParser(b []byte) *parser {
 | 
			
		||||
@@ -42,21 +46,30 @@ func newParser(b []byte) *parser {
 | 
			
		||||
	if !yaml_parser_initialize(&p.parser) {
 | 
			
		||||
		panic("failed to initialize YAML emitter")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(b) == 0 {
 | 
			
		||||
		b = []byte{'\n'}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	yaml_parser_set_input_string(&p.parser, b)
 | 
			
		||||
 | 
			
		||||
	p.skip()
 | 
			
		||||
	if p.event.typ != yaml_STREAM_START_EVENT {
 | 
			
		||||
		panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
 | 
			
		||||
	}
 | 
			
		||||
	p.skip()
 | 
			
		||||
	return &p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newParserFromReader(r io.Reader) *parser {
 | 
			
		||||
	p := parser{}
 | 
			
		||||
	if !yaml_parser_initialize(&p.parser) {
 | 
			
		||||
		panic("failed to initialize YAML emitter")
 | 
			
		||||
	}
 | 
			
		||||
	yaml_parser_set_input_reader(&p.parser, r)
 | 
			
		||||
	return &p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parser) init() {
 | 
			
		||||
	if p.doneInit {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	p.expect(yaml_STREAM_START_EVENT)
 | 
			
		||||
	p.doneInit = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parser) destroy() {
 | 
			
		||||
	if p.event.typ != yaml_NO_EVENT {
 | 
			
		||||
		yaml_event_delete(&p.event)
 | 
			
		||||
@@ -64,16 +77,35 @@ func (p *parser) destroy() {
 | 
			
		||||
	yaml_parser_delete(&p.parser)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parser) skip() {
 | 
			
		||||
	if p.event.typ != yaml_NO_EVENT {
 | 
			
		||||
		if p.event.typ == yaml_STREAM_END_EVENT {
 | 
			
		||||
			failf("attempted to go past the end of stream; corrupted value?")
 | 
			
		||||
// expect consumes an event from the event stream and
 | 
			
		||||
// checks that it's of the expected type.
 | 
			
		||||
func (p *parser) expect(e yaml_event_type_t) {
 | 
			
		||||
	if p.event.typ == yaml_NO_EVENT {
 | 
			
		||||
		if !yaml_parser_parse(&p.parser, &p.event) {
 | 
			
		||||
			p.fail()
 | 
			
		||||
		}
 | 
			
		||||
		yaml_event_delete(&p.event)
 | 
			
		||||
	}
 | 
			
		||||
	if p.event.typ == yaml_STREAM_END_EVENT {
 | 
			
		||||
		failf("attempted to go past the end of stream; corrupted value?")
 | 
			
		||||
	}
 | 
			
		||||
	if p.event.typ != e {
 | 
			
		||||
		p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
 | 
			
		||||
		p.fail()
 | 
			
		||||
	}
 | 
			
		||||
	yaml_event_delete(&p.event)
 | 
			
		||||
	p.event.typ = yaml_NO_EVENT
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// peek peeks at the next event in the event stream,
 | 
			
		||||
// puts the results into p.event and returns the event type.
 | 
			
		||||
func (p *parser) peek() yaml_event_type_t {
 | 
			
		||||
	if p.event.typ != yaml_NO_EVENT {
 | 
			
		||||
		return p.event.typ
 | 
			
		||||
	}
 | 
			
		||||
	if !yaml_parser_parse(&p.parser, &p.event) {
 | 
			
		||||
		p.fail()
 | 
			
		||||
	}
 | 
			
		||||
	return p.event.typ
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parser) fail() {
 | 
			
		||||
@@ -81,6 +113,10 @@ func (p *parser) fail() {
 | 
			
		||||
	var line int
 | 
			
		||||
	if p.parser.problem_mark.line != 0 {
 | 
			
		||||
		line = p.parser.problem_mark.line
 | 
			
		||||
		// Scanner errors don't iterate line before returning error
 | 
			
		||||
		if p.parser.error == yaml_SCANNER_ERROR {
 | 
			
		||||
			line++
 | 
			
		||||
		}
 | 
			
		||||
	} else if p.parser.context_mark.line != 0 {
 | 
			
		||||
		line = p.parser.context_mark.line
 | 
			
		||||
	}
 | 
			
		||||
@@ -103,7 +139,8 @@ func (p *parser) anchor(n *node, anchor []byte) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parser) parse() *node {
 | 
			
		||||
	switch p.event.typ {
 | 
			
		||||
	p.init()
 | 
			
		||||
	switch p.peek() {
 | 
			
		||||
	case yaml_SCALAR_EVENT:
 | 
			
		||||
		return p.scalar()
 | 
			
		||||
	case yaml_ALIAS_EVENT:
 | 
			
		||||
@@ -118,9 +155,8 @@ func (p *parser) parse() *node {
 | 
			
		||||
		// Happens when attempting to decode an empty buffer.
 | 
			
		||||
		return nil
 | 
			
		||||
	default:
 | 
			
		||||
		panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
 | 
			
		||||
		panic("attempted to parse unknown event: " + p.event.typ.String())
 | 
			
		||||
	}
 | 
			
		||||
	panic("unreachable")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parser) node(kind int) *node {
 | 
			
		||||
@@ -135,19 +171,20 @@ func (p *parser) document() *node {
 | 
			
		||||
	n := p.node(documentNode)
 | 
			
		||||
	n.anchors = make(map[string]*node)
 | 
			
		||||
	p.doc = n
 | 
			
		||||
	p.skip()
 | 
			
		||||
	p.expect(yaml_DOCUMENT_START_EVENT)
 | 
			
		||||
	n.children = append(n.children, p.parse())
 | 
			
		||||
	if p.event.typ != yaml_DOCUMENT_END_EVENT {
 | 
			
		||||
		panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
 | 
			
		||||
	}
 | 
			
		||||
	p.skip()
 | 
			
		||||
	p.expect(yaml_DOCUMENT_END_EVENT)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parser) alias() *node {
 | 
			
		||||
	n := p.node(aliasNode)
 | 
			
		||||
	n.value = string(p.event.anchor)
 | 
			
		||||
	p.skip()
 | 
			
		||||
	n.alias = p.doc.anchors[n.value]
 | 
			
		||||
	if n.alias == nil {
 | 
			
		||||
		failf("unknown anchor '%s' referenced", n.value)
 | 
			
		||||
	}
 | 
			
		||||
	p.expect(yaml_ALIAS_EVENT)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -157,29 +194,29 @@ func (p *parser) scalar() *node {
 | 
			
		||||
	n.tag = string(p.event.tag)
 | 
			
		||||
	n.implicit = p.event.implicit
 | 
			
		||||
	p.anchor(n, p.event.anchor)
 | 
			
		||||
	p.skip()
 | 
			
		||||
	p.expect(yaml_SCALAR_EVENT)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parser) sequence() *node {
 | 
			
		||||
	n := p.node(sequenceNode)
 | 
			
		||||
	p.anchor(n, p.event.anchor)
 | 
			
		||||
	p.skip()
 | 
			
		||||
	for p.event.typ != yaml_SEQUENCE_END_EVENT {
 | 
			
		||||
	p.expect(yaml_SEQUENCE_START_EVENT)
 | 
			
		||||
	for p.peek() != yaml_SEQUENCE_END_EVENT {
 | 
			
		||||
		n.children = append(n.children, p.parse())
 | 
			
		||||
	}
 | 
			
		||||
	p.skip()
 | 
			
		||||
	p.expect(yaml_SEQUENCE_END_EVENT)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parser) mapping() *node {
 | 
			
		||||
	n := p.node(mappingNode)
 | 
			
		||||
	p.anchor(n, p.event.anchor)
 | 
			
		||||
	p.skip()
 | 
			
		||||
	for p.event.typ != yaml_MAPPING_END_EVENT {
 | 
			
		||||
	p.expect(yaml_MAPPING_START_EVENT)
 | 
			
		||||
	for p.peek() != yaml_MAPPING_END_EVENT {
 | 
			
		||||
		n.children = append(n.children, p.parse(), p.parse())
 | 
			
		||||
	}
 | 
			
		||||
	p.skip()
 | 
			
		||||
	p.expect(yaml_MAPPING_END_EVENT)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -188,9 +225,10 @@ func (p *parser) mapping() *node {
 | 
			
		||||
 | 
			
		||||
type decoder struct {
 | 
			
		||||
	doc     *node
 | 
			
		||||
	aliases map[string]bool
 | 
			
		||||
	aliases map[*node]bool
 | 
			
		||||
	mapType reflect.Type
 | 
			
		||||
	terrors []string
 | 
			
		||||
	strict  bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
@@ -198,11 +236,13 @@ var (
 | 
			
		||||
	durationType   = reflect.TypeOf(time.Duration(0))
 | 
			
		||||
	defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
 | 
			
		||||
	ifaceType      = defaultMapType.Elem()
 | 
			
		||||
	timeType       = reflect.TypeOf(time.Time{})
 | 
			
		||||
	ptrTimeType    = reflect.TypeOf(&time.Time{})
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func newDecoder() *decoder {
 | 
			
		||||
	d := &decoder{mapType: defaultMapType}
 | 
			
		||||
	d.aliases = make(map[string]bool)
 | 
			
		||||
func newDecoder(strict bool) *decoder {
 | 
			
		||||
	d := &decoder{mapType: defaultMapType, strict: strict}
 | 
			
		||||
	d.aliases = make(map[*node]bool)
 | 
			
		||||
	return d
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -251,7 +291,7 @@ func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
 | 
			
		||||
//
 | 
			
		||||
// If n holds a null value, prepare returns before doing anything.
 | 
			
		||||
func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
 | 
			
		||||
	if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "" && n.implicit) {
 | 
			
		||||
	if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
 | 
			
		||||
		return out, false, false
 | 
			
		||||
	}
 | 
			
		||||
	again := true
 | 
			
		||||
@@ -308,16 +348,13 @@ func (d *decoder) document(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
	an, ok := d.doc.anchors[n.value]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		failf("unknown anchor '%s' referenced", n.value)
 | 
			
		||||
	}
 | 
			
		||||
	if d.aliases[n.value] {
 | 
			
		||||
	if d.aliases[n] {
 | 
			
		||||
		// TODO this could actually be allowed in some circumstances.
 | 
			
		||||
		failf("anchor '%s' value contains itself", n.value)
 | 
			
		||||
	}
 | 
			
		||||
	d.aliases[n.value] = true
 | 
			
		||||
	good = d.unmarshal(an, out)
 | 
			
		||||
	delete(d.aliases, n.value)
 | 
			
		||||
	d.aliases[n] = true
 | 
			
		||||
	good = d.unmarshal(n.alias, out)
 | 
			
		||||
	delete(d.aliases, n)
 | 
			
		||||
	return good
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -329,7 +366,7 @@ func resetMap(out reflect.Value) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
func (d *decoder) scalar(n *node, out reflect.Value) bool {
 | 
			
		||||
	var tag string
 | 
			
		||||
	var resolved interface{}
 | 
			
		||||
	if n.tag == "" && !n.implicit {
 | 
			
		||||
@@ -353,9 +390,26 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if s, ok := resolved.(string); ok && out.CanAddr() {
 | 
			
		||||
		if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
 | 
			
		||||
			err := u.UnmarshalText([]byte(s))
 | 
			
		||||
	if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
 | 
			
		||||
		// We've resolved to exactly the type we want, so use that.
 | 
			
		||||
		out.Set(resolvedv)
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	// Perhaps we can use the value as a TextUnmarshaler to
 | 
			
		||||
	// set its value.
 | 
			
		||||
	if out.CanAddr() {
 | 
			
		||||
		u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
 | 
			
		||||
		if ok {
 | 
			
		||||
			var text []byte
 | 
			
		||||
			if tag == yaml_BINARY_TAG {
 | 
			
		||||
				text = []byte(resolved.(string))
 | 
			
		||||
			} else {
 | 
			
		||||
				// We let any value be unmarshaled into TextUnmarshaler.
 | 
			
		||||
				// That might be more lax than we'd like, but the
 | 
			
		||||
				// TextUnmarshaler itself should bowl out any dubious values.
 | 
			
		||||
				text = []byte(n.value)
 | 
			
		||||
			}
 | 
			
		||||
			err := u.UnmarshalText(text)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				fail(err)
 | 
			
		||||
			}
 | 
			
		||||
@@ -366,46 +420,54 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
	case reflect.String:
 | 
			
		||||
		if tag == yaml_BINARY_TAG {
 | 
			
		||||
			out.SetString(resolved.(string))
 | 
			
		||||
			good = true
 | 
			
		||||
		} else if resolved != nil {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
		if resolved != nil {
 | 
			
		||||
			out.SetString(n.value)
 | 
			
		||||
			good = true
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Interface:
 | 
			
		||||
		if resolved == nil {
 | 
			
		||||
			out.Set(reflect.Zero(out.Type()))
 | 
			
		||||
		} else if tag == yaml_TIMESTAMP_TAG {
 | 
			
		||||
			// It looks like a timestamp but for backward compatibility
 | 
			
		||||
			// reasons we set it as a string, so that code that unmarshals
 | 
			
		||||
			// timestamp-like values into interface{} will continue to
 | 
			
		||||
			// see a string and not a time.Time.
 | 
			
		||||
			// TODO(v3) Drop this.
 | 
			
		||||
			out.Set(reflect.ValueOf(n.value))
 | 
			
		||||
		} else {
 | 
			
		||||
			out.Set(reflect.ValueOf(resolved))
 | 
			
		||||
		}
 | 
			
		||||
		good = true
 | 
			
		||||
		return true
 | 
			
		||||
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 | 
			
		||||
		switch resolved := resolved.(type) {
 | 
			
		||||
		case int:
 | 
			
		||||
			if !out.OverflowInt(int64(resolved)) {
 | 
			
		||||
				out.SetInt(int64(resolved))
 | 
			
		||||
				good = true
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		case int64:
 | 
			
		||||
			if !out.OverflowInt(resolved) {
 | 
			
		||||
				out.SetInt(resolved)
 | 
			
		||||
				good = true
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		case uint64:
 | 
			
		||||
			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 | 
			
		||||
				out.SetInt(int64(resolved))
 | 
			
		||||
				good = true
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		case float64:
 | 
			
		||||
			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
 | 
			
		||||
				out.SetInt(int64(resolved))
 | 
			
		||||
				good = true
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		case string:
 | 
			
		||||
			if out.Type() == durationType {
 | 
			
		||||
				d, err := time.ParseDuration(resolved)
 | 
			
		||||
				if err == nil {
 | 
			
		||||
					out.SetInt(int64(d))
 | 
			
		||||
					good = true
 | 
			
		||||
					return true
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -414,44 +476,49 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
		case int:
 | 
			
		||||
			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 | 
			
		||||
				out.SetUint(uint64(resolved))
 | 
			
		||||
				good = true
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		case int64:
 | 
			
		||||
			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
 | 
			
		||||
				out.SetUint(uint64(resolved))
 | 
			
		||||
				good = true
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		case uint64:
 | 
			
		||||
			if !out.OverflowUint(uint64(resolved)) {
 | 
			
		||||
				out.SetUint(uint64(resolved))
 | 
			
		||||
				good = true
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		case float64:
 | 
			
		||||
			if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
 | 
			
		||||
				out.SetUint(uint64(resolved))
 | 
			
		||||
				good = true
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Bool:
 | 
			
		||||
		switch resolved := resolved.(type) {
 | 
			
		||||
		case bool:
 | 
			
		||||
			out.SetBool(resolved)
 | 
			
		||||
			good = true
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Float32, reflect.Float64:
 | 
			
		||||
		switch resolved := resolved.(type) {
 | 
			
		||||
		case int:
 | 
			
		||||
			out.SetFloat(float64(resolved))
 | 
			
		||||
			good = true
 | 
			
		||||
			return true
 | 
			
		||||
		case int64:
 | 
			
		||||
			out.SetFloat(float64(resolved))
 | 
			
		||||
			good = true
 | 
			
		||||
			return true
 | 
			
		||||
		case uint64:
 | 
			
		||||
			out.SetFloat(float64(resolved))
 | 
			
		||||
			good = true
 | 
			
		||||
			return true
 | 
			
		||||
		case float64:
 | 
			
		||||
			out.SetFloat(resolved)
 | 
			
		||||
			good = true
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Struct:
 | 
			
		||||
		if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
 | 
			
		||||
			out.Set(resolvedv)
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Ptr:
 | 
			
		||||
		if out.Type().Elem() == reflect.TypeOf(resolved) {
 | 
			
		||||
@@ -459,13 +526,11 @@ func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
			elem := reflect.New(out.Type().Elem())
 | 
			
		||||
			elem.Elem().Set(reflect.ValueOf(resolved))
 | 
			
		||||
			out.Set(elem)
 | 
			
		||||
			good = true
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if !good {
 | 
			
		||||
		d.terror(n, tag, out)
 | 
			
		||||
	}
 | 
			
		||||
	return good
 | 
			
		||||
	d.terror(n, tag, out)
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func settableValueOf(i interface{}) reflect.Value {
 | 
			
		||||
@@ -482,6 +547,10 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
	switch out.Kind() {
 | 
			
		||||
	case reflect.Slice:
 | 
			
		||||
		out.Set(reflect.MakeSlice(out.Type(), l, l))
 | 
			
		||||
	case reflect.Array:
 | 
			
		||||
		if l != out.Len() {
 | 
			
		||||
			failf("invalid array: want %d elements but got %d", out.Len(), l)
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Interface:
 | 
			
		||||
		// No type hints. Will have to use a generic sequence.
 | 
			
		||||
		iface = out
 | 
			
		||||
@@ -500,7 +569,9 @@ func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
			j++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	out.Set(out.Slice(0, j))
 | 
			
		||||
	if out.Kind() != reflect.Array {
 | 
			
		||||
		out.Set(out.Slice(0, j))
 | 
			
		||||
	}
 | 
			
		||||
	if iface.IsValid() {
 | 
			
		||||
		iface.Set(out)
 | 
			
		||||
	}
 | 
			
		||||
@@ -561,7 +632,7 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
			}
 | 
			
		||||
			e := reflect.New(et).Elem()
 | 
			
		||||
			if d.unmarshal(n.children[i+1], e) {
 | 
			
		||||
				out.SetMapIndex(k, e)
 | 
			
		||||
				d.setMapIndex(n.children[i+1], out, k, e)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -569,6 +640,14 @@ func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
 | 
			
		||||
	if d.strict && out.MapIndex(k) != zeroValue {
 | 
			
		||||
		d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	out.SetMapIndex(k, v)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
	outt := out.Type()
 | 
			
		||||
	if outt.Elem() != mapItemType {
 | 
			
		||||
@@ -616,6 +695,10 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
		elemType = inlineMap.Type().Elem()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var doneFields []bool
 | 
			
		||||
	if d.strict {
 | 
			
		||||
		doneFields = make([]bool, len(sinfo.FieldsList))
 | 
			
		||||
	}
 | 
			
		||||
	for i := 0; i < l; i += 2 {
 | 
			
		||||
		ni := n.children[i]
 | 
			
		||||
		if isMerge(ni) {
 | 
			
		||||
@@ -626,6 +709,13 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if info, ok := sinfo.FieldsMap[name.String()]; ok {
 | 
			
		||||
			if d.strict {
 | 
			
		||||
				if doneFields[info.Id] {
 | 
			
		||||
					d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				doneFields[info.Id] = true
 | 
			
		||||
			}
 | 
			
		||||
			var field reflect.Value
 | 
			
		||||
			if info.Inline == nil {
 | 
			
		||||
				field = out.Field(info.Num)
 | 
			
		||||
@@ -639,7 +729,9 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
 | 
			
		||||
			}
 | 
			
		||||
			value := reflect.New(elemType).Elem()
 | 
			
		||||
			d.unmarshal(n.children[i+1], value)
 | 
			
		||||
			inlineMap.SetMapIndex(name, value)
 | 
			
		||||
			d.setMapIndex(n.children[i+1], inlineMap, name, value)
 | 
			
		||||
		} else if d.strict {
 | 
			
		||||
			d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/gopkg.in/yaml.v2/emitterc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/gopkg.in/yaml.v2/emitterc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,6 +2,7 @@ package yaml
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Flush the buffer if needed.
 | 
			
		||||
@@ -664,9 +665,8 @@ func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
 | 
			
		||||
		return yaml_emitter_emit_mapping_start(emitter, event)
 | 
			
		||||
	default:
 | 
			
		||||
		return yaml_emitter_set_emitter_error(emitter,
 | 
			
		||||
			"expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
 | 
			
		||||
			fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Expect ALIAS.
 | 
			
		||||
@@ -843,7 +843,7 @@ func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write an achor.
 | 
			
		||||
// Write an anchor.
 | 
			
		||||
func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
 | 
			
		||||
	if emitter.anchor_data.anchor == nil {
 | 
			
		||||
		return true
 | 
			
		||||
@@ -995,10 +995,10 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 | 
			
		||||
		break_space    = false
 | 
			
		||||
		space_break    = false
 | 
			
		||||
 | 
			
		||||
		preceeded_by_whitespace = false
 | 
			
		||||
		followed_by_whitespace  = false
 | 
			
		||||
		previous_space          = false
 | 
			
		||||
		previous_break          = false
 | 
			
		||||
		preceded_by_whitespace = false
 | 
			
		||||
		followed_by_whitespace = false
 | 
			
		||||
		previous_space         = false
 | 
			
		||||
		previous_break         = false
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	emitter.scalar_data.value = value
 | 
			
		||||
@@ -1017,7 +1017,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 | 
			
		||||
		flow_indicators = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	preceeded_by_whitespace = true
 | 
			
		||||
	preceded_by_whitespace = true
 | 
			
		||||
	for i, w := 0, 0; i < len(value); i += w {
 | 
			
		||||
		w = width(value[i])
 | 
			
		||||
		followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
 | 
			
		||||
@@ -1048,7 +1048,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 | 
			
		||||
					block_indicators = true
 | 
			
		||||
				}
 | 
			
		||||
			case '#':
 | 
			
		||||
				if preceeded_by_whitespace {
 | 
			
		||||
				if preceded_by_whitespace {
 | 
			
		||||
					flow_indicators = true
 | 
			
		||||
					block_indicators = true
 | 
			
		||||
				}
 | 
			
		||||
@@ -1089,7 +1089,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
 | 
			
		||||
		preceeded_by_whitespace = is_blankz(value, i)
 | 
			
		||||
		preceded_by_whitespace = is_blankz(value, i)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	emitter.scalar_data.multiline = line_breaks
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										136
									
								
								vendor/gopkg.in/yaml.v2/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										136
									
								
								vendor/gopkg.in/yaml.v2/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -3,12 +3,14 @@ package yaml
 | 
			
		||||
import (
 | 
			
		||||
	"encoding"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type encoder struct {
 | 
			
		||||
@@ -16,25 +18,39 @@ type encoder struct {
 | 
			
		||||
	event   yaml_event_t
 | 
			
		||||
	out     []byte
 | 
			
		||||
	flow    bool
 | 
			
		||||
	// doneInit holds whether the initial stream_start_event has been
 | 
			
		||||
	// emitted.
 | 
			
		||||
	doneInit bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newEncoder() (e *encoder) {
 | 
			
		||||
	e = &encoder{}
 | 
			
		||||
	e.must(yaml_emitter_initialize(&e.emitter))
 | 
			
		||||
func newEncoder() *encoder {
 | 
			
		||||
	e := &encoder{}
 | 
			
		||||
	yaml_emitter_initialize(&e.emitter)
 | 
			
		||||
	yaml_emitter_set_output_string(&e.emitter, &e.out)
 | 
			
		||||
	yaml_emitter_set_unicode(&e.emitter, true)
 | 
			
		||||
	e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING))
 | 
			
		||||
	e.emit()
 | 
			
		||||
	e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true))
 | 
			
		||||
	e.emit()
 | 
			
		||||
	return e
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *encoder) finish() {
 | 
			
		||||
	e.must(yaml_document_end_event_initialize(&e.event, true))
 | 
			
		||||
func newEncoderWithWriter(w io.Writer) *encoder {
 | 
			
		||||
	e := &encoder{}
 | 
			
		||||
	yaml_emitter_initialize(&e.emitter)
 | 
			
		||||
	yaml_emitter_set_output_writer(&e.emitter, w)
 | 
			
		||||
	yaml_emitter_set_unicode(&e.emitter, true)
 | 
			
		||||
	return e
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *encoder) init() {
 | 
			
		||||
	if e.doneInit {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
 | 
			
		||||
	e.emit()
 | 
			
		||||
	e.doneInit = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *encoder) finish() {
 | 
			
		||||
	e.emitter.open_ended = false
 | 
			
		||||
	e.must(yaml_stream_end_event_initialize(&e.event))
 | 
			
		||||
	yaml_stream_end_event_initialize(&e.event)
 | 
			
		||||
	e.emit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -44,9 +60,7 @@ func (e *encoder) destroy() {
 | 
			
		||||
 | 
			
		||||
func (e *encoder) emit() {
 | 
			
		||||
	// This will internally delete the e.event value.
 | 
			
		||||
	if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT {
 | 
			
		||||
		e.must(false)
 | 
			
		||||
	}
 | 
			
		||||
	e.must(yaml_emitter_emit(&e.emitter, &e.event))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *encoder) must(ok bool) {
 | 
			
		||||
@@ -59,13 +73,28 @@ func (e *encoder) must(ok bool) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *encoder) marshalDoc(tag string, in reflect.Value) {
 | 
			
		||||
	e.init()
 | 
			
		||||
	yaml_document_start_event_initialize(&e.event, nil, nil, true)
 | 
			
		||||
	e.emit()
 | 
			
		||||
	e.marshal(tag, in)
 | 
			
		||||
	yaml_document_end_event_initialize(&e.event, true)
 | 
			
		||||
	e.emit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *encoder) marshal(tag string, in reflect.Value) {
 | 
			
		||||
	if !in.IsValid() {
 | 
			
		||||
	if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
 | 
			
		||||
		e.nilv()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	iface := in.Interface()
 | 
			
		||||
	if m, ok := iface.(Marshaler); ok {
 | 
			
		||||
	switch m := iface.(type) {
 | 
			
		||||
	case time.Time, *time.Time:
 | 
			
		||||
		// Although time.Time implements TextMarshaler,
 | 
			
		||||
		// we don't want to treat it as a string for YAML
 | 
			
		||||
		// purposes because YAML has special support for
 | 
			
		||||
		// timestamps.
 | 
			
		||||
	case Marshaler:
 | 
			
		||||
		v, err := m.MarshalYAML()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fail(err)
 | 
			
		||||
@@ -75,31 +104,34 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		in = reflect.ValueOf(v)
 | 
			
		||||
	} else if m, ok := iface.(encoding.TextMarshaler); ok {
 | 
			
		||||
	case encoding.TextMarshaler:
 | 
			
		||||
		text, err := m.MarshalText()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fail(err)
 | 
			
		||||
		}
 | 
			
		||||
		in = reflect.ValueOf(string(text))
 | 
			
		||||
	case nil:
 | 
			
		||||
		e.nilv()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	switch in.Kind() {
 | 
			
		||||
	case reflect.Interface:
 | 
			
		||||
		if in.IsNil() {
 | 
			
		||||
			e.nilv()
 | 
			
		||||
		} else {
 | 
			
		||||
			e.marshal(tag, in.Elem())
 | 
			
		||||
		}
 | 
			
		||||
		e.marshal(tag, in.Elem())
 | 
			
		||||
	case reflect.Map:
 | 
			
		||||
		e.mapv(tag, in)
 | 
			
		||||
	case reflect.Ptr:
 | 
			
		||||
		if in.IsNil() {
 | 
			
		||||
			e.nilv()
 | 
			
		||||
		if in.Type() == ptrTimeType {
 | 
			
		||||
			e.timev(tag, in.Elem())
 | 
			
		||||
		} else {
 | 
			
		||||
			e.marshal(tag, in.Elem())
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Struct:
 | 
			
		||||
		e.structv(tag, in)
 | 
			
		||||
	case reflect.Slice:
 | 
			
		||||
		if in.Type() == timeType {
 | 
			
		||||
			e.timev(tag, in)
 | 
			
		||||
		} else {
 | 
			
		||||
			e.structv(tag, in)
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Slice, reflect.Array:
 | 
			
		||||
		if in.Type().Elem() == mapItemType {
 | 
			
		||||
			e.itemsv(tag, in)
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -191,10 +223,10 @@ func (e *encoder) mappingv(tag string, f func()) {
 | 
			
		||||
		e.flow = false
 | 
			
		||||
		style = yaml_FLOW_MAPPING_STYLE
 | 
			
		||||
	}
 | 
			
		||||
	e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
 | 
			
		||||
	yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
 | 
			
		||||
	e.emit()
 | 
			
		||||
	f()
 | 
			
		||||
	e.must(yaml_mapping_end_event_initialize(&e.event))
 | 
			
		||||
	yaml_mapping_end_event_initialize(&e.event)
 | 
			
		||||
	e.emit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -240,23 +272,36 @@ var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0
 | 
			
		||||
func (e *encoder) stringv(tag string, in reflect.Value) {
 | 
			
		||||
	var style yaml_scalar_style_t
 | 
			
		||||
	s := in.String()
 | 
			
		||||
	rtag, rs := resolve("", s)
 | 
			
		||||
	if rtag == yaml_BINARY_TAG {
 | 
			
		||||
		if tag == "" || tag == yaml_STR_TAG {
 | 
			
		||||
			tag = rtag
 | 
			
		||||
			s = rs.(string)
 | 
			
		||||
		} else if tag == yaml_BINARY_TAG {
 | 
			
		||||
	canUsePlain := true
 | 
			
		||||
	switch {
 | 
			
		||||
	case !utf8.ValidString(s):
 | 
			
		||||
		if tag == yaml_BINARY_TAG {
 | 
			
		||||
			failf("explicitly tagged !!binary data must be base64-encoded")
 | 
			
		||||
		} else {
 | 
			
		||||
		}
 | 
			
		||||
		if tag != "" {
 | 
			
		||||
			failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
 | 
			
		||||
		}
 | 
			
		||||
		// It can't be encoded directly as YAML so use a binary tag
 | 
			
		||||
		// and encode it as base64.
 | 
			
		||||
		tag = yaml_BINARY_TAG
 | 
			
		||||
		s = encodeBase64(s)
 | 
			
		||||
	case tag == "":
 | 
			
		||||
		// Check to see if it would resolve to a specific
 | 
			
		||||
		// tag when encoded unquoted. If it doesn't,
 | 
			
		||||
		// there's no need to quote it.
 | 
			
		||||
		rtag, _ := resolve("", s)
 | 
			
		||||
		canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
 | 
			
		||||
	}
 | 
			
		||||
	if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
 | 
			
		||||
		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
 | 
			
		||||
	} else if strings.Contains(s, "\n") {
 | 
			
		||||
	// Note: it's possible for user code to emit invalid YAML
 | 
			
		||||
	// if they explicitly specify a tag and a string containing
 | 
			
		||||
	// text that's incompatible with that tag.
 | 
			
		||||
	switch {
 | 
			
		||||
	case strings.Contains(s, "\n"):
 | 
			
		||||
		style = yaml_LITERAL_SCALAR_STYLE
 | 
			
		||||
	} else {
 | 
			
		||||
	case canUsePlain:
 | 
			
		||||
		style = yaml_PLAIN_SCALAR_STYLE
 | 
			
		||||
	default:
 | 
			
		||||
		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
 | 
			
		||||
	}
 | 
			
		||||
	e.emitScalar(s, "", tag, style)
 | 
			
		||||
}
 | 
			
		||||
@@ -281,9 +326,20 @@ func (e *encoder) uintv(tag string, in reflect.Value) {
 | 
			
		||||
	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *encoder) timev(tag string, in reflect.Value) {
 | 
			
		||||
	t := in.Interface().(time.Time)
 | 
			
		||||
	s := t.Format(time.RFC3339Nano)
 | 
			
		||||
	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *encoder) floatv(tag string, in reflect.Value) {
 | 
			
		||||
	// FIXME: Handle 64 bits here.
 | 
			
		||||
	s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
 | 
			
		||||
	// Issue #352: When formatting, use the precision of the underlying value
 | 
			
		||||
	precision := 64
 | 
			
		||||
	if in.Kind() == reflect.Float32 {
 | 
			
		||||
		precision = 32
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
 | 
			
		||||
	switch s {
 | 
			
		||||
	case "+Inf":
 | 
			
		||||
		s = ".inf"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/gopkg.in/yaml.v2/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/gopkg.in/yaml.v2/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
module "gopkg.in/yaml.v2"
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	"gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/gopkg.in/yaml.v2/parserc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/gopkg.in/yaml.v2/parserc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -166,7 +166,6 @@ func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool
 | 
			
		||||
	default:
 | 
			
		||||
		panic("invalid parser state")
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parse the production:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/gopkg.in/yaml.v2/readerc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/gopkg.in/yaml.v2/readerc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -93,9 +93,18 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
 | 
			
		||||
		panic("read handler must be set")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// [Go] This function was changed to guarantee the requested length size at EOF.
 | 
			
		||||
	// The fact we need to do this is pretty awful, but the description above implies
 | 
			
		||||
	// for that to be the case, and there are tests 
 | 
			
		||||
 | 
			
		||||
	// If the EOF flag is set and the raw buffer is empty, do nothing.
 | 
			
		||||
	if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
 | 
			
		||||
		return true
 | 
			
		||||
		// [Go] ACTUALLY! Read the documentation of this function above.
 | 
			
		||||
		// This is just broken. To return true, we need to have the
 | 
			
		||||
		// given length in the buffer. Not doing that means every single
 | 
			
		||||
		// check that calls this function to make sure the buffer has a
 | 
			
		||||
		// given length is Go) panicking; or C) accessing invalid memory.
 | 
			
		||||
		//return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Return if the buffer contains enough characters.
 | 
			
		||||
@@ -389,6 +398,15 @@ func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// [Go] Read the documentation of this function above. To return true,
 | 
			
		||||
	// we need to have the given length in the buffer. Not doing that means
 | 
			
		||||
	// every single check that calls this function to make sure the buffer
 | 
			
		||||
	// has a given length is Go) panicking; or C) accessing invalid memory.
 | 
			
		||||
	// This happens here due to the EOF above breaking early.
 | 
			
		||||
	for buffer_len < length {
 | 
			
		||||
		parser.buffer[buffer_len] = 0
 | 
			
		||||
		buffer_len++
 | 
			
		||||
	}
 | 
			
		||||
	parser.buffer = parser.buffer[:buffer_len]
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										91
									
								
								vendor/gopkg.in/yaml.v2/resolve.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										91
									
								
								vendor/gopkg.in/yaml.v2/resolve.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -3,9 +3,10 @@ package yaml
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"math"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type resolveMapItem struct {
 | 
			
		||||
@@ -74,12 +75,14 @@ func longTag(tag string) string {
 | 
			
		||||
 | 
			
		||||
func resolvableTag(tag string) bool {
 | 
			
		||||
	switch tag {
 | 
			
		||||
	case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
 | 
			
		||||
	case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`)
 | 
			
		||||
 | 
			
		||||
func resolve(tag string, in string) (rtag string, out interface{}) {
 | 
			
		||||
	if !resolvableTag(tag) {
 | 
			
		||||
		return tag, in
 | 
			
		||||
@@ -89,6 +92,19 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 | 
			
		||||
		switch tag {
 | 
			
		||||
		case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
 | 
			
		||||
			return
 | 
			
		||||
		case yaml_FLOAT_TAG:
 | 
			
		||||
			if rtag == yaml_INT_TAG {
 | 
			
		||||
				switch v := out.(type) {
 | 
			
		||||
				case int64:
 | 
			
		||||
					rtag = yaml_FLOAT_TAG
 | 
			
		||||
					out = float64(v)
 | 
			
		||||
					return
 | 
			
		||||
				case int:
 | 
			
		||||
					rtag = yaml_FLOAT_TAG
 | 
			
		||||
					out = float64(v)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
 | 
			
		||||
	}()
 | 
			
		||||
@@ -122,6 +138,15 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 | 
			
		||||
 | 
			
		||||
		case 'D', 'S':
 | 
			
		||||
			// Int, float, or timestamp.
 | 
			
		||||
			// Only try values as a timestamp if the value is unquoted or there's an explicit
 | 
			
		||||
			// !!timestamp tag.
 | 
			
		||||
			if tag == "" || tag == yaml_TIMESTAMP_TAG {
 | 
			
		||||
				t, ok := parseTimestamp(in)
 | 
			
		||||
				if ok {
 | 
			
		||||
					return yaml_TIMESTAMP_TAG, t
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			plain := strings.Replace(in, "_", "", -1)
 | 
			
		||||
			intv, err := strconv.ParseInt(plain, 0, 64)
 | 
			
		||||
			if err == nil {
 | 
			
		||||
@@ -135,9 +160,11 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				return yaml_INT_TAG, uintv
 | 
			
		||||
			}
 | 
			
		||||
			floatv, err := strconv.ParseFloat(plain, 64)
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				return yaml_FLOAT_TAG, floatv
 | 
			
		||||
			if yamlStyleFloat.MatchString(plain) {
 | 
			
		||||
				floatv, err := strconv.ParseFloat(plain, 64)
 | 
			
		||||
				if err == nil {
 | 
			
		||||
					return yaml_FLOAT_TAG, floatv
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if strings.HasPrefix(plain, "0b") {
 | 
			
		||||
				intv, err := strconv.ParseInt(plain[2:], 2, 64)
 | 
			
		||||
@@ -153,28 +180,20 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
 | 
			
		||||
					return yaml_INT_TAG, uintv
 | 
			
		||||
				}
 | 
			
		||||
			} else if strings.HasPrefix(plain, "-0b") {
 | 
			
		||||
				intv, err := strconv.ParseInt(plain[3:], 2, 64)
 | 
			
		||||
				intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
 | 
			
		||||
				if err == nil {
 | 
			
		||||
					if intv == int64(int(intv)) {
 | 
			
		||||
						return yaml_INT_TAG, -int(intv)
 | 
			
		||||
					if true || intv == int64(int(intv)) {
 | 
			
		||||
						return yaml_INT_TAG, int(intv)
 | 
			
		||||
					} else {
 | 
			
		||||
						return yaml_INT_TAG, -intv
 | 
			
		||||
						return yaml_INT_TAG, intv
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// XXX Handle timestamps here.
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if tag == yaml_BINARY_TAG {
 | 
			
		||||
		return yaml_BINARY_TAG, in
 | 
			
		||||
	}
 | 
			
		||||
	if utf8.ValidString(in) {
 | 
			
		||||
		return yaml_STR_TAG, in
 | 
			
		||||
	}
 | 
			
		||||
	return yaml_BINARY_TAG, encodeBase64(in)
 | 
			
		||||
	return yaml_STR_TAG, in
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// encodeBase64 encodes s as base64 that is broken up into multiple lines
 | 
			
		||||
@@ -201,3 +220,39 @@ func encodeBase64(s string) string {
 | 
			
		||||
	}
 | 
			
		||||
	return string(out[:k])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This is a subset of the formats allowed by the regular expression
 | 
			
		||||
// defined at http://yaml.org/type/timestamp.html.
 | 
			
		||||
var allowedTimestampFormats = []string{
 | 
			
		||||
	"2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
 | 
			
		||||
	"2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
 | 
			
		||||
	"2006-1-2 15:4:5.999999999",       // space separated with no time zone
 | 
			
		||||
	"2006-1-2",                        // date only
 | 
			
		||||
	// Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
 | 
			
		||||
	// from the set of examples.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseTimestamp parses s as a timestamp string and
 | 
			
		||||
// returns the timestamp and reports whether it succeeded.
 | 
			
		||||
// Timestamp formats are defined at http://yaml.org/type/timestamp.html
 | 
			
		||||
func parseTimestamp(s string) (time.Time, bool) {
 | 
			
		||||
	// TODO write code to check all the formats supported by
 | 
			
		||||
	// http://yaml.org/type/timestamp.html instead of using time.Parse.
 | 
			
		||||
 | 
			
		||||
	// Quick check: all date formats start with YYYY-.
 | 
			
		||||
	i := 0
 | 
			
		||||
	for ; i < len(s); i++ {
 | 
			
		||||
		if c := s[i]; c < '0' || c > '9' {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if i != 4 || i == len(s) || s[i] != '-' {
 | 
			
		||||
		return time.Time{}, false
 | 
			
		||||
	}
 | 
			
		||||
	for _, format := range allowedTimestampFormats {
 | 
			
		||||
		if t, err := time.Parse(format, s); err == nil {
 | 
			
		||||
			return t, true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return time.Time{}, false
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								vendor/gopkg.in/yaml.v2/scannerc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/gopkg.in/yaml.v2/scannerc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -9,7 +9,7 @@ import (
 | 
			
		||||
// ************
 | 
			
		||||
//
 | 
			
		||||
// The following notes assume that you are familiar with the YAML specification
 | 
			
		||||
// (http://yaml.org/spec/cvs/current.html).  We mostly follow it, although in
 | 
			
		||||
// (http://yaml.org/spec/1.2/spec.html).  We mostly follow it, although in
 | 
			
		||||
// some cases we are less restrictive that it requires.
 | 
			
		||||
//
 | 
			
		||||
// The process of transforming a YAML stream into a sequence of events is
 | 
			
		||||
@@ -611,7 +611,7 @@ func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, co
 | 
			
		||||
	if directive {
 | 
			
		||||
		context = "while parsing a %TAG directive"
 | 
			
		||||
	}
 | 
			
		||||
	return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
 | 
			
		||||
	return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func trace(args ...interface{}) func() {
 | 
			
		||||
@@ -871,12 +871,6 @@ func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
 | 
			
		||||
 | 
			
		||||
	required := parser.flow_level == 0 && parser.indent == parser.mark.column
 | 
			
		||||
 | 
			
		||||
	// A simple key is required only when it is the first token in the current
 | 
			
		||||
	// line.  Therefore it is always allowed.  But we add a check anyway.
 | 
			
		||||
	if required && !parser.simple_key_allowed {
 | 
			
		||||
		panic("should not happen")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// If the current position may start a simple key, save it.
 | 
			
		||||
	//
 | 
			
		||||
@@ -1944,7 +1938,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
 | 
			
		||||
	} else {
 | 
			
		||||
		// It's either the '!' tag or not really a tag handle.  If it's a %TAG
 | 
			
		||||
		// directive, it's an error.  If it's a tag token, it must be a part of URI.
 | 
			
		||||
		if directive && !(s[0] == '!' && s[1] == 0) {
 | 
			
		||||
		if directive && string(s) != "!" {
 | 
			
		||||
			yaml_parser_set_scanner_tag_error(parser, directive,
 | 
			
		||||
				start_mark, "did not find expected '!'")
 | 
			
		||||
			return false
 | 
			
		||||
@@ -1959,6 +1953,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
 | 
			
		||||
func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
 | 
			
		||||
	//size_t length = head ? strlen((char *)head) : 0
 | 
			
		||||
	var s []byte
 | 
			
		||||
	hasTag := len(head) > 0
 | 
			
		||||
 | 
			
		||||
	// Copy the head if needed.
 | 
			
		||||
	//
 | 
			
		||||
@@ -2000,10 +1995,10 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte
 | 
			
		||||
		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		hasTag = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check if the tag is non-empty.
 | 
			
		||||
	if len(s) == 0 {
 | 
			
		||||
	if !hasTag {
 | 
			
		||||
		yaml_parser_set_scanner_tag_error(parser, directive,
 | 
			
		||||
			start_mark, "did not find expected tag URI")
 | 
			
		||||
		return false
 | 
			
		||||
@@ -2474,6 +2469,10 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check if we are at the end of the scalar.
 | 
			
		||||
		if single {
 | 
			
		||||
			if parser.buffer[parser.buffer_pos] == '\'' {
 | 
			
		||||
@@ -2486,10 +2485,6 @@ func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, si
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Consume blank characters.
 | 
			
		||||
		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
 | 
			
		||||
			if is_blank(parser.buffer, parser.buffer_pos) {
 | 
			
		||||
				// Consume a space or a tab character.
 | 
			
		||||
@@ -2591,19 +2586,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
 | 
			
		||||
		// Consume non-blank characters.
 | 
			
		||||
		for !is_blankz(parser.buffer, parser.buffer_pos) {
 | 
			
		||||
 | 
			
		||||
			// Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13".
 | 
			
		||||
			if parser.flow_level > 0 &&
 | 
			
		||||
				parser.buffer[parser.buffer_pos] == ':' &&
 | 
			
		||||
				!is_blankz(parser.buffer, parser.buffer_pos+1) {
 | 
			
		||||
				yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
 | 
			
		||||
					start_mark, "found unexpected ':'")
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Check for indicators that may end a plain scalar.
 | 
			
		||||
			if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
 | 
			
		||||
				(parser.flow_level > 0 &&
 | 
			
		||||
					(parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' ||
 | 
			
		||||
					(parser.buffer[parser.buffer_pos] == ',' ||
 | 
			
		||||
						parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
 | 
			
		||||
						parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
 | 
			
		||||
						parser.buffer[parser.buffer_pos] == '}')) {
 | 
			
		||||
@@ -2655,10 +2641,10 @@ func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) b
 | 
			
		||||
		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
 | 
			
		||||
			if is_blank(parser.buffer, parser.buffer_pos) {
 | 
			
		||||
 | 
			
		||||
				// Check for tab character that abuse indentation.
 | 
			
		||||
				// Check for tab characters that abuse indentation.
 | 
			
		||||
				if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
 | 
			
		||||
					yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
 | 
			
		||||
						start_mark, "found a tab character that violate indentation")
 | 
			
		||||
						start_mark, "found a tab character that violates indentation")
 | 
			
		||||
					return false
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/gopkg.in/yaml.v2/sorter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/gopkg.in/yaml.v2/sorter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -51,6 +51,15 @@ func (l keyList) Less(i, j int) bool {
 | 
			
		||||
		}
 | 
			
		||||
		var ai, bi int
 | 
			
		||||
		var an, bn int64
 | 
			
		||||
		if ar[i] == '0' || br[i] == '0' {
 | 
			
		||||
			for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
 | 
			
		||||
				if ar[j] != '0' {
 | 
			
		||||
					an = 1
 | 
			
		||||
					bn = 1
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
 | 
			
		||||
			an = an*10 + int64(ar[ai]-'0')
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										65
									
								
								vendor/gopkg.in/yaml.v2/writerc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										65
									
								
								vendor/gopkg.in/yaml.v2/writerc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -18,72 +18,9 @@ func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If the output encoding is UTF-8, we don't need to recode the buffer.
 | 
			
		||||
	if emitter.encoding == yaml_UTF8_ENCODING {
 | 
			
		||||
		if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
 | 
			
		||||
			return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
 | 
			
		||||
		}
 | 
			
		||||
		emitter.buffer_pos = 0
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Recode the buffer into the raw buffer.
 | 
			
		||||
	var low, high int
 | 
			
		||||
	if emitter.encoding == yaml_UTF16LE_ENCODING {
 | 
			
		||||
		low, high = 0, 1
 | 
			
		||||
	} else {
 | 
			
		||||
		high, low = 1, 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pos := 0
 | 
			
		||||
	for pos < emitter.buffer_pos {
 | 
			
		||||
		// See the "reader.c" code for more details on UTF-8 encoding.  Note
 | 
			
		||||
		// that we assume that the buffer contains a valid UTF-8 sequence.
 | 
			
		||||
 | 
			
		||||
		// Read the next UTF-8 character.
 | 
			
		||||
		octet := emitter.buffer[pos]
 | 
			
		||||
 | 
			
		||||
		var w int
 | 
			
		||||
		var value rune
 | 
			
		||||
		switch {
 | 
			
		||||
		case octet&0x80 == 0x00:
 | 
			
		||||
			w, value = 1, rune(octet&0x7F)
 | 
			
		||||
		case octet&0xE0 == 0xC0:
 | 
			
		||||
			w, value = 2, rune(octet&0x1F)
 | 
			
		||||
		case octet&0xF0 == 0xE0:
 | 
			
		||||
			w, value = 3, rune(octet&0x0F)
 | 
			
		||||
		case octet&0xF8 == 0xF0:
 | 
			
		||||
			w, value = 4, rune(octet&0x07)
 | 
			
		||||
		}
 | 
			
		||||
		for k := 1; k < w; k++ {
 | 
			
		||||
			octet = emitter.buffer[pos+k]
 | 
			
		||||
			value = (value << 6) + (rune(octet) & 0x3F)
 | 
			
		||||
		}
 | 
			
		||||
		pos += w
 | 
			
		||||
 | 
			
		||||
		// Write the character.
 | 
			
		||||
		if value < 0x10000 {
 | 
			
		||||
			var b [2]byte
 | 
			
		||||
			b[high] = byte(value >> 8)
 | 
			
		||||
			b[low] = byte(value & 0xFF)
 | 
			
		||||
			emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
 | 
			
		||||
		} else {
 | 
			
		||||
			// Write the character using a surrogate pair (check "reader.c").
 | 
			
		||||
			var b [4]byte
 | 
			
		||||
			value -= 0x10000
 | 
			
		||||
			b[high] = byte(0xD8 + (value >> 18))
 | 
			
		||||
			b[low] = byte((value >> 10) & 0xFF)
 | 
			
		||||
			b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
 | 
			
		||||
			b[low+2] = byte(value & 0xFF)
 | 
			
		||||
			emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Write the raw buffer.
 | 
			
		||||
	if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
 | 
			
		||||
	if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
 | 
			
		||||
		return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	emitter.buffer_pos = 0
 | 
			
		||||
	emitter.raw_buffer = emitter.raw_buffer[:0]
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										136
									
								
								vendor/gopkg.in/yaml.v2/yaml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										136
									
								
								vendor/gopkg.in/yaml.v2/yaml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -9,6 +9,7 @@ package yaml
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
@@ -77,8 +78,65 @@ type Marshaler interface {
 | 
			
		||||
// supported tag options.
 | 
			
		||||
//
 | 
			
		||||
func Unmarshal(in []byte, out interface{}) (err error) {
 | 
			
		||||
	return unmarshal(in, out, false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalStrict is like Unmarshal except that any fields that are found
 | 
			
		||||
// in the data that do not have corresponding struct members, or mapping
 | 
			
		||||
// keys that are duplicates, will result in
 | 
			
		||||
// an error.
 | 
			
		||||
func UnmarshalStrict(in []byte, out interface{}) (err error) {
 | 
			
		||||
	return unmarshal(in, out, true)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A Decorder reads and decodes YAML values from an input stream.
 | 
			
		||||
type Decoder struct {
 | 
			
		||||
	strict bool
 | 
			
		||||
	parser *parser
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewDecoder returns a new decoder that reads from r.
 | 
			
		||||
//
 | 
			
		||||
// The decoder introduces its own buffering and may read
 | 
			
		||||
// data from r beyond the YAML values requested.
 | 
			
		||||
func NewDecoder(r io.Reader) *Decoder {
 | 
			
		||||
	return &Decoder{
 | 
			
		||||
		parser: newParserFromReader(r),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetStrict sets whether strict decoding behaviour is enabled when
 | 
			
		||||
// decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
 | 
			
		||||
func (dec *Decoder) SetStrict(strict bool) {
 | 
			
		||||
	dec.strict = strict
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Decode reads the next YAML-encoded value from its input
 | 
			
		||||
// and stores it in the value pointed to by v.
 | 
			
		||||
//
 | 
			
		||||
// See the documentation for Unmarshal for details about the
 | 
			
		||||
// conversion of YAML into a Go value.
 | 
			
		||||
func (dec *Decoder) Decode(v interface{}) (err error) {
 | 
			
		||||
	d := newDecoder(dec.strict)
 | 
			
		||||
	defer handleErr(&err)
 | 
			
		||||
	d := newDecoder()
 | 
			
		||||
	node := dec.parser.parse()
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return io.EOF
 | 
			
		||||
	}
 | 
			
		||||
	out := reflect.ValueOf(v)
 | 
			
		||||
	if out.Kind() == reflect.Ptr && !out.IsNil() {
 | 
			
		||||
		out = out.Elem()
 | 
			
		||||
	}
 | 
			
		||||
	d.unmarshal(node, out)
 | 
			
		||||
	if len(d.terrors) > 0 {
 | 
			
		||||
		return &TypeError{d.terrors}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func unmarshal(in []byte, out interface{}, strict bool) (err error) {
 | 
			
		||||
	defer handleErr(&err)
 | 
			
		||||
	d := newDecoder(strict)
 | 
			
		||||
	p := newParser(in)
 | 
			
		||||
	defer p.destroy()
 | 
			
		||||
	node := p.parse()
 | 
			
		||||
@@ -99,8 +157,8 @@ func Unmarshal(in []byte, out interface{}) (err error) {
 | 
			
		||||
// of the generated document will reflect the structure of the value itself.
 | 
			
		||||
// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
 | 
			
		||||
//
 | 
			
		||||
// Struct fields are only unmarshalled if they are exported (have an upper case
 | 
			
		||||
// first letter), and are unmarshalled using the field name lowercased as the
 | 
			
		||||
// Struct fields are only marshalled if they are exported (have an upper case
 | 
			
		||||
// first letter), and are marshalled using the field name lowercased as the
 | 
			
		||||
// default key. Custom keys may be defined via the "yaml" name in the field
 | 
			
		||||
// tag: the content preceding the first comma is used as the key, and the
 | 
			
		||||
// following comma-separated options are used to tweak the marshalling process.
 | 
			
		||||
@@ -114,7 +172,10 @@ func Unmarshal(in []byte, out interface{}) (err error) {
 | 
			
		||||
//
 | 
			
		||||
//     omitempty    Only include the field if it's not set to the zero
 | 
			
		||||
//                  value for the type or to empty slices or maps.
 | 
			
		||||
//                  Does not apply to zero valued structs.
 | 
			
		||||
//                  Zero valued structs will be omitted if all their public
 | 
			
		||||
//                  fields are zero, unless they implement an IsZero
 | 
			
		||||
//                  method (see the IsZeroer interface type), in which
 | 
			
		||||
//                  case the field will be included if that method returns true.
 | 
			
		||||
//
 | 
			
		||||
//     flow         Marshal using a flow style (useful for structs,
 | 
			
		||||
//                  sequences and maps).
 | 
			
		||||
@@ -129,7 +190,7 @@ func Unmarshal(in []byte, out interface{}) (err error) {
 | 
			
		||||
// For example:
 | 
			
		||||
//
 | 
			
		||||
//     type T struct {
 | 
			
		||||
//         F int "a,omitempty"
 | 
			
		||||
//         F int `yaml:"a,omitempty"`
 | 
			
		||||
//         B int
 | 
			
		||||
//     }
 | 
			
		||||
//     yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
 | 
			
		||||
@@ -139,12 +200,47 @@ func Marshal(in interface{}) (out []byte, err error) {
 | 
			
		||||
	defer handleErr(&err)
 | 
			
		||||
	e := newEncoder()
 | 
			
		||||
	defer e.destroy()
 | 
			
		||||
	e.marshal("", reflect.ValueOf(in))
 | 
			
		||||
	e.marshalDoc("", reflect.ValueOf(in))
 | 
			
		||||
	e.finish()
 | 
			
		||||
	out = e.out
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An Encoder writes YAML values to an output stream.
 | 
			
		||||
type Encoder struct {
 | 
			
		||||
	encoder *encoder
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewEncoder returns a new encoder that writes to w.
 | 
			
		||||
// The Encoder should be closed after use to flush all data
 | 
			
		||||
// to w.
 | 
			
		||||
func NewEncoder(w io.Writer) *Encoder {
 | 
			
		||||
	return &Encoder{
 | 
			
		||||
		encoder: newEncoderWithWriter(w),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Encode writes the YAML encoding of v to the stream.
 | 
			
		||||
// If multiple items are encoded to the stream, the
 | 
			
		||||
// second and subsequent document will be preceded
 | 
			
		||||
// with a "---" document separator, but the first will not.
 | 
			
		||||
//
 | 
			
		||||
// See the documentation for Marshal for details about the conversion of Go
 | 
			
		||||
// values to YAML.
 | 
			
		||||
func (e *Encoder) Encode(v interface{}) (err error) {
 | 
			
		||||
	defer handleErr(&err)
 | 
			
		||||
	e.encoder.marshalDoc("", reflect.ValueOf(v))
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close closes the encoder by writing any remaining data.
 | 
			
		||||
// It does not write a stream terminating string "...".
 | 
			
		||||
func (e *Encoder) Close() (err error) {
 | 
			
		||||
	defer handleErr(&err)
 | 
			
		||||
	e.encoder.finish()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleErr(err *error) {
 | 
			
		||||
	if v := recover(); v != nil {
 | 
			
		||||
		if e, ok := v.(yamlError); ok {
 | 
			
		||||
@@ -200,6 +296,9 @@ type fieldInfo struct {
 | 
			
		||||
	Num       int
 | 
			
		||||
	OmitEmpty bool
 | 
			
		||||
	Flow      bool
 | 
			
		||||
	// Id holds the unique field identifier, so we can cheaply
 | 
			
		||||
	// check for field duplicates without maintaining an extra map.
 | 
			
		||||
	Id int
 | 
			
		||||
 | 
			
		||||
	// Inline holds the field index if the field is part of an inlined struct.
 | 
			
		||||
	Inline []int
 | 
			
		||||
@@ -279,6 +378,7 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
 | 
			
		||||
					} else {
 | 
			
		||||
						finfo.Inline = append([]int{i}, finfo.Inline...)
 | 
			
		||||
					}
 | 
			
		||||
					finfo.Id = len(fieldsList)
 | 
			
		||||
					fieldsMap[finfo.Key] = finfo
 | 
			
		||||
					fieldsList = append(fieldsList, finfo)
 | 
			
		||||
				}
 | 
			
		||||
@@ -300,11 +400,16 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
 | 
			
		||||
			return nil, errors.New(msg)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		info.Id = len(fieldsList)
 | 
			
		||||
		fieldsList = append(fieldsList, info)
 | 
			
		||||
		fieldsMap[info.Key] = info
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
 | 
			
		||||
	sinfo = &structInfo{
 | 
			
		||||
		FieldsMap:  fieldsMap,
 | 
			
		||||
		FieldsList: fieldsList,
 | 
			
		||||
		InlineMap:  inlineMap,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fieldMapMutex.Lock()
 | 
			
		||||
	structMap[st] = sinfo
 | 
			
		||||
@@ -312,8 +417,23 @@ func getStructInfo(st reflect.Type) (*structInfo, error) {
 | 
			
		||||
	return sinfo, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsZeroer is used to check whether an object is zero to
 | 
			
		||||
// determine whether it should be omitted when marshaling
 | 
			
		||||
// with the omitempty flag. One notable implementation
 | 
			
		||||
// is time.Time.
 | 
			
		||||
type IsZeroer interface {
 | 
			
		||||
	IsZero() bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isZero(v reflect.Value) bool {
 | 
			
		||||
	switch v.Kind() {
 | 
			
		||||
	kind := v.Kind()
 | 
			
		||||
	if z, ok := v.Interface().(IsZeroer); ok {
 | 
			
		||||
		if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
		return z.IsZero()
 | 
			
		||||
	}
 | 
			
		||||
	switch kind {
 | 
			
		||||
	case reflect.String:
 | 
			
		||||
		return len(v.String()) == 0
 | 
			
		||||
	case reflect.Interface, reflect.Ptr:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								vendor/gopkg.in/yaml.v2/yamlh.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/gopkg.in/yaml.v2/yamlh.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +1,7 @@
 | 
			
		||||
package yaml
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -239,6 +240,27 @@ const (
 | 
			
		||||
	yaml_MAPPING_END_EVENT    // A MAPPING-END event.
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var eventStrings = []string{
 | 
			
		||||
	yaml_NO_EVENT:             "none",
 | 
			
		||||
	yaml_STREAM_START_EVENT:   "stream start",
 | 
			
		||||
	yaml_STREAM_END_EVENT:     "stream end",
 | 
			
		||||
	yaml_DOCUMENT_START_EVENT: "document start",
 | 
			
		||||
	yaml_DOCUMENT_END_EVENT:   "document end",
 | 
			
		||||
	yaml_ALIAS_EVENT:          "alias",
 | 
			
		||||
	yaml_SCALAR_EVENT:         "scalar",
 | 
			
		||||
	yaml_SEQUENCE_START_EVENT: "sequence start",
 | 
			
		||||
	yaml_SEQUENCE_END_EVENT:   "sequence end",
 | 
			
		||||
	yaml_MAPPING_START_EVENT:  "mapping start",
 | 
			
		||||
	yaml_MAPPING_END_EVENT:    "mapping end",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e yaml_event_type_t) String() string {
 | 
			
		||||
	if e < 0 || int(e) >= len(eventStrings) {
 | 
			
		||||
		return fmt.Sprintf("unknown event %d", e)
 | 
			
		||||
	}
 | 
			
		||||
	return eventStrings[e]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The event structure.
 | 
			
		||||
type yaml_event_t struct {
 | 
			
		||||
 | 
			
		||||
@@ -508,7 +530,7 @@ type yaml_parser_t struct {
 | 
			
		||||
 | 
			
		||||
	problem string // Error description.
 | 
			
		||||
 | 
			
		||||
	// The byte about which the problem occured.
 | 
			
		||||
	// The byte about which the problem occurred.
 | 
			
		||||
	problem_offset int
 | 
			
		||||
	problem_value  int
 | 
			
		||||
	problem_mark   yaml_mark_t
 | 
			
		||||
@@ -521,9 +543,9 @@ type yaml_parser_t struct {
 | 
			
		||||
 | 
			
		||||
	read_handler yaml_read_handler_t // Read handler.
 | 
			
		||||
 | 
			
		||||
	input_file io.Reader // File input data.
 | 
			
		||||
	input      []byte    // String input data.
 | 
			
		||||
	input_pos  int
 | 
			
		||||
	input_reader io.Reader // File input data.
 | 
			
		||||
	input        []byte    // String input data.
 | 
			
		||||
	input_pos    int
 | 
			
		||||
 | 
			
		||||
	eof bool // EOF flag
 | 
			
		||||
 | 
			
		||||
@@ -632,7 +654,7 @@ type yaml_emitter_t struct {
 | 
			
		||||
	write_handler yaml_write_handler_t // Write handler.
 | 
			
		||||
 | 
			
		||||
	output_buffer *[]byte   // String output data.
 | 
			
		||||
	output_file   io.Writer // File output data.
 | 
			
		||||
	output_writer io.Writer // File output data.
 | 
			
		||||
 | 
			
		||||
	buffer     []byte // The working buffer.
 | 
			
		||||
	buffer_pos int    // The current position of the buffer.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user