Compare commits

...

153 Commits

Author SHA1 Message Date
Mark Bates 0273362499
Merge pull request #102 from requaos/requaos/gzip
Remove hepa library for revision at a later date
2020-08-12 13:53:52 -04:00
Neil Skinner c78e87acb0 Updating documentation to reflect the paths generated without the hepa library 2020-06-10 09:31:24 -04:00
Neil Skinner 143afe6a94 remove post-processing library hepa; pending revision 2020-06-09 10:09:43 -04:00
Mark Bates 992ea93a2a
Merge pull request #97 from qmuntal/master
Support const paths
2020-06-03 14:03:53 -04:00
Mark Bates d84a13e7c2
Merge pull request #101 from requaos/requaos/gzip
Apply hepa filters before gzip'ing content
2020-06-03 14:03:12 -04:00
Neil Skinner fdcec3a4ea Apply hepa filters before gzip'ing content
- markbates/pkger#26
2020-06-03 12:46:06 -04:00
Quim Muntal Diaz c7908c9bfc support const expressions 2020-05-21 17:19:19 +02:00
Mark Bates d97c60c346
Merge pull request #93 from xDuck/master
Fixes high cache miss rate, significant performance increase.
2020-05-15 17:09:09 -04:00
xDuck efed726c9e Fixes high cache miss rate, significant performance increase. Closes #92 2020-05-15 15:34:27 -04:00
Mark Bates c028e66556
Merge pull request #82 from xDuck/master
Add conditional build tag to generated files
2020-04-03 10:58:08 -04:00
Mark Bates 8554e69817
Merge pull request #83 from Bios-Marcel/patch-1
Fix a small typo
2020-04-03 10:57:47 -04:00
Marcel Schramm b4563ccbec
Fix a small typo 2020-03-27 20:01:47 +01:00
Chris 3c88c54d65
Removed optional tags with one tag, !skippkger 2020-03-24 14:14:21 -04:00
Chris 331c57067b
Moved build tags below code generation warning 2020-03-24 14:02:20 -04:00
Chris bc0ae93dc6
Added -t for specifying conditional build tags 2020-03-24 13:51:10 -04:00
Mark Bates a78c11e368
Merge pull request #80 from taiyangc/master
Fix pkger generating the wrong package name for pkger.go
2020-03-11 14:37:04 -04:00
Eric Chen 9552dcf46d Fix pkger generating the wrong package name for pkger.go
The issue is that, if pkger.go is created (empty) before the `go list
-json` call it will fail and give the generic directory name instead of the
actual package name under the directory. This is fine in most cases,
except when the package name differs from the directory name - which is
allowed. Then pkger.go will conflict and fail to compile with the rest
of *.go under the same directory.

To fix, we simply obtain the real package name before creating the dummy
pkger.go file and then pass the name into the file.
2020-03-11 03:31:03 -07:00
Mark Bates 5b8abbabca
Merge pull request #77 from ghouscht/issue-76
fix pkger error if a project contains a .go directory #76
2020-03-04 09:55:04 -05:00
Thomas Gosteli 5d81ba66cb fix pkger error if a project contains a .go directory #76 2020-03-04 14:33:57 +01:00
Mark Bates c9b56cd758
Merge pull request #70 from hnnsgstfssn/fix-typo
Fix typo
2020-02-17 16:29:53 -05:00
Hannes Gustafsson 9925b6cc05 Fix typo
4e1fe7b43f introduced a Fprintf call that
passes a variable without a formatting directive. This will cause go vet
-printf to fail with

    cmd/pkger/cmds/pack.go:150: no formatting directive in Fprintf call

Drop the variable from the call.
2020-02-16 22:05:56 +00:00
Mark Bates defb2921c0
Merge pull request #69 from hnnsgstfssn/add-generated-code-disclaimer
Add generated code disclaimer
2020-02-16 15:13:34 -05:00
Hannes Gustafsson 4e1fe7b43f Add generated code disclaimer
Generated code should contain a disclaimer as per [1].

Add a disclaimer to the top of the file generated by the pack command.

Fixes #68.

[1] https://golang.org/s/generatedcode
2020-02-16 19:54:06 +00:00
Mark Bates d9d5139985
Merge pull request #61 from markbates/fix-external-pkgs
Fixes issues with `<pkg>:/<name>` paths not resolving correctly.
2020-01-09 15:48:40 -05:00
Mark Bates 4a3675581d use pkg info from string parse 2020-01-08 17:37:55 -05:00
Mark Bates c5e820d039
Merge pull request #50 from markbates/here-here
use gobuffalo/here fixes #49
2019-12-17 10:19:58 -05:00
Mark Bates db2f21a8c7 see yourself 2019-12-17 10:16:55 -05:00
Mark Bates 7a3189e727 Merge branch 'master' into here-here 2019-12-17 10:12:20 -05:00
Mark Bates 6217c988eb
Merge pull request #55 from moqmar/master
Provide workaround for segmentation fault (fixes #54)
2019-12-17 10:08:08 -05:00
Moritz Marquardt 2a4daae578
Provide workaround for segmentation fault (fixes #54) 2019-12-16 09:09:58 +01:00
Mark Bates 6c1b23a5cb new include 2019-12-13 11:24:17 -05:00
Mark Bates 5497054b42
Merge pull request #53 from markbates/handle-main
handle main packages
2019-12-11 15:15:54 -05:00
Mark Bates 945a3a2811
Merge branch 'master' into handle-main 2019-12-11 15:04:01 -05:00
Mark Bates b334bd73ac handle main functions 2019-12-11 15:02:51 -05:00
Mark Bates b0a67f7917
Merge pull request #52 from koddr/patch-1
Fixed import block (generated pkged.go file)
2019-12-11 15:02:41 -05:00
Vic Shóstak 9d57b03b3c
Fixed import block 2019-12-05 22:09:34 +03:00
Mark Bates 6431634511 better error 2019-12-03 17:40:04 -05:00
Mark Bates 0167919fce ignore .tmp stuff 2019-12-03 17:36:58 -05:00
Mark Bates e4d652a24e revert 2019-12-03 15:32:08 -05:00
Mark Bates ec8c803b27 verbs 2019-12-03 15:29:17 -05:00
Mark Bates b24faf1070 get -t 2019-12-03 15:23:12 -05:00
Mark Bates 94798bc8a6 remove 1.12 2019-12-03 15:13:55 -05:00
Mark Bates 10f43292e9 github stuff 2019-12-03 15:11:25 -05:00
Mark Bates 16972f8f18 use gobuffalo/here fixes #49 2019-12-03 15:07:51 -05:00
Mark Bates 7752bb822e magic prize 2019-11-21 11:42:19 -05:00
Mark Bates 43a11bf0fc fix goreleaser 2019-11-21 11:35:54 -05:00
Mark Bates d6ca5ac119
Merge pull request #41 from markbates/github-actions 2019-11-21 08:33:32 -08:00
Mark Bates 32f1de1b25 the ship is leaking 2019-11-21 11:31:06 -05:00
Mark Bates 2560bdca09 in the sun 2019-11-21 11:29:00 -05:00
Mark Bates ddc055cac4 tidy 2019-11-21 09:02:05 -05:00
Mark Bates e611253b7b dop 2019-11-21 08:53:05 -05:00
Mark Bates 0b8a69abe2 why? 2019-11-21 08:07:00 -05:00
Mark Bates b40b98d739 do you? 2019-11-20 22:02:20 -05:00
Mark Bates c83687a932 copy sum too 2019-11-20 21:58:48 -05:00
Mark Bates 8f84b7462f sum 2019-11-20 21:54:48 -05:00
Mark Bates 9b9b72922d the killing curse 2019-11-20 21:50:35 -05:00
Mark Bates f548238cc7
Merge pull request #40 from devnode/fix-file-seek
missing File.reader initialization on Seek()
2019-11-20 18:43:18 -08:00
Tom Mombourquette 5d492d737f removed io package for consistency 2019-11-20 21:48:09 -04:00
Tom Mombourquette b8247ce972 added test 2019-11-20 19:17:36 -04:00
Tom Mombourquette d9ef17a04d initial 2019-11-20 16:36:29 -04:00
Mark Bates 3f76ab6dd9 version bump: v0.12.5 2019-11-20 05:50:48 -08:00
Mark Bates 338906395e version bump: v0.12.4 2019-11-17 10:10:11 -08:00
Mark Bates 9ca6c03d94 version bump: v0.12.3 2019-11-14 11:51:18 -05:00
Mark Bates 6089e09d37
Merge pull request #35 from markbates/fix-no-go-err
`go list` need at least one `.go` file in the root of the project fixes #34
2019-11-14 08:50:27 -08:00
Mark Bates 0c7e018c10 `go list` need at least one `.go` file in the root of the project fixes #34 2019-11-13 17:29:41 -05:00
Mark Bates 7a5b071f5b version bump: v0.12.2 2019-11-11 18:21:41 -05:00
Mark Bates b4c1e6e713
Merge pull request #31 from markbates/rocks-my-soul
drag it up
2019-11-11 15:21:17 -08:00
Mark Bates 1e03febf38 drag it up 2019-11-11 18:17:26 -05:00
Mark Bates d14ce58f35 version bump: v0.12.1 2019-11-11 17:56:13 -05:00
Mark Bates f25d3ebfe9
Merge pull request #30 from nlepage/fix/out_pkged
fix embed not working with -o
2019-11-11 14:55:39 -08:00
Mark Bates 7067fa6132 docs 2019-11-11 17:45:39 -05:00
Nicolas Lepage b97aa787b5
fix embed not working with -o 2019-11-11 23:34:17 +01:00
Mark Bates c69a63df8d version bump: v0.12.0 2019-11-11 17:27:36 -05:00
Mark Bates e6edc3713b
Merge pull request #29 from markbates/minotaur
Adds -include flag and pkger.Include directive fixes #28
2019-11-11 14:26:35 -08:00
Mark Bates b3c81b5fd3 docs 2019-11-11 17:21:59 -05:00
Mark Bates 8879dba851 remove out file if packing panics 2019-11-11 16:46:12 -05:00
Mark Bates 7ee0500044 Adds -include flag and pkger.Include directive fixes #28 2019-11-11 16:01:05 -05:00
Mark Bates 1a3cb0f04d update README.md 2019-11-10 18:59:20 -05:00
Mark Bates d90c068476 version bump: v0.11.0 2019-11-10 18:50:09 -05:00
Mark Bates 834898d6b5
Merge pull request #25 from markbates/out-flag
add -o flag
2019-11-10 15:49:12 -08:00
Mark Bates 5c0596fcb6
Merge branch 'master' into out-flag 2019-11-10 15:44:45 -08:00
Mark Bates 9da9f00821 add -o flag 2019-11-10 18:43:12 -05:00
Mark Bates 342e00a7be
Merge pull request #24 from markbates/aperezg-22_detect_gomod_no_pkg
Error when a directory contains no `.go` or `go.mod` files fixes #22
2019-11-10 15:42:52 -08:00
Mark Bates ac15f56d3f match error for nonGoDirRx 2019-11-10 18:38:44 -05:00
Mark Bates 794943f042 now with less printlns and more tests 2019-11-10 18:27:57 -05:00
Mark Bates 812232aaff improve error testing for non go directories.
also cleans up there here.Info api
2019-11-10 18:22:06 -05:00
Mark Bates 2a9f9649bb stabilize tests 2019-11-10 17:22:01 -05:00
Mark Bates b4f921bd19 reset the testdata/ref app 2019-11-10 17:09:54 -05:00
Mark Bates 37ad5dad0f Revert "remove accidental testdata"
This reverts commit 93cf940d5a.
2019-11-10 17:09:08 -05:00
Mark Bates 93cf940d5a remove accidental testdata 2019-11-10 17:06:28 -05:00
aperezg e8ea7c2ce8 modify test stuff to cover the case for isolated go.mod 2019-11-10 14:11:07 +01:00
aperezg 6a21c5378b remove ImportPath from NewInfoFromPath 2019-11-10 11:56:09 +01:00
aperezg 71d20943f0 check if there a go.mod in a directory without any go files 2019-11-09 20:43:22 +01:00
aperezg 6cf141c51a remove unnecessary conversion 2019-11-09 20:26:33 +01:00
Mark Bates 2a3000b896 version bump: v0.10.1 2019-11-08 11:21:34 -08:00
Mark Bates 5e527e6ae5
Merge pull request #20 from markbates/pkger-hangs
pkger hangs fixes #19
2019-11-08 11:21:09 -08:00
Mark Bates 632f108343 ignore .C errors 2019-11-08 11:07:33 -08:00
Mark Bates ac960d47a9 pkger hangs fixes #19 2019-11-08 11:05:03 -08:00
Mark Bates 9a9d8d6275
Update README.md 2019-11-05 15:22:08 -05:00
Mark Bates 992448a71b
Update README.md 2019-11-05 15:21:12 -05:00
Mark Bates a04b1791e4 version bump: v0.10.0 2019-11-05 15:16:50 -05:00
Mark Bates 08fb31c710
Merge pull request #17 from markbates/declan-macmanus
skip ignoreable directories
2019-11-05 15:16:12 -05:00
Mark Bates 889d184af7 prime the mod cache 2019-11-05 15:09:28 -05:00
Mark Bates e7599507eb giggling crew 2019-11-05 15:04:38 -05:00
Mark Bates 5a8d085fb8 long lost 2019-11-05 11:55:53 -05:00
Mark Bates d96dfd3e37 always be tidying 2019-11-05 11:52:13 -05:00
Mark Bates 9ef79c78e8 test for external module 2019-11-05 11:44:15 -05:00
Mark Bates 20292c885b skip ignoreable directories 2019-11-04 11:48:06 -05:00
Mark Bates 3cbd07f98b fix stat example 2019-11-01 16:22:08 -04:00
Mark Bates 9473092e41 version bump: v0.9.0 2019-11-01 16:12:39 -04:00
Mark Bates afce25df00
Merge pull request #16 from markbates/elvis
Elvis
2019-11-01 16:12:18 -04:00
Mark Bates 1fa89d0323 Digging the "Dancing Queen" 2019-11-01 16:08:10 -04:00
Mark Bates 93d467fbde You were a spoilt child then with a record to plug 2019-11-01 16:04:37 -04:00
Mark Bates 952d962d54 Imploring: "Another melody?" 2019-11-01 16:00:30 -04:00
Mark Bates c191846c48 You gave me this tattoo back in '82 2019-11-01 15:53:54 -04:00
Mark Bates cc6861871c better tests 2019-10-31 17:20:15 -04:00
Mark Bates d41fe52ef2 a self-made mug is hard to break 2019-10-31 11:12:18 -04:00
Mark Bates 5c07a3dede it's not your punch then it's your pout 2019-10-31 11:06:20 -04:00
Mark Bates 6638215c4d where is the harmony? 2019-10-30 17:32:47 -04:00
Mark Bates 296799efbc even though I've seen the movie 2019-10-30 17:15:49 -04:00
Mark Bates b9ac82f558 always fascinated by the weird edge of town 2019-10-30 16:56:22 -04:00
Mark Bates f79eafd257 his suntan lotion and his castanets 2019-10-30 16:49:55 -04:00
Mark Bates da03471d96 juliet was waiting with a safety net 2019-10-30 16:39:05 -04:00
Mark Bates 0edd9cf5cc please don't stick me on the late shift 2019-10-30 13:05:35 -04:00
Mark Bates 4481d6120d 13 steps lead down 2019-10-30 11:31:39 -04:00
Mark Bates 13275eea7b Close-up of the sign that says,"We never close" 2019-10-25 17:11:34 -04:00
Mark Bates 77f832ce9e version bump: v0.8.1 2019-10-25 15:30:59 -04:00
Mark Bates 49b57cab14 you remind me of everyone 2019-10-25 15:30:12 -04:00
Mark Bates c84d74f6cf version bump: v0.8.0 2019-10-25 11:42:16 -04:00
Mark Bates 5e795946c5
Merge pull request #15 from markbates/marshal-mathers
do run run
2019-10-25 11:41:54 -04:00
Mark Bates 86547c5019 do run run 2019-10-25 10:19:27 -04:00
Mark Bates 27560b91c3 version bump: v0.7.0 2019-10-25 09:35:05 -04:00
Mark Bates 09ed2c28b7
Merge pull request #14 from markbates/comply
to bring you my love
2019-10-25 09:34:38 -04:00
Mark Bates a1787a9901 the wheel 2019-10-25 09:30:31 -04:00
Mark Bates 1154513c57 to bring you my love 2019-10-24 16:22:15 -04:00
Mark Bates 545b970a33 Merge branch 'master' of https://github.com/markbates/pkger 2019-10-23 14:41:48 -04:00
Mark Bates 5365ef92e1 version bump: v0.6.0 2019-10-23 13:26:50 -04:00
Mark Bates 0cc509fd30
Merge pull request #13 from markbates/mkdir-parse
hot hot hot
2019-10-23 13:26:32 -04:00
Mark Bates d9ff2b27b7 the love cats 2019-10-23 13:23:02 -04:00
Mark Bates 885aee89ac hot hot hot 2019-10-23 13:19:39 -04:00
Mark Bates e604be5ebe version bump: v0.5.1 2019-10-23 12:37:22 -04:00
Mark Bates 3c3f8e5c51
Merge pull request #11 from markbates/http
to see you eat in the middle of the night
2019-10-23 12:36:58 -04:00
Mark Bates 5ea9c95193 to see you eat in the middle of the night 2019-10-22 16:01:37 -04:00
Mark Bates 9fdb75a0a4 version bump: v0.5.0 2019-10-22 15:31:57 -04:00
Mark Bates 31b7fea8b6 she's made arrangements for me in the sand 2019-10-22 15:30:56 -04:00
Mark Bates c04004f152 version bump: v0.4.0 2019-10-22 14:51:15 -04:00
Mark Bates da5e6120c4 sometimes it happens 2019-10-22 14:50:48 -04:00
Mark Bates 80292eb459 version bump: v0.3.3 2019-10-22 13:40:22 -04:00
Mark Bates 48c2362aa8 if i had a mountain 2019-10-22 13:40:06 -04:00
Mark Bates 9a2162e1a0 version bump: v0.3.2 2019-10-22 13:29:08 -04:00
Mark Bates 3c88088905 version bump: v0.3.1 2019-10-22 13:26:08 -04:00
Mark Bates a09d2070cd version bump: v0.3.0 2019-10-22 10:06:30 -04:00
Mark Bates 522c2c06bd
Merge pull request #9 from markbates/new-years-resolution
until i see the light
2019-10-22 10:05:53 -04:00
179 changed files with 4622 additions and 9340 deletions

4
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,4 @@
# These are supported funding model platforms
github: markbates
patreon: buffalo

28
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: Release
on:
release:
types:
- published
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
-
name: Set up Go 1.13
uses: actions/setup-go@v1
with:
go-version: 1.13
id: go
-
name: Checkout Code
uses: actions/checkout@master
-
name: Run GoReleaser
env:
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
uses: goreleaser/goreleaser-action@v1
with:
version: latest
args: release --rm-dist

25
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: Tests
on: [push]
jobs:
tests:
name: ${{matrix.os}} Tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
steps:
- name: Set up Go 1.13
uses: actions/setup-go@v1
with:
go-version: 1.13
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v1
- name: Test
run: |
go mod download
go mod tidy -v
go test -race ./...

View File

@ -1,33 +1,45 @@
# Code generated by github.com/gobuffalo/release. DO NOT EDIT.
# Edit .goreleaser.yml.plush instead
builds:
-
goos:
- darwin
- linux
- windows
env:
- CGO_ENABLED=0
main: ./cmd/pkger/main.go
-
main: ./cmd/pkger/main.go
env:
- CGO_ENABLED=0
ldflags:
- -s -w -X "github.com/markbates/pkger.Version={{.Tag}}"
goos:
- darwin
- linux
- windows
goarch:
- amd64
- 386
- arm
- arm64
goarm:
- 6
- 7
archives:
-
replacements:
'386': i386
darwin: Darwin
linux: Linux
windows: Windows
amd64: x86_64
checksum:
name_template: 'checksums.txt'
name_template: checksums.txt
snapshot:
name_template: "{{ .Tag }}-next"
name_template: '{{ .Tag }}-next'
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
brews:
-
name: pkger
github:
owner: markbates
name: homebrew-tap
-
name: 'pkger'
github:
owner: 'markbates'
name: 'homebrew-tap'
install: |
bin.install "pkger"

View File

@ -1,30 +0,0 @@
builds:
-
goos:
- darwin
- linux
- windows
env:
- CGO_ENABLED=0
main: ./cmd/pkger/main.go
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
<%= if (brew) { %>
brews:
-
name: pkger
github:
owner: markbates
name: homebrew-tap
<% } %>

View File

@ -17,7 +17,7 @@ build: tidy
make tidy
test: tidy
$(GO_BIN) test -cover -tags ${TAGS} -timeout 5s ./...
$(GO_BIN) test -count 1 -cover -tags ${TAGS} -timeout 1m ./...
make tidy
cov:

398
README.md
View File

@ -2,7 +2,12 @@
[`github.com/markbates/pkger`](https://godoc.org/github.com/markbates/pkger) is a tool for embedding static files into Go binaries. It will, hopefully, be a replacement for [`github.com/gobuffalo/packr/v2`](https://godoc.org/github.com/gobuffalo/packr/v2).
## How it Works
### Requirements
* Go 1.13+
* Go Modules
## How it Works (Module Aware Pathing)
Pkger is powered by the dark magic of Go Modules, so they're like, totally required.
@ -19,22 +24,146 @@ Paths:
* Packages can specified in at the beginning of a path with a `:` seperator.
github.com/markbates/pkger:/cmd/pkger/main.go
* There are no relative paths. All paths are absolute to the modules root.
* Fully-qualified paths are embedded into the metadata of your static assets. If this behavior is undesirable, a preference is to build in a containerized environ, like docker, where the path strings are not ex-filtrating data about your development environment.
```
"github.com/gobuffalo/buffalo:/go.mod" => $GOPATH/pkg/mod/github.com/gobuffalo/buffalo@v0.14.7/go.mod
"github.com/gobuffalo/buffalo:/go.mod" => /go/pkg/mod/github.com/gobuffalo/buffalo@v0.14.7/go.mod
```
## Usage
## CLI
### Installation
```bash
$ go get github.com/markbates/pkger/cmd/pkger
$ pkger -h
```
### Usage
```bash
$ pkger
```
The result will be a `pkged.go` file in the **root** of the module with the embedded information and the package name of the module.
```go
// ./pkged.go
package <.>
// Pkger stuff here
```
The `-o` flag can be used to specify the directory of the `pkged.go` file.
```bash
$ pkger -o cmd/reader
```
The result will be a `pkged.go` file in the **cmd/reader** folder with the embedded information and the package name of that folder.
```go
// cmd/reader/pkged.go
package <reader>
// Pkger stuff here
```
### Including Files at Package Time
There may be reasons where you don't reference a particular file, or folder, that you want embedded in your application, such as a build artifact.
To do this you may use either the [`github.com/markbates/pkger#Include`](https://godoc.org/github.com/markbates/pkger#Include) function to set a no-op parser directive to include the specified path.
Alternatively, you may use the `-include` flag with the `pkger` and `pkger list` commands.
```bash
$ pkger list -include /actions -include github.com/gobuffalo/buffalo:/app.go
app
> app:/actions
> app:/actions/actions.go
> app:/assets
> app:/assets/css
> app:/assets/css/_buffalo.scss
> app:/assets/css/application.scss
> app:/assets/images
> app:/assets/images/favicon.ico
> app:/assets/images/logo.svg
> app:/assets/js
> app:/assets/js/application.js
> app:/go.mod
> app:/locales/all.en-us.yaml
> app:/public
> app:/public/assets
> app:/public/assets/.keep
> app:/public/assets/app.css
> app:/public/images
> app:/public/images/img1.png
> app:/public/index.html
> app:/public/robots.txt
> app:/templates
> app:/templates/_flash.plush.html
> app:/templates/application.plush.html
> app:/templates/index.plush.html
> app:/web
> app:/web/web.go
> github.com/gobuffalo/buffalo:/app.go
> github.com/gobuffalo/buffalo:/logo.svg
```
## Reference Application
The reference application for the `README` examples, as well as all testing, can be found at [https://github.com/markbates/pkger/tree/master/pkging/pkgtest/testdata/ref](https://github.com/markbates/pkger/tree/master/pkging/pkgtest/testdata/ref).
```
├── actions
│   └── actions.go
├── assets
│   ├── css
│   │   ├── _buffalo.scss
│   │   └── application.scss
│   ├── images
│   │   ├── favicon.ico
│   │   └── logo.svg
│   └── js
│   └── application.js
├── go.mod
├── go.sum
├── locales
│   └── all.en-us.yaml
├── main.go
├── mod
│   └── mod.go
├── models
│   └── models.go
├── public
│   ├── assets
│   │   └── app.css
│   ├── images
│   │   └── img1.png
│   ├── index.html
│   └── robots.txt
├── templates
│   ├── _flash.plush.html
│   ├── application.plush.html
│   └── index.plush.html
└── web
└── web.go
13 directories, 20 files
```
## API Usage
Pkger's API is modeled on that of the [`os`](https://godoc.org/os) package in Go's standard library. This makes Pkger usage familiar to Go developers.
The two most important interfaces are [`github.com/markbates/pkger/pkging#Pkger`](https://godoc.org/github.com/markbates/pkger/pkging#Pkger) and [`github.com/markbates/pkger/pkging#File`](https://godoc.org/github.com/markbates/pkger/pkging#File).
```go
type Pkger interface {
Parse(p string) (Path, error)
Abs(p string) (string, error)
AbsPath(Path) (string, error)
Current() (here.Info, error)
Info(p string) (here.Info, error)
Create(name string) (File, error)
@ -48,7 +177,6 @@ type Pkger interface {
type File interface {
Close() error
Abs() (string, error)
Info() here.Info
Name() string
Open(name string) (http.File, error)
@ -61,38 +189,56 @@ type File interface {
}
```
```bash
├── go.mod
├── go.sum
├── main.go
├── public
│   ├── images
│   │   ├── mark-small.png
│   │   ├── img1.png
│   │   ├── mark_250px.png
│   │   └── mark_400px.png
│   └── index.html
```
These two interfaces, along with the [`os#FileInfo`](https://godoc.org/os#FileInfo), provide the bulk of the API surface area.
### Open
```go
package main
import (
"fmt"
"log"
"os"
"text/tabwriter"
"time"
"github.com/markbates/pkger"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
func run() error {
f, err := pkger.Open("/public/index.html")
if err != nil {
return err
}
}
defer f.Close()
info, err := f.Stat()
if err != nil {
return err
}
fmt.Println("Name: ", info.Name())
fmt.Println("Size: ", info.Size())
fmt.Println("Mode: ", info.Mode())
fmt.Println("ModTime: ", info.ModTime())
if _, err := io.Copy(os.Stdout, f); err != nil {
return err
}
return nil
}
```
### Stat
```go
func run() error {
info, err := pkger.Stat("/public/index.html")
if err != nil {
return err
}
fmt.Println("Name: ", info.Name())
fmt.Println("Size: ", info.Size())
fmt.Println("Mode: ", info.Mode())
fmt.Println("ModTime: ", info.ModTime())
return nil
}
```
### Walk
```go
func run() error {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 0, ' ', tabwriter.Debug)
defer w.Flush()
@ -116,33 +262,171 @@ func run() error {
}
```
### Output Without Packing
## Understanding the Parser
The [`github.com/markbates/pkger/parser#Parser`](https://godoc.org/github.com/markbates/pkger/parser#Parser) works by statically analyzing the source code of your module using the [`go/parser`](https://godoc.org/go/parser) to find a selection of declarations.
The following declarations in your source code will tell the parser to embed files or folders.
* `pkger.Dir("<path>")` - Embeds all files under the specified path.
* `pkger.Open("<path>")` - Embeds the file, or folder, of the specified path.
* `pkger.Stat("<path>")` - Embeds the file, or folder, of the specified path.
* `pkger.Walk("<path>", filepath.WalkFunc)` - Embeds all files under the specified path.
* `pkger.Include("<path>")` - `Include` is a no-op that directs the pkger tool to include the desired file or folder.
### CLI Usage
To see what declarations the parser has found, you can use the `pkger parse` command to get a `JSON` list of the declarations.
```bash
# compile the go binary as usual and run the app:
$ go build -v; ./app
/public | 128 | drwxr-xr-x | 2019-10-17T15:02:57-04:00 |
/public/images | 192 | drwxr-xr-x | 2019-10-17T15:02:57-04:00 |
/public/images/mark-small.png | 649549 | -rw-r--r-- | 2019-10-17T15:02:56-04:00 |
/public/images/img1.png | 50401191 | -rw-r--r-- | 2019-10-17T15:02:57-04:00 |
/public/images/mark_250px.png | 27718 | -rw-r--r-- | 2019-10-17T15:02:57-04:00 |
/public/images/mark_400px.png | 63543 | -rw-r--r-- | 2019-10-17T15:02:57-04:00 |
/public/index.html | 257 | -rw-r--r-- | 2019-10-17T15:02:57-04:00 |
$ pkger parse
{
".": [
{
"file": {
"Abs": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/foo/bar/baz",
"Path": {
"Pkg": "app",
"Name": "/foo/bar/baz"
},
"Here": {
"Dir": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref",
"ImportPath": "app",
"Module": {
"Path": "app",
"Main": true,
"Dir": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref",
"GoMod": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/go.mod",
"GoVersion": "1.13"
},
"Name": "main"
}
},
"pos": {
"Filename": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/main.go",
"Offset": 629,
"Line": 47,
"Column": 27
},
"type": "pkger.MkdirAll",
"value": "/foo/bar/baz"
},
{
"file": {
"Abs": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/foo/bar/baz/biz.txt",
"Path": {
"Pkg": "app",
"Name": "/foo/bar/baz/biz.txt"
},
"Here": {
"Dir": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref",
"ImportPath": "app",
"Module": {
"Path": "app",
"Main": true,
"Dir": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref",
"GoMod": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/go.mod",
"GoVersion": "1.13"
},
"Name": "main"
}
},
"pos": {
"Filename": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/main.go",
"Offset": 706,
"Line": 51,
"Column": 25
},
"type": "pkger.Create",
"value": "/foo/bar/baz/biz.txt"
},
...
]
}
```
### Output With Packing
For a module aware list use the `pkger list` command.
```bash
# run the pkger cli to generate a pkged.go file:
$ pkger
$ pkger list
# compile the go binary as usual and run the app:
$ go build -v; ./app
/ | 128 | drwxr-xr-x | 2019-10-17T15:02:57-04:00 |
/images | 192 | drwxr-xr-x | 2019-10-17T15:02:57-04:00 |
/images/mark-small.png | 649549 | -rw-r--r-- | 2019-10-17T15:02:56-04:00 |
/images/img1.png | 50401191 | -rw-r--r-- | 2019-10-17T15:02:57-04:00 |
/images/mark_250px.png | 27718 | -rw-r--r-- | 2019-10-17T15:02:57-04:00 |
/images/mark_400px.png | 63543 | -rw-r--r-- | 2019-10-17T15:02:57-04:00 |
/index.html | 257 | -rw-r--r-- | 2019-10-17T15:02:57-04:00 |
app
> app:/assets
> app:/assets/css
> app:/assets/css/_buffalo.scss
> app:/assets/css/application.scss
> app:/assets/images
> app:/assets/images/favicon.ico
> app:/assets/images/logo.svg
> app:/assets/js
> app:/assets/js/application.js
> app:/go.mod
> app:/locales/all.en-us.yaml
> app:/public
> app:/public/assets
> app:/public/assets/.keep
> app:/public/assets/app.css
> app:/public/images
> app:/public/images/img1.png
> app:/public/index.html
> app:/public/robots.txt
> app:/templates
> app:/templates/_flash.plush.html
> app:/templates/application.plush.html
> app:/templates/index.plush.html
> app:/web
> app:/web/web.go
> github.com/gobuffalo/buffalo:/logo.svg
```
The `-json` flag can be used to get a more detailed list in JSON.
```bash
$ pkger list -json
{
"ImportPath": "app",
"Files": [
{
"Abs": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/assets",
"Path": {
"Pkg": "app",
"Name": "/assets"
},
"Here": {
"Dir": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/assets",
"ImportPath": "",
"Module": {
"Path": "app",
"Main": true,
"Dir": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref",
"GoMod": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/go.mod",
"GoVersion": "1.13"
},
"Name": "assets"
}
},
{
"Abs": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/assets/css",
"Path": {
"Pkg": "app",
"Name": "/assets/css"
},
"Here": {
"Dir": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/assets",
"ImportPath": "",
"Module": {
"Path": "app",
"Main": true,
"Dir": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref",
"GoMod": "/go/src/github.com/markbates/pkger/pkging/pkgtest/testdata/ref/go.mod",
"GoVersion": "1.13"
},
"Name": "assets"
}
},
...
}
```

View File

@ -1,5 +1,3 @@
// +build !debug
package pkger
import (
@ -11,6 +9,7 @@ import (
// for layering of pkging.Pkger implementations.
func Apply(pkg pkging.Pkger, err error) error {
if err != nil {
panic(err)
return err
}
gil.Lock()

View File

@ -1,26 +0,0 @@
// +build debug
package pkger
import (
"os"
"github.com/markbates/pkger/pkging"
"github.com/markbates/pkger/pkging/pkgutil"
)
// Apply will wrap the current implementation
// of pkger.Pkger with the new pkg. This allows
// for layering of pkging.Pkger implementations.
func Apply(pkg pkging.Pkger, err error) error {
gil.Lock()
defer gil.Unlock()
if err != nil {
return err
}
if err := pkgutil.Dump(os.Stdout, pkg); err != nil {
return err
}
current = pkging.Wrap(current, pkg)
return nil
}

View File

@ -1,48 +0,0 @@
variables:
GOPROXY: "https://proxy.golang.org"
GOBIN: "$(GOPATH)/bin" # Go binaries path
GOPATH: "$(system.defaultWorkingDirectory)/gopath" # Go workspace path
modulePath: "$(GOPATH)/src/github.com/$(build.repository.name)" # Path to the module"s code
jobs:
- job: Windows
pool:
vmImage: "vs2017-win2016"
strategy:
matrix:
go 1.12 (on):
go_version: "1.12.9"
GO111MODULE: "on"
go 1.13 (on):
go_version: "1.13"
GO111MODULE: "on"
steps:
- template: azure-tests.yml
- job: macOS
pool:
vmImage: "macOS-10.13"
strategy:
matrix:
go 1.12 (on):
go_version: "1.12.9"
GO111MODULE: "on"
go 1.13 (on):
go_version: "1.13"
GO111MODULE: "on"
steps:
- template: azure-tests.yml
- job: Linux
pool:
vmImage: "ubuntu-16.04"
strategy:
matrix:
go 1.12 (on):
go_version: "1.12.9"
GO111MODULE: "on"
go 1.13 (on):
go_version: "1.13"
GO111MODULE: "on"
steps:
- template: azure-tests.yml

View File

@ -1,19 +0,0 @@
steps:
- task: GoTool@0
inputs:
version: $(go_version)
- task: Bash@3
inputs:
targetType: inline
script: |
mkdir -p "$(GOBIN)"
mkdir -p "$(GOPATH)/pkg"
mkdir -p "$(modulePath)"
shopt -s extglob
mv !(gopath) "$(modulePath)"
displayName: "Setup Go Workspace"
- script: |
go get -t -v ./...
go test -race ./...
workingDirectory: "$(modulePath)"
displayName: "Tests"

91
cmd/pkger/cmds/list.go Normal file
View File

@ -0,0 +1,91 @@
package cmds
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"os"
"path/filepath"
"github.com/markbates/pkger"
"github.com/markbates/pkger/parser"
)
type listCmd struct {
*flag.FlagSet
help bool
json bool
include slice
subs []command
}
func (e *listCmd) Name() string {
return e.Flags().Name()
}
func (e *listCmd) Exec(args []string) error {
e.Parse(args)
if e.help {
e.Usage()
return nil
}
args = e.Args()
info, err := pkger.Current()
if err != nil {
return err
}
fp := filepath.Join(info.Dir, outName)
os.RemoveAll(fp)
decls, err := parser.Parse(info, e.include...)
if err != nil {
return err
}
jay := struct {
ImportPath string
Files []*parser.File
}{
ImportPath: info.ImportPath,
}
files, err := decls.Files()
if err != nil {
return err
}
jay.Files = files
if e.json {
bb := &bytes.Buffer{}
enc := json.NewEncoder(bb)
enc.SetIndent("", " ")
if err := enc.Encode(jay); err != nil {
return err
}
_, err = os.Stdout.Write(bb.Bytes())
return err
}
fmt.Println(jay.ImportPath)
for _, f := range jay.Files {
fmt.Println(" >", f.Path)
}
return nil
}
func (e *listCmd) Flags() *flag.FlagSet {
if e.FlagSet == nil {
e.FlagSet = flag.NewFlagSet("list", flag.ExitOnError)
e.BoolVar(&e.json, "json", false, "prints in JSON format")
e.Var(&e.include, "include", "packages the specified file or directory")
}
e.Usage = Usage(os.Stderr, e.FlagSet)
return e.FlagSet
}

View File

@ -4,20 +4,35 @@ import (
"flag"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"github.com/markbates/pkger"
"github.com/markbates/pkger/here"
"github.com/markbates/pkger/parser"
"github.com/markbates/pkger/pkging/pkgutil"
)
type slice []string
func (i slice) String() string {
return fmt.Sprintf("%s", []string(i))
}
func (i *slice) Set(value string) error {
*i = append(*i, value)
return nil
}
const outName = "pkged.go"
type packCmd struct {
*flag.FlagSet
help bool
list bool
subs []command
out string
help bool
include slice
subs []command
}
func (e *packCmd) Name() string {
@ -30,24 +45,15 @@ func (e *packCmd) Exec(args []string) error {
return err
}
fp := info.FilePath(outName)
fp := filepath.Join(info.Dir, e.out, outName)
os.RemoveAll(fp)
res, err := parser.Parse(info)
decls, err := parser.Parse(info, e.include...)
if err != nil {
return err
}
if e.list {
fmt.Println(info.ImportPath)
for _, p := range res {
fmt.Printf(" > %s\n", p)
}
return nil
}
if err := Package(fp, res); err != nil {
if err := Package(info, fp, decls); err != nil {
return err
}
@ -82,22 +88,23 @@ func (e *packCmd) Route(args []string) error {
}
}
return e.Exec(args)
return fmt.Errorf("unknown arguments: %s", strings.Join(args, " "))
}
func New() (*packCmd, error) {
c := &packCmd{}
c.subs = []command{
&readCmd{}, &serveCmd{}, &statCmd{}, &infoCmd{},
&serveCmd{}, &statCmd{}, &infoCmd{}, &pathCmd{}, &parseCmd{}, &listCmd{},
}
sort.Slice(c.subs, func(a, b int) bool {
return c.subs[a].Name() <= c.subs[b].Name()
})
c.FlagSet = flag.NewFlagSet("pkger", flag.ExitOnError)
c.BoolVar(&c.list, "list", false, "prints a list of files/dirs to be packaged")
c.BoolVar(&c.help, "h", false, "prints help information")
c.StringVar(&c.out, "o", "", "output directory for pkged.go")
c.Var(&c.include, "include", "packages the specified file or directory")
c.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage:\n\n")
Usage(os.Stderr, c.FlagSet)()
@ -111,14 +118,23 @@ func New() (*packCmd, error) {
func (e *packCmd) Flags() *flag.FlagSet {
if e.FlagSet == nil {
e.FlagSet = flag.NewFlagSet("", flag.ExitOnError)
e.BoolVar(&e.list, "list", false, "prints a list of files/dirs to be packaged")
}
e.Usage = Usage(os.Stderr, e.FlagSet)
return e.FlagSet
}
func Package(out string, decls parser.Decls) error {
func Package(info here.Info, out string, decls parser.Decls) error {
c, err := here.Dir(filepath.Dir(out))
if err != nil {
return err
}
os.RemoveAll(out)
defer func() {
if err := recover(); err != nil {
os.RemoveAll(out)
}
}()
f, err := os.Create(out)
if err != nil {
@ -126,20 +142,14 @@ func Package(out string, decls parser.Decls) error {
}
defer f.Close()
c, err := pkger.Current()
if err != nil {
return err
}
fmt.Fprintf(f, "// Code generated by pkger; DO NOT EDIT.\n\n")
fmt.Fprintf(f, "// +build !skippkger\n\n")
fmt.Fprintf(f, "package %s\n\n", c.Name)
fmt.Fprintf(f, "import \"github.com/markbates/pkger\"\n\n")
fmt.Fprintf(f, "import \"github.com/markbates/pkger/pkging/mem\"\n\n")
fmt.Fprintf(f, "// packing:\n")
// for _, p := range paths {
// fmt.Fprintf(f, "// %s\n", p)
// }
fmt.Fprintf(f, "\nvar _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`")
fmt.Fprintf(f, "import (\n\t\"github.com/markbates/pkger\"\n\t")
fmt.Fprintf(f, "\"github.com/markbates/pkger/pkging/mem\"\n)\n\n")
fmt.Fprintf(f, "var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`")
if err := pkgutil.Stuff(f, c, decls); err != nil {
if err := pkgutil.Stuff(f, info, decls); err != nil {
return err
}

73
cmd/pkger/cmds/parse.go Normal file
View File

@ -0,0 +1,73 @@
package cmds
import (
"encoding/json"
"flag"
"os"
"github.com/markbates/pkger/here"
"github.com/markbates/pkger/parser"
)
type parseCmd struct {
*flag.FlagSet
json bool
help bool
}
func (s *parseCmd) Name() string {
return s.Flags().Name()
}
func (c *parseCmd) Flags() *flag.FlagSet {
if c.FlagSet == nil {
c.FlagSet = flag.NewFlagSet("parse", flag.ExitOnError)
// c.BoolVar(&c.json, "json", false, "outputs as json")
c.BoolVar(&c.help, "h", false, "prints help information")
}
return c.FlagSet
}
func (c *parseCmd) Exec(args []string) error {
c.Parse(args)
if c.help {
c.Usage()
return nil
}
args = c.Args()
if len(args) == 0 {
args = append(args, ".")
}
m := map[string]parser.Decls{}
for _, a := range args {
var info here.Info
var err error
if a == "." {
info, err = here.Dir(a)
if err != nil {
return err
}
} else {
info, err = here.Package(a)
if err != nil {
return err
}
}
decls, err := parser.Parse(info)
if err != nil {
return err
}
m[a] = decls
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
return enc.Encode(m)
}

58
cmd/pkger/cmds/path.go Normal file
View File

@ -0,0 +1,58 @@
package cmds
import (
"encoding/json"
"flag"
"fmt"
"os"
"github.com/markbates/pkger"
"github.com/markbates/pkger/here"
)
type pathCmd struct {
*flag.FlagSet
json bool
help bool
}
func (s *pathCmd) Name() string {
return s.Flags().Name()
}
func (c *pathCmd) Flags() *flag.FlagSet {
if c.FlagSet == nil {
c.FlagSet = flag.NewFlagSet("path", flag.ExitOnError)
// c.BoolVar(&c.json, "json", false, "outputs as json")
c.BoolVar(&c.help, "h", false, "prints help information")
}
return c.FlagSet
}
func (c *pathCmd) Exec(args []string) error {
c.Parse(args)
if c.help {
c.Usage()
return nil
}
args = c.Args()
if len(args) == 0 {
return fmt.Errorf("you specify at least one path")
}
paths := map[string]here.Path{}
for _, a := range args {
pt, err := pkger.Parse(a)
if err != nil {
return err
}
paths[a] = pt
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
return enc.Encode(paths)
}

View File

@ -1,63 +0,0 @@
package cmds
import (
"encoding/json"
"flag"
"fmt"
"io"
"os"
"github.com/markbates/pkger"
)
type readCmd struct {
*flag.FlagSet
JSON bool
}
func (s *readCmd) Name() string {
return s.Flags().Name()
}
func (r *readCmd) Flags() *flag.FlagSet {
if r.FlagSet == nil {
r.FlagSet = flag.NewFlagSet("read", flag.ExitOnError)
r.FlagSet.BoolVar(&r.JSON, "json", false, "print as JSON")
}
return r.FlagSet
}
func (r *readCmd) Exec(args []string) error {
if len(args) == 0 {
args = []string{"."}
}
for _, a := range args {
f, err := pkger.Open(a)
if err != nil {
return err
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
return err
}
if fi.IsDir() && !r.JSON {
return fmt.Errorf("can not read a dir %s", a)
}
if r.JSON {
err = json.NewEncoder(os.Stdout).Encode(f)
if err != nil {
return err
}
continue
}
_, err = io.Copy(os.Stdout, f)
if err != nil {
return err
}
}
return nil
}

View File

@ -1,19 +0,0 @@
package cmds
import (
"fmt"
"os"
"github.com/markbates/pkger"
)
func walk(args []string) error {
err := pkger.Walk("/", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
fmt.Println(path)
return nil
})
return err
}

View File

@ -10,7 +10,7 @@ import (
func main() {
clean := func() {
c := exec.Command("go", "mod", "tidy", "-v")
c := exec.Command("go", "mod", "tidy")
c.Stdout = os.Stdout
c.Stderr = os.Stderr
c.Stdin = os.Stdin
@ -18,6 +18,13 @@ func main() {
}
defer clean()
defer func() {
if err := recover(); err != nil {
clean()
log.Fatal(err)
}
}()
if err := run(); err != nil {
clean()
log.Fatal(err)

View File

@ -0,0 +1,7 @@
FROM alpine
EXPOSE 3000
COPY example /bin/
CMD /bin/example

View File

@ -0,0 +1,5 @@
default:
pkger
GOOS=linux go build -v -o example
docker build -t pkger:example .
docker run -p 3000:3000 pkger:example

View File

@ -0,0 +1,5 @@
module app
go 1.13
require github.com/markbates/pkger v0.5.1

View File

@ -0,0 +1,22 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/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/markbates/pkger v0.5.1 h1:l0s55z4X5XbwIat2LyLe0HABMBswVK1GJbzLXQbuAXs=
github.com/markbates/pkger v0.5.1/go.mod h1:so/QD8FeTM0IilC3nRArkwOvUT+tsJsaXLFUAKmjzJk=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -0,0 +1,43 @@
package main
import (
"fmt"
"io"
"log"
"os"
"github.com/markbates/pkger"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
info, err := pkger.Stat("/go.mod")
if err != nil {
return err
}
fmt.Println(info)
if err := pkger.MkdirAll("/foo/bar/baz", 0755); err != nil {
return err
}
f, err := pkger.Create("/foo/bar/baz/biz.txt")
if err != nil {
return err
}
f.Write([]byte("BIZ!!"))
if err := f.Close(); err != nil {
return err
}
f, err = pkger.Open("/foo/bar/baz/biz.txt")
if err != nil {
return err
}
io.Copy(os.Stdout, f)
return f.Close()
}

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -1,5 +1,4 @@
default:
go get github.com/markbates/pkger/cmd/pkger
pkger
GOOS=linux go build -v -o example
docker build -t pkger:example .

View File

@ -2,4 +2,6 @@ module app
go 1.13
require github.com/markbates/pkger v0.0.0-20191016200917-09e9684b656b
require github.com/markbates/pkger v0.5.0
replace github.com/markbates/pkger => ../../../

View File

@ -1,13 +1,15 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/gobuffalo/here v0.5.2-0.20191203194143-8e97fc9ad6d3 h1:9NGxHWbGFujaZ5vT+uXurb9m3QoWa175cYM2Qs97nQo=
github.com/gobuffalo/here v0.5.2-0.20191203194143-8e97fc9ad6d3/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI=
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
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/markbates/pkger v0.0.0-20191016200917-09e9684b656b h1:cXYQ3JZQkRLFyN8m22Q58mOhdKyTooPqvGt8pyWR8eA=
github.com/markbates/pkger v0.0.0-20191016200917-09e9684b656b/go.mod h1:0nBNvgA9jJk9gWhO/BcIYz1qJ8BJ0MWCSyKFPApdWNs=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -18,3 +20,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -14,10 +14,6 @@ func main() {
}
func run() error {
f, err := pkger.Open("/public")
if err != nil {
return err
}
dir := http.FileServer(f)
dir := http.FileServer(pkger.Dir("/public"))
return http.ListenAndServe(":3000", dir)
}

View File

@ -1,8 +0,0 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package main
import _ "app/packrd"

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,4 @@
default:
go get github.com/markbates/pkger/cmd/pkger
pkger
GOOS=linux go build -v -o example
docker build -t pkger:example .

View File

@ -2,4 +2,6 @@ module app
go 1.13
require github.com/markbates/pkger v0.0.0-20191016200917-09e9684b656b
require github.com/markbates/pkger v0.8.0
replace github.com/markbates/pkger => ../../../

View File

@ -6,8 +6,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
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/markbates/pkger v0.0.0-20191016200917-09e9684b656b h1:cXYQ3JZQkRLFyN8m22Q58mOhdKyTooPqvGt8pyWR8eA=
github.com/markbates/pkger v0.0.0-20191016200917-09e9684b656b/go.mod h1:0nBNvgA9jJk9gWhO/BcIYz1qJ8BJ0MWCSyKFPApdWNs=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -16,5 +14,6 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -0,0 +1,7 @@
FROM alpine
EXPOSE 3000
COPY example /bin/
CMD /bin/example

View File

@ -0,0 +1,5 @@
default:
pkger
GOOS=linux go build -v -o example
docker build -t pkger:example .
docker run -p 3000:3000 pkger:example

View File

@ -0,0 +1,7 @@
module app
go 1.13
require github.com/markbates/pkger v0.8.0
replace github.com/markbates/pkger => ../../../

View File

@ -0,0 +1,19 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -0,0 +1,28 @@
package main
import (
"fmt"
"log"
"github.com/markbates/pkger"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
info, err := pkger.Stat("/public/index.html")
if err != nil {
return err
}
fmt.Println("Name: ", info.Name())
fmt.Println("Size: ", info.Size())
fmt.Println("Mode: ", info.Mode())
fmt.Println("ModTime: ", info.ModTime())
return nil
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>HI</title>
</head>
<body>
HELLO
<img src="/images/img1.png" alt=""/>
</body>
</html>

View File

@ -0,0 +1,7 @@
FROM alpine
EXPOSE 3000
COPY example /bin/
CMD /bin/example

View File

@ -0,0 +1,4 @@
default:
GOOS=linux go build -v -o example
docker build -t pkger:example .
docker run -p 3000:3000 pkger:example

3
examples/stat/std/go.mod Normal file
View File

@ -0,0 +1,3 @@
module app
go 1.13

27
examples/stat/std/main.go Normal file
View File

@ -0,0 +1,27 @@
package main
import (
"fmt"
"log"
"os"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
info, err := os.Stat("./public/index.html")
if err != nil {
return err
}
fmt.Println("Name: ", info.Name())
fmt.Println("Size: ", info.Size())
fmt.Println("Mode: ", info.Mode())
fmt.Println("ModTime: ", info.ModTime())
return nil
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>HI</title>
</head>
<body>
HELLO
<img src="/images/img1.png" alt=""/>
</body>
</html>

View File

@ -1,8 +0,0 @@
// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.
// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package main
import _ "app/packrd"

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,5 @@
module app
go 1.13
require github.com/markbates/pkger v0.4.0 // indirect

18
examples/walk/std/go.sum Normal file
View File

@ -0,0 +1,18 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/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/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/markbates/pkger v0.4.0 h1:fIzmOXYsJV+nFS+RtsmWZvXeH5DDGQtF/SwKJgfgVoE=
github.com/markbates/pkger v0.4.0/go.mod h1:so/QD8FeTM0IilC3nRArkwOvUT+tsJsaXLFUAKmjzJk=
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

5
go.mod
View File

@ -3,9 +3,6 @@ module github.com/markbates/pkger
go 1.13
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/gobuffalo/here v0.6.0
github.com/stretchr/testify v1.4.0
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/yaml.v2 v2.2.4 // indirect
)

10
go.sum
View File

@ -1,7 +1,8 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI=
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
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=
@ -9,14 +10,13 @@ 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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -1,29 +0,0 @@
package here
import (
"path/filepath"
"sync"
)
var curOnce sync.Once
var curErr error
var current Info
func Current() (Info, error) {
(&curOnce).Do(func() {
b, err := run("go", "env", "GOMOD")
if err != nil {
curErr = err
return
}
root := filepath.Dir(string(b))
i, err := Dir(root)
if err != nil {
curErr = err
return
}
current = i
})
return current, curErr
}

View File

@ -1,53 +0,0 @@
package here
import (
"encoding/json"
"os"
"path/filepath"
)
// Dir attempts to gather info for the requested directory.
func Dir(p string) (Info, error) {
i, err := Cache(p, func(p string) (Info, error) {
var i Info
fi, err := os.Stat(p)
if err != nil {
return i, err
}
if !fi.IsDir() {
p = filepath.Dir(p)
}
pwd, err := os.Getwd()
if err != nil {
return i, err
}
defer os.Chdir(pwd)
os.Chdir(p)
b, err := run("go", "list", "-json")
if err != nil {
return i, err
}
if err := json.Unmarshal(b, &i); err != nil {
return i, err
}
return i, nil
})
if err != nil {
return i, err
}
Cache(i.ImportPath, func(p string) (Info, error) {
return i, nil
})
return i, nil
}

View File

@ -1,39 +1,14 @@
package here
import (
"bytes"
"os"
"os/exec"
"sync"
"github.com/gobuffalo/here"
)
var cache = &infoMap{
data: &sync.Map{},
}
type Info = here.Info
type Module = here.Module
type Path = here.Path
func run(n string, args ...string) ([]byte, error) {
c := exec.Command(n, args...)
bb := &bytes.Buffer{}
c.Stdout = bb
c.Stderr = os.Stderr
err := c.Run()
if err != nil {
return nil, err
}
return bb.Bytes(), nil
}
func Cache(p string, fn func(string) (Info, error)) (Info, error) {
i, ok := cache.Load(p)
if ok {
return i, nil
}
i, err := fn(p)
if err != nil {
return i, err
}
cache.Store(p, i)
return i, nil
}
var Here = here.New()
var Dir = Here.Dir
var Package = Here.Package
var Current = Here.Current

View File

@ -1,96 +0,0 @@
package here
import (
"encoding/json"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/markbates/pkger/internal/takeon/github.com/markbates/hepa"
"github.com/markbates/pkger/internal/takeon/github.com/markbates/hepa/filters"
)
// Info represents details about the directory/package
type Info struct {
Dir string
ImportPath string
Name string
// Imports []string
Module Module
}
func (fi Info) MarshalJSON() ([]byte, error) {
mm := map[string]interface{}{
"ImportPath": fi.ImportPath,
"Name": fi.Name,
// "Imports": fi.Imports,
"Module": fi.Module,
}
hep := hepa.New()
hep = hepa.With(hep, filters.Home())
hep = hepa.With(hep, filters.Golang())
cm := map[string]string{
"Dir": fi.Dir,
}
for k, v := range cm {
b, err := hep.Filter([]byte(v))
if err != nil {
return nil, err
}
mm[k] = string(b)
}
return json.Marshal(mm)
}
func (i Info) FilePath(paths ...string) string {
res := []string{i.Dir}
for _, p := range paths {
p = strings.TrimPrefix(p, i.Dir)
p = strings.TrimPrefix(p, "/")
if runtime.GOOS == "windows" {
p = strings.Replace(p, "/", "\\", -1)
}
res = append(res, p)
}
return filepath.Join(res...)
}
func (i Info) Open(p string) (*os.File, error) {
return os.Open(i.FilePath(p))
}
// ModuleName returns the name of the current
// module, or if not using modules, the current
// package. These *might* not match.
func (i Info) ModuleName() string {
if i.Mods() {
return i.Module.Path
}
return i.ImportPath
}
// IsZero checks if the type has been filled
// with rich chocolately data goodness
func (i Info) IsZero() bool {
return i.String() == Info{}.String()
}
// Mods returns whether Go modules are used
// in this directory/package.
func (i Info) Mods() bool {
return !i.Module.IsZero()
}
func (i Info) String() string {
b, err := json.MarshalIndent(i, "", " ")
if err != nil {
return err.Error()
}
s := string(b)
return s
}

View File

@ -1,87 +0,0 @@
// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT.
package here
import (
"sort"
"sync"
)
// infoMap wraps sync.Map and uses the following types:
// key: string
// value: Info
type infoMap struct {
data *sync.Map
}
// Delete the key from the map
func (m *infoMap) Delete(key string) {
m.data.Delete(key)
}
// Load the key from the map.
// Returns Info or bool.
// A false return indicates either the key was not found
// or the value is not of type Info
func (m *infoMap) Load(key string) (Info, bool) {
i, ok := m.data.Load(key)
if !ok {
return Info{}, false
}
s, ok := i.(Info)
return s, ok
}
// LoadOrStore will return an existing key or
// store the value if not already in the map
func (m *infoMap) LoadOrStore(key string, value Info) (Info, bool) {
i, _ := m.data.LoadOrStore(key, value)
s, ok := i.(Info)
return s, ok
}
// LoadOr will return an existing key or
// run the function and store the results
func (m *infoMap) LoadOr(key string, fn func(*infoMap) (Info, bool)) (Info, bool) {
i, ok := m.Load(key)
if ok {
return i, ok
}
i, ok = fn(m)
if ok {
m.Store(key, i)
return i, ok
}
return i, false
}
// Range over the Info values in the map
func (m *infoMap) Range(f func(key string, value Info) bool) {
m.data.Range(func(k, v interface{}) bool {
key, ok := k.(string)
if !ok {
return false
}
value, ok := v.(Info)
if !ok {
return false
}
return f(key, value)
})
}
// Store a Info in the map
func (m *infoMap) Store(key string, value Info) {
m.data.Store(key, value)
}
// Keys returns a list of keys in the map
func (m *infoMap) Keys() []string {
var keys []string
m.Range(func(key string, value Info) bool {
keys = append(keys, key)
return true
})
sort.Strings(keys)
return keys
}

View File

@ -1,55 +0,0 @@
package here
import (
"encoding/json"
"github.com/markbates/pkger/internal/takeon/github.com/markbates/hepa"
"github.com/markbates/pkger/internal/takeon/github.com/markbates/hepa/filters"
)
type Module struct {
Path string
Main bool
Dir string
GoMod string
GoVersion string
}
func (m Module) MarshalJSON() ([]byte, error) {
mm := map[string]interface{}{
"Main": m.Main,
"GoVersion": m.GoVersion,
}
hep := hepa.New()
hep = hepa.With(hep, filters.Home())
hep = hepa.With(hep, filters.Golang())
cm := map[string]string{
"Path": m.Path,
"Dir": m.Dir,
"GoMod": m.GoMod,
}
for k, v := range cm {
b, err := hep.Filter([]byte(v))
if err != nil {
return nil, err
}
mm[k] = string(b)
}
return json.Marshal(mm)
}
func (i Module) String() string {
b, err := json.MarshalIndent(i, "", " ")
if err != nil {
return err.Error()
}
return string(b)
}
func (i Module) IsZero() bool {
return i.String() == Module{}.String()
}

View File

@ -1,63 +0,0 @@
package here
import (
"fmt"
"path/filepath"
"regexp"
"strings"
)
func (i Info) Parse(p string) (Path, error) {
p = strings.TrimSpace(p)
p = filepath.Clean(p)
p = strings.TrimPrefix(p, i.Dir)
p = strings.Replace(p, "\\", "/", -1)
p = strings.TrimSpace(p)
if len(p) == 0 || p == ":" || p == "." {
return i.build("", "", "")
}
res := pathrx.FindAllStringSubmatch(p, -1)
if len(res) == 0 {
return Path{}, fmt.Errorf("could not parse %q", p)
}
matches := res[0]
if len(matches) != 4 {
return Path{}, fmt.Errorf("could not parse %q", p)
}
return i.build(p, matches[1], matches[3])
}
func (i Info) build(p, pkg, name string) (Path, error) {
pt := Path{
Pkg: pkg,
Name: name,
}
if strings.HasPrefix(pt.Pkg, "/") || len(pt.Pkg) == 0 {
pt.Name = pt.Pkg
pt.Pkg = i.ImportPath
}
if len(pt.Name) == 0 {
pt.Name = "/"
}
if pt.Pkg == pt.Name {
pt.Pkg = i.ImportPath
pt.Name = "/"
}
if !strings.HasPrefix(pt.Name, "/") {
pt.Name = "/" + pt.Name
}
pt.Name = strings.TrimPrefix(pt.Name, i.Dir)
return pt, nil
}
var pathrx = regexp.MustCompile("([^:]+)(:(/.+))?")

View File

@ -1,60 +0,0 @@
package here_test
import (
"path/filepath"
"strings"
"testing"
"github.com/markbates/pkger/here"
"github.com/markbates/pkger/pkging/pkgtest"
"github.com/stretchr/testify/require"
)
func Test_Info_Parse(t *testing.T) {
const name = "/public/index.html"
r := require.New(t)
app, err := pkgtest.App()
r.NoError(err)
ip := app.Info.ImportPath
ip2 := "another/app"
table := []struct {
in string
exp here.Path
err bool
}{
{in: name, exp: here.Path{Pkg: ip, Name: name}},
{in: "", exp: here.Path{Pkg: ip, Name: "/"}},
{in: "/", exp: here.Path{Pkg: ip, Name: "/"}},
{in: filepath.Join(app.Info.Dir, name), exp: here.Path{Pkg: ip, Name: name}},
{in: ":" + name, exp: here.Path{Pkg: ip, Name: name}},
{in: ip + ":" + name, exp: here.Path{Pkg: ip, Name: name}},
{in: ip, exp: here.Path{Pkg: ip, Name: "/"}},
{in: ":", exp: here.Path{Pkg: ip, Name: "/"}},
{in: ip2 + ":" + name, exp: here.Path{Pkg: ip2, Name: name}},
{in: ip2, exp: here.Path{Pkg: ip2, Name: "/"}},
{in: ip2 + ":", exp: here.Path{Pkg: ip2, Name: "/"}},
}
for _, tt := range table {
for _, in := range []string{tt.in, strings.ReplaceAll(tt.in, "/", "\\")} {
t.Run(in, func(st *testing.T) {
r := require.New(st)
pt, err := app.Info.Parse(in)
if tt.err {
r.Error(err)
return
}
r.NoError(err)
r.Equal(tt.exp, pt)
})
}
}
}

View File

@ -1,20 +0,0 @@
package here
import (
"fmt"
)
type Path struct {
Pkg string `json:"pkg"`
Name string `json:"name"`
}
func (p Path) String() string {
if p.Name == "" {
p.Name = "/"
}
if p.Pkg == "" {
return p.Name
}
return fmt.Sprintf("%s:%s", p.Pkg, p.Name)
}

View File

@ -1,40 +0,0 @@
package here
import (
"encoding/json"
)
// Package attempts to gather info for the requested package.
//
// From the `go help list` docs:
// The -find flag causes list to identify the named packages but not
// resolve their dependencies: the Imports and Deps lists will be empty.
//
// A workaround for this issue is to use the `Dir` field in the
// returned `Info` value and pass it to the `Dir(string) (Info, error)`
// function to return the complete data.
func Package(p string) (Info, error) {
i, err := Cache(p, func(p string) (Info, error) {
var i Info
b, err := run("go", "list", "-json", "-find", p)
if err != nil {
return i, err
}
if err := json.Unmarshal(b, &i); err != nil {
return i, err
}
return i, nil
})
if err != nil {
return i, err
}
Cache(i.Dir, func(p string) (Info, error) {
return i, nil
})
return i, nil
}

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2019 Mark Bates
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,35 +0,0 @@
package hepa
import "bytes"
type Filter interface {
Filter([]byte) ([]byte, error)
}
type FilterFunc func([]byte) ([]byte, error)
func (f FilterFunc) Filter(b []byte) ([]byte, error) {
return f(b)
}
func Rinse(p Purifier, s, r []byte) Purifier {
return WithFunc(p, func(b []byte) ([]byte, error) {
b = bytes.ReplaceAll(b, s, r)
return b, nil
})
}
func Clean(p Purifier, s []byte) Purifier {
return WithFunc(p, func(b []byte) ([]byte, error) {
if bytes.Contains(b, s) {
return []byte{}, nil
}
return b, nil
})
}
func Noop() FilterFunc {
return func(b []byte) ([]byte, error) {
return b, nil
}
}

View File

@ -1,42 +0,0 @@
package filters
import (
"os"
"strconv"
"strings"
)
var env = func() map[string]string {
m := map[string]string{}
for _, line := range os.Environ() {
kv := strings.Split(line, "=")
k, v := kv[0], kv[1]
kt, vt := strings.TrimSpace(k), strings.TrimSpace(v)
if len(kt) == 0 || len(vt) == 0 {
continue
}
switch k {
case "GO111MODULE":
continue
}
switch v {
case "true", "TRUE", "false", "FALSE", "null", "nil", "NULL":
continue
}
if _, err := strconv.Atoi(k); err == nil {
continue
}
if _, err := strconv.Atoi(v); err == nil {
continue
}
m[k] = v
}
return m
}()

View File

@ -1,12 +0,0 @@
package filters
type FilterFunc func([]byte) ([]byte, error)
func (f FilterFunc) Filter(b []byte) ([]byte, error) {
return f(b)
}
type dir struct {
Dir string
Err error
}

View File

@ -1,51 +0,0 @@
package filters
import (
"bytes"
"os"
"path/filepath"
)
func Golang() FilterFunc {
return func(b []byte) ([]byte, error) {
gp, err := gopath(home)
if err != nil {
return nil, err
}
b = bytes.ReplaceAll(b, []byte(gp.Dir), []byte("$GOPATH"))
gru, err := goroot(gp)
if err != nil {
return nil, err
}
b = bytes.ReplaceAll(b, []byte(gru.Dir), []byte("$GOROOT"))
return b, nil
}
}
func goroot(gp dir) (dir, error) {
gru, ok := os.LookupEnv("GOROOT")
if !ok {
if gp.Err != nil {
return gp, gp.Err
}
gru = filepath.Join(string(gp.Dir), "go")
}
return dir{
Dir: gru,
}, nil
}
func gopath(home dir) (dir, error) {
gp, ok := os.LookupEnv("GOPATH")
if !ok {
if home.Err != nil {
return home, home.Err
}
gp = filepath.Join(string(home.Dir), "go")
}
return dir{
Dir: gp,
}, nil
}

View File

@ -1,31 +0,0 @@
package filters
import (
"bytes"
"os"
)
var home = func() dir {
var d dir
home, ok := os.LookupEnv("HOME")
if !ok {
pwd, err := os.Getwd()
if err != nil {
d.Err = err
return d
}
home = pwd
}
d.Dir = home
return d
}()
func Home() FilterFunc {
return func(b []byte) ([]byte, error) {
if home.Err != nil {
return b, home.Err
}
return bytes.ReplaceAll(b, []byte(home.Dir), []byte("$HOME")), nil
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +0,0 @@
package filters
import (
"bytes"
"strings"
)
func Secrets() FilterFunc {
return func(b []byte) ([]byte, error) {
for k, v := range env {
for _, s := range secretSuffixes {
if !strings.HasSuffix(k, s) {
continue
}
b = bytes.ReplaceAll(b, []byte(v), []byte(mask()))
break
}
}
return b, nil
}
}
var secretSuffixes = []string{
"_KEY",
"_SECRET",
"_TOKEN",
"_PASSWORD",
"_PASS",
}

View File

@ -1,15 +0,0 @@
package hepa
func WithFunc(p Purifier, fn FilterFunc) Purifier {
c := New()
c.parent = &p
c.filter = fn
return c
}
func With(p Purifier, f Filter) Purifier {
c := New()
c.parent = &p
c.filter = f
return c
}

View File

@ -1,67 +0,0 @@
package hepa
import (
"bufio"
"bytes"
"io"
"github.com/markbates/pkger/internal/takeon/github.com/markbates/hepa/filters"
)
type Purifier struct {
parent *Purifier
filter Filter
}
func (p Purifier) Filter(b []byte) ([]byte, error) {
if p.filter == nil {
p.filter = filters.Home()
}
b, err := p.filter.Filter(b)
if err != nil {
return b, err
}
if p.parent != nil {
return p.parent.Filter(b)
}
return b, nil
}
func (p Purifier) Clean(r io.Reader) ([]byte, error) {
bb := &bytes.Buffer{}
if p.filter == nil {
if p.parent != nil {
return p.parent.Clean(r)
}
_, err := io.Copy(bb, r)
return bb.Bytes(), err
}
home := filters.Home()
reader := bufio.NewReader(r)
for {
input, _, err := reader.ReadLine()
if err != nil && err == io.EOF {
break
}
input, err = p.Filter(input)
if err != nil {
return nil, err
}
input, err = home(input)
if err != nil {
return nil, err
}
bb.Write(input)
// if len(input) > 0 {
bb.Write([]byte("\n"))
// }
}
return bb.Bytes(), nil
}
func New() Purifier {
return Purifier{}
}

View File

@ -1,4 +0,0 @@
package hepa
// Version of hepa
const Version = "v0.0.1"

51
parser/create.go Normal file
View File

@ -0,0 +1,51 @@
package parser
import (
"encoding/json"
"go/token"
"os"
)
var _ Decl = CreateDecl{}
type CreateDecl struct {
file *File
pos token.Position
value string
}
func (d CreateDecl) String() string {
b, _ := json.Marshal(d)
return string(b)
}
func (d CreateDecl) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"type": "pkger.Create",
"file": d.file,
"pos": d.pos,
"value": d.value,
})
}
func (d CreateDecl) File() (*File, error) {
if d.file == nil {
return nil, os.ErrNotExist
}
return d.file, nil
}
func (d CreateDecl) Position() (token.Position, error) {
return d.pos, nil
}
func (d CreateDecl) Value() (string, error) {
if d.value == "" {
return "", os.ErrNotExist
}
return d.value, nil
}
func (d CreateDecl) VirtualPaths() []string {
return []string{d.value}
}

View File

@ -1,38 +1,51 @@
package parser
import (
"fmt"
"go/token"
"sort"
)
type Decl interface {
File() (*File, error)
Pos() (token.Pos, error)
Position() (token.Position, error)
Value() (string, error)
}
type Filer interface {
Files() ([]*File, error)
Files(map[string]string) ([]*File, error)
}
type Virtualer interface {
VirtualPaths() []string
}
type Decls []Decl
func (decls Decls) Files() ([]*File, error) {
m := map[string]*File{}
v := map[string]string{}
for _, d := range decls {
if vt, ok := d.(Virtualer); ok {
for _, s := range vt.VirtualPaths() {
v[s] = s
}
}
fl, ok := d.(Filer)
if !ok {
continue
}
files, err := fl.Files()
files, err := fl.Files(v)
if err != nil {
return nil, err
return nil, fmt.Errorf("%s: %s", err, d)
}
for _, f := range files {
m[f.Path.String()] = f
m[f.Abs] = f
v[f.Abs] = f.Abs
}
}

View File

@ -2,11 +2,6 @@ package parser
import (
"encoding/json"
"go/ast"
"go/parser"
"go/token"
"io"
"io/ioutil"
"github.com/markbates/pkger/here"
)
@ -21,36 +16,3 @@ func (f File) String() string {
b, _ := json.MarshalIndent(f, "", " ")
return string(b)
}
type parsedFile struct {
File string
FileSet *token.FileSet
Ast *ast.File
}
// parseFileMode ...
func parseFileMode(f string, mode parser.Mode) (parsedFile, error) {
pf := parsedFile{
File: f,
FileSet: token.NewFileSet(),
}
b, err := ioutil.ReadFile(f)
if err != nil {
return pf, err
}
src := string(b)
pff, err := parser.ParseFile(pf.FileSet, f, src, mode)
if err != nil && err != io.EOF {
return pf, err
}
pf.Ast = pff
return pf, nil
}
// parseFile ...
func parseFile(f string) (parsedFile, error) {
return parseFileMode(f, 0)
}

57
parser/http.go Normal file
View File

@ -0,0 +1,57 @@
package parser
import (
"encoding/json"
"go/token"
"os"
)
var _ Decl = HTTPDecl{}
type HTTPDecl struct {
file *File
pos token.Position
value string
}
func (d HTTPDecl) String() string {
b, _ := json.Marshal(d)
return string(b)
}
func (d HTTPDecl) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"type": "pkger.Dir",
"file": d.file,
"pos": d.pos,
"value": d.value,
})
}
func (d HTTPDecl) File() (*File, error) {
if d.file == nil {
return nil, os.ErrNotExist
}
return d.file, nil
}
func (d HTTPDecl) Position() (token.Position, error) {
return d.pos, nil
}
func (d HTTPDecl) Value() (string, error) {
if d.value == "" {
return "", os.ErrNotExist
}
return d.value, nil
}
func (d HTTPDecl) Files(virtual map[string]string) ([]*File, error) {
od := OpenDecl{
file: d.file,
pos: d.pos,
value: d.value,
}
return od.Files(virtual)
}

88
parser/include.go Normal file
View File

@ -0,0 +1,88 @@
package parser
import (
"encoding/json"
"fmt"
"go/token"
"os"
"path/filepath"
"github.com/markbates/pkger/here"
)
var _ Decl = IncludeDecl{}
type IncludeDecl struct {
file *File
pos token.Position
value string
}
func NewInclude(her here.Info, inc string) (IncludeDecl, error) {
var id IncludeDecl
pt, err := her.Parse(inc)
if err != nil {
return id, err
}
if pt.Pkg != her.ImportPath {
her, err = here.Package(pt.Pkg)
if err != nil {
return id, err
}
}
abs := filepath.Join(her.Module.Dir, pt.Name)
f := &File{
Abs: abs,
Path: pt,
Here: her,
}
return IncludeDecl{
value: inc,
file: f,
}, nil
}
func (d IncludeDecl) String() string {
return fmt.Sprintf("pkger.Include(%q)", d.value)
}
func (d IncludeDecl) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"type": "pkger.Include",
"file": d.file,
"pos": d.pos,
"value": d.value,
})
}
func (d IncludeDecl) File() (*File, error) {
if d.file == nil {
return nil, os.ErrNotExist
}
return d.file, nil
}
func (d IncludeDecl) Position() (token.Position, error) {
return d.pos, nil
}
func (d IncludeDecl) Value() (string, error) {
if d.value == "" {
return "", os.ErrNotExist
}
return d.value, nil
}
func (d IncludeDecl) Files(virtual map[string]string) ([]*File, error) {
od := OpenDecl{
file: d.file,
pos: d.pos,
value: d.value,
}
return od.Files(virtual)
}

51
parser/mkdir.go Normal file
View File

@ -0,0 +1,51 @@
package parser
import (
"encoding/json"
"go/token"
"os"
)
var _ Decl = MkdirAllDecl{}
type MkdirAllDecl struct {
file *File
pos token.Position
value string
}
func (d MkdirAllDecl) String() string {
b, _ := json.Marshal(d)
return string(b)
}
func (d MkdirAllDecl) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"type": "pkger.MkdirAll",
"file": d.file,
"pos": d.pos,
"value": d.value,
})
}
func (d MkdirAllDecl) File() (*File, error) {
if d.file == nil {
return nil, os.ErrNotExist
}
return d.file, nil
}
func (d MkdirAllDecl) Position() (token.Position, error) {
return d.pos, nil
}
func (d MkdirAllDecl) Value() (string, error) {
if d.value == "" {
return "", os.ErrNotExist
}
return d.value, nil
}
func (d MkdirAllDecl) VirtualPaths() []string {
return []string{d.value}
}

View File

@ -1,22 +1,34 @@
package parser
import (
"encoding/json"
"go/token"
"os"
"path/filepath"
"github.com/markbates/pkger"
"github.com/markbates/pkger/here"
)
var _ Decl = OpenDecl{}
type OpenDecl struct {
file *File
pos token.Pos
pos token.Position
value string
}
func (d OpenDecl) String() string {
b, _ := json.Marshal(d)
return string(b)
}
func (d OpenDecl) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"type": "pkger.Open",
"file": d.file,
"pos": d.pos,
"value": d.value,
})
}
func (d OpenDecl) File() (*File, error) {
if d.file == nil {
return nil, os.ErrNotExist
@ -24,10 +36,7 @@ func (d OpenDecl) File() (*File, error) {
return d.file, nil
}
func (d OpenDecl) Pos() (token.Pos, error) {
if d.pos <= 0 {
return -1, os.ErrNotExist
}
func (d OpenDecl) Position() (token.Position, error) {
return d.pos, nil
}
@ -38,19 +47,15 @@ func (d OpenDecl) Value() (string, error) {
return d.value, nil
}
func (d OpenDecl) Files() ([]*File, error) {
pt, err := pkger.Parse(d.value)
if err != nil {
return nil, err
func (d OpenDecl) Files(virtual map[string]string) ([]*File, error) {
if _, ok := virtual[d.value]; ok {
return nil, nil
}
her, err := here.Package(pt.Pkg)
if err != nil {
return nil, err
}
her := d.file.Here
pt := d.file.Path
fp := filepath.Join(her.Dir, pt.Name)
fp := filepath.Join(her.Module.Dir, pt.Name)
osf, err := os.Stat(fp)
if err != nil {
@ -63,15 +68,11 @@ func (d OpenDecl) Files() ([]*File, error) {
pos: d.pos,
value: d.value,
}
return wd.Files()
return wd.Files(virtual)
}
var files []*File
files = append(files, &File{
Abs: filepath.Join(her.Dir, pt.Name),
Path: pt,
Here: her,
})
files = append(files, d.file)
return files, nil
}

View File

@ -4,56 +4,237 @@ import (
"fmt"
"go/parser"
"go/token"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
"github.com/markbates/pkger/here"
)
// var DefaultIgnoredFolders = []string{".", "_", "vendor", "node_modules", "_fixtures", "testdata"}
var defaultIgnoredFolders = []string{".", "_", "vendor", "node_modules", "testdata"}
func Parse(her here.Info) (Decls, error) {
src, err := fromSource(her)
if err != nil {
return nil, err
}
return src, nil
func New(her here.Info) (*Parser, error) {
return &Parser{
Info: her,
decls: map[string]Decls{},
}, nil
}
func fromSource(her here.Info) (Decls, error) {
root := her.Dir
fi, err := os.Stat(root)
type Parser struct {
here.Info
decls map[string]Decls
once sync.Once
includes []string
err error
}
func Parse(her here.Info, includes ...string) (Decls, error) {
p, err := New(her)
if err != nil {
return nil, err
}
if !fi.IsDir() {
return nil, fmt.Errorf("%q is not a directory", root)
p.includes = includes
return p.Decls()
}
func (p *Parser) ParseSource(source Source, mode parser.Mode) (*ParsedSource, error) {
pf := &ParsedSource{
Source: source,
FileSet: token.NewFileSet(),
}
b, err := ioutil.ReadFile(source.Abs)
if err != nil {
return nil, err
}
src := string(b)
pff, err := parser.ParseFile(pf.FileSet, source.Abs, src, mode)
if err != nil && err != io.EOF {
return nil, err
}
pf.Ast = pff
return pf, nil
}
func (p *Parser) ParseFile(abs string, mode parser.Mode) (*ParsedSource, error) {
s := Source{
Abs: abs,
}
info, err := os.Stat(abs)
if err != nil {
return nil, err
}
if info.IsDir() {
return nil, fmt.Errorf("%s is a directory", abs)
}
dir := filepath.Dir(abs)
s.Here, err = here.Dir(dir)
if err != nil {
return nil, err
}
s.Path, err = s.Here.Parse(strings.TrimPrefix(abs, dir))
return p.ParseSource(s, 0)
}
func (p *Parser) ParseDir(abs string, mode parser.Mode) ([]*ParsedSource, error) {
info, err := os.Stat(abs)
if err != nil {
return nil, err
}
if !info.IsDir() {
return nil, fmt.Errorf("%s is not a directory", abs)
}
her, err := here.Dir(abs)
if err != nil {
return nil, fmt.Errorf("%s: here.Dir failed %s", err, abs)
}
pt, err := her.Parse(strings.TrimPrefix(abs, filepath.Dir(abs)))
if err != nil {
return nil, fmt.Errorf("%s: here.Parse failed %s", err, abs)
}
filter := func(f os.FileInfo) bool {
return !f.IsDir()
}
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, root, nil, 0)
pkgs, err := parser.ParseDir(fset, abs, filter, 0)
if err != nil {
return nil, fmt.Errorf("%s: ParseDir failed %s", err, abs)
}
var srcs []*ParsedSource
for _, pkg := range pkgs {
for name, pf := range pkg.Files {
s := &ParsedSource{
Source: Source{
Abs: name,
Path: pt,
Here: her,
},
FileSet: fset,
Ast: pf,
}
srcs = append(srcs, s)
}
}
return srcs, nil
}
func (p *Parser) Decls() (Decls, error) {
if err := p.parse(); err != nil {
return nil, err
}
var decls Decls
orderedNames := []string{
"MkdirAll",
"Create",
"Include",
"Stat",
"Open",
"Dir",
"Walk",
}
for _, pkg := range pkgs {
for name, pf := range pkg.Files {
f := &file{
fset: fset,
astFile: pf,
filename: name,
}
x, err := f.find()
if err != nil {
return nil, err
}
decls = append(decls, x...)
}
for _, n := range orderedNames {
decls = append(decls, p.decls[n]...)
}
return decls, nil
}
func (p *Parser) DeclsMap() (map[string]Decls, error) {
err := p.Parse()
return p.decls, err
}
func (p *Parser) Parse() error {
(&p.once).Do(func() {
p.err = p.parse()
})
return p.err
}
func (p *Parser) parse() error {
p.decls = map[string]Decls{}
root := p.Dir
if err := p.parseIncludes(); err != nil {
return err
}
fi, err := os.Stat(root)
if err != nil {
return err
}
if !fi.IsDir() {
return fmt.Errorf("%q is not a directory", root)
}
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
return nil
}
base := filepath.Base(path)
for _, x := range defaultIgnoredFolders {
if strings.HasPrefix(base, x) {
return filepath.SkipDir
}
}
srcs, err := p.ParseDir(path, 0)
if err != nil {
return fmt.Errorf("%s: %s", err, path)
}
for _, src := range srcs {
mm, err := src.DeclsMap()
if err != nil {
return fmt.Errorf("%s: %s", err, src.Abs)
}
for k, v := range mm {
p.decls[k] = append(p.decls[k], v...)
}
}
return nil
})
return err
}
func (p *Parser) parseIncludes() error {
for _, i := range p.includes {
d, err := NewInclude(p.Info, i)
if err != nil {
return err
}
p.decls["Include"] = append(p.decls["Include"], d)
}
return nil
}

View File

@ -1,37 +1,122 @@
package parser_test
package parser
import (
"fmt"
"sort"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/markbates/pkger/parser"
"github.com/markbates/pkger/here"
"github.com/markbates/pkger/pkging/pkgtest"
"github.com/markbates/pkger/pkging/stdos"
"github.com/stretchr/testify/require"
)
func Test_Parser_App(t *testing.T) {
func Test_Parser_Ref(t *testing.T) {
defer func() {
c := exec.Command("go", "mod", "tidy", "-v")
c.Run()
}()
r := require.New(t)
app, err := pkgtest.App()
ref, err := pkgtest.NewRef()
r.NoError(err)
defer os.RemoveAll(ref.Dir)
disk, err := stdos.New(ref.Info)
r.NoError(err)
res, err := parser.Parse(app.Info)
_, err = pkgtest.LoadFiles("/", ref, disk)
r.NoError(err)
res, err := Parse(ref.Info)
r.NoError(err)
files, err := res.Files()
r.NoError(err)
for _, f := range files {
fmt.Println(f.Path)
}
r.Len(files, 25)
}
func Test_Parser_Ref_Include(t *testing.T) {
defer func() {
c := exec.Command("go", "mod", "tidy", "-v")
c.Run()
}()
r := require.New(t)
ref, err := pkgtest.NewRef()
r.NoError(err)
defer os.RemoveAll(ref.Dir)
disk, err := stdos.New(ref.Info)
r.NoError(err)
_, err = pkgtest.LoadFiles("/", ref, disk)
r.NoError(err)
res, err := Parse(ref.Info, "github.com/stretchr/testify:/go.mod")
r.NoError(err)
files, err := res.Files()
r.NoError(err)
act := make([]string, len(files))
for i := 0; i < len(files); i++ {
act[i] = files[i].Path.String()
}
sort.Strings(act)
for _, a := range act {
fmt.Println(a)
}
r.Equal(app.Paths.Parser, act)
l := len(files)
r.Equal(26, l)
}
func Test_Parser_dotGo_Directory(t *testing.T) {
r := require.New(t)
ref, err := pkgtest.NewRef()
r.NoError(err)
defer os.RemoveAll(ref.Dir)
err = os.Mkdir(filepath.Join(ref.Dir, ".go"), 0755)
r.NoError(err)
disk, err := stdos.New(ref.Info)
r.NoError(err)
_, err = pkgtest.LoadFiles("/", ref, disk)
r.NoError(err)
res, err := Parse(ref.Info)
r.NoError(err)
r.Equal(11, len(res))
}
func Test_Parser_Example_HTTP(t *testing.T) {
r := require.New(t)
cur, err := here.Package("github.com/markbates/pkger")
r.NoError(err)
root := filepath.Join(cur.Dir, "examples", "http", "pkger")
defer func() {
c := exec.Command("go", "mod", "tidy", "-v")
c.Run()
}()
her, err := here.Dir(root)
r.NoError(err)
res, err := Parse(her)
r.NoError(err)
files, err := res.Files()
r.NoError(err)
r.Len(files, 5)
for _, f := range files {
r.True(strings.HasPrefix(f.Abs, her.Dir), "%q %q", f.Abs, her.Dir)
r.True(strings.HasPrefix(f.Path.Name, "/public"), "%q %q", f.Path.Name, "/public")
}
}

216
parser/source.go Normal file
View File

@ -0,0 +1,216 @@
package parser
import (
"fmt"
"go/ast"
"go/token"
"path/filepath"
"strconv"
"sync"
"github.com/markbates/pkger/here"
)
type Source struct {
Abs string // full path on disk to file
Path here.Path
Here here.Info
}
type ParsedSource struct {
Source
FileSet *token.FileSet
Ast *ast.File
decls map[string]Decls
once sync.Once
err error
}
func (p *ParsedSource) Parse() error {
(&p.once).Do(func() {
p.err = p.parse()
})
return p.err
}
func (p *ParsedSource) valueIdent(node *ast.Ident) (s string) {
s = node.Name
if node.Obj.Kind != ast.Con {
return
}
// As per ast package a Con object is always a *ValueSpec,
// but double-checking to avoid panics
if x, ok := node.Obj.Decl.(*ast.ValueSpec); ok {
// The const var can be defined inline with other vars,
// as in `const a, b = "a", "b"`.
for i, v := range x.Names {
if v.Name == node.Name {
s = p.valueNode(x.Values[i])
break
}
}
}
return
}
func (p *ParsedSource) valueNode(node ast.Node) string {
var s string
switch x := node.(type) {
case *ast.BasicLit:
s = x.Value
case *ast.Ident:
s = p.valueIdent(x)
}
return s
}
func (p *ParsedSource) value(node ast.Node) (string, error) {
s := p.valueNode(node)
return strconv.Unquote(s)
}
func (p *ParsedSource) parse() error {
p.decls = map[string]Decls{}
var fn walker = func(node ast.Node) bool {
ce, ok := node.(*ast.CallExpr)
if !ok {
return true
}
sel, ok := ce.Fun.(*ast.SelectorExpr)
if !ok {
return true
}
pkg, ok := sel.X.(*ast.Ident)
if !ok {
return true
}
if pkg.Name != "pkger" {
return true
}
var fn func(f File, pos token.Position, value string) Decl
name := sel.Sel.Name
switch name {
case "MkdirAll":
fn = func(f File, pos token.Position, value string) Decl {
return MkdirAllDecl{
file: &f,
pos: pos,
value: value,
}
}
case "Create":
fn = func(f File, pos token.Position, value string) Decl {
return CreateDecl{
file: &f,
pos: pos,
value: value,
}
}
case "Include":
fn = func(f File, pos token.Position, value string) Decl {
return IncludeDecl{
file: &f,
pos: pos,
value: value,
}
}
case "Stat":
fn = func(f File, pos token.Position, value string) Decl {
return StatDecl{
file: &f,
pos: pos,
value: value,
}
}
case "Open":
fn = func(f File, pos token.Position, value string) Decl {
return OpenDecl{
file: &f,
pos: pos,
value: value,
}
}
case "Dir":
fn = func(f File, pos token.Position, value string) Decl {
return HTTPDecl{
file: &f,
pos: pos,
value: value,
}
}
case "Walk":
fn = func(f File, pos token.Position, value string) Decl {
return WalkDecl{
file: &f,
pos: pos,
value: value,
}
}
default:
return true
}
if len(ce.Args) < 1 {
p.err = fmt.Errorf("declarations require at least one argument")
return false
}
n := ce.Args[0]
val, err := p.value(n)
if err != nil {
p.err = fmt.Errorf("%s: %s", err, n)
return false
}
info, err := here.Dir(filepath.Dir(p.Abs))
if err != nil {
p.err = fmt.Errorf("%s: %s", err, p.Abs)
return false
}
pt, err := info.Parse(val)
if err != nil {
p.err = fmt.Errorf("%s: %s", err, p.Abs)
return false
}
if pt.Pkg != info.Module.Path {
info, err = here.Package(pt.Pkg)
if err != nil {
p.err = fmt.Errorf("%s: %s", err, p.Abs)
return false
}
}
f := File{
Abs: filepath.Join(info.Module.Dir, pt.Name),
Here: info,
Path: pt,
}
p.decls[name] = append(p.decls[name], fn(f, p.FileSet.Position(n.Pos()), val))
return true
}
ast.Walk(fn, p.Ast)
return nil
}
func (p *ParsedSource) DeclsMap() (map[string]Decls, error) {
err := p.Parse()
return p.decls, err
}
// wrap a function to fulfill ast.Visitor interface
type walker func(ast.Node) bool
func (w walker) Visit(node ast.Node) ast.Visitor {
if w(node) {
return w
}
return nil
}

57
parser/stat.go Normal file
View File

@ -0,0 +1,57 @@
package parser
import (
"encoding/json"
"fmt"
"go/token"
"os"
)
var _ Decl = StatDecl{}
type StatDecl struct {
file *File
pos token.Position
value string
}
func (d StatDecl) String() string {
return fmt.Sprintf("pkger.Stat(%q)", d.value)
}
func (d StatDecl) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"type": "pkger.Stat",
"file": d.file,
"pos": d.pos,
"value": d.value,
})
}
func (d StatDecl) File() (*File, error) {
if d.file == nil {
return nil, os.ErrNotExist
}
return d.file, nil
}
func (d StatDecl) Position() (token.Position, error) {
return d.pos, nil
}
func (d StatDecl) Value() (string, error) {
if d.value == "" {
return "", os.ErrNotExist
}
return d.value, nil
}
func (d StatDecl) Files(virtual map[string]string) ([]*File, error) {
od := OpenDecl{
file: d.file,
pos: d.pos,
value: d.value,
}
return od.Files(virtual)
}

View File

@ -1,159 +0,0 @@
package parser
import (
"go/ast"
"go/token"
"path/filepath"
"strconv"
"github.com/markbates/pkger/here"
)
type visitor func(node ast.Node) (w ast.Visitor)
func (v visitor) Visit(node ast.Node) ast.Visitor {
return v(node)
}
// inspired by https://gist.github.com/cryptix/d1b129361cea51a59af2
type file struct {
fset *token.FileSet
astFile *ast.File
filename string
decls Decls
}
func (f *file) walk(fn func(ast.Node) bool) {
ast.Walk(walker(fn), f.astFile)
}
func (f *file) find() (Decls, error) {
if err := f.findOpenCalls(); err != nil {
return nil, err
}
if err := f.findWalkCalls(); err != nil {
return nil, err
}
return f.decls, nil
}
func (f *file) asValue(node ast.Node) (string, error) {
var s string
switch x := node.(type) {
case *ast.BasicLit:
s = x.Value
case *ast.Ident:
s = x.Name
}
return strconv.Unquote(s)
}
func (f *file) findOpenCalls() error {
var err error
f.walk(func(node ast.Node) bool {
ce, ok := node.(*ast.CallExpr)
if !ok {
return true
}
exists := isPkgDot(ce.Fun, "pkger", "Open")
if !(exists) || len(ce.Args) != 1 {
return true
}
n := ce.Args[0]
s, err := f.asValue(n)
if err != nil {
return false
}
info, err := here.Dir(filepath.Dir(f.filename))
if err != nil {
return false
}
pf := &File{
Abs: f.filename,
Here: info,
}
decl := OpenDecl{
file: pf,
pos: n.Pos(),
value: s,
}
f.decls = append(f.decls, decl)
return true
})
return err
}
func (f *file) findWalkCalls() error {
var err error
f.walk(func(node ast.Node) bool {
ce, ok := node.(*ast.CallExpr)
if !ok {
return true
}
exists := isPkgDot(ce.Fun, "pkger", "Walk")
if !(exists) || len(ce.Args) != 2 {
return true
}
n := ce.Args[0]
s, err := f.asValue(n)
if err != nil {
return false
}
info, err := here.Dir(filepath.Dir(f.filename))
if err != nil {
return false
}
pf := &File{
Abs: f.filename,
Here: info,
}
decl := WalkDecl{
file: pf,
pos: n.Pos(),
value: s,
}
f.decls = append(f.decls, decl)
return true
})
return err
}
// helpers
// =======
func isPkgDot(expr ast.Expr, pkg, name string) bool {
sel, ok := expr.(*ast.SelectorExpr)
return ok && isIdent(sel.X, pkg) && isIdent(sel.Sel, name)
}
func isIdent(expr ast.Expr, ident string) bool {
id, ok := expr.(*ast.Ident)
return ok && id.Name == ident
}
// wrap a function to fulfill ast.Visitor interface
type walker func(ast.Node) bool
func (w walker) Visit(node ast.Node) ast.Visitor {
if w(node) {
return w
}
return nil
}

View File

@ -1,12 +1,12 @@
package parser
import (
"encoding/json"
"go/token"
"os"
"path/filepath"
"strings"
"github.com/markbates/pkger"
"github.com/markbates/pkger/here"
)
@ -14,10 +14,24 @@ var _ Decl = WalkDecl{}
type WalkDecl struct {
file *File
pos token.Pos
pos token.Position
value string
}
func (d WalkDecl) String() string {
b, _ := json.Marshal(d)
return string(b)
}
func (d WalkDecl) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"type": "pkger.Walk",
"file": d.file,
"pos": d.pos,
"value": d.value,
})
}
func (d WalkDecl) File() (*File, error) {
if d.file == nil {
return nil, os.ErrNotExist
@ -25,10 +39,7 @@ func (d WalkDecl) File() (*File, error) {
return d.file, nil
}
func (d WalkDecl) Pos() (token.Pos, error) {
if d.pos <= 0 {
return -1, os.ErrNotExist
}
func (d WalkDecl) Position() (token.Position, error) {
return d.pos, nil
}
@ -39,37 +50,44 @@ func (d WalkDecl) Value() (string, error) {
return d.value, nil
}
func (d WalkDecl) Files() ([]*File, error) {
pt, err := pkger.Parse(d.value)
if err != nil {
return nil, err
}
cur, err := here.Package(pt.Pkg)
if err != nil {
return nil, err
}
root := filepath.Join(cur.Dir, pt.Name)
func (d WalkDecl) Files(virtual map[string]string) ([]*File, error) {
var files []*File
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
her := d.file.Here
pt := d.file.Path
root := filepath.Join(her.Module.Dir, pt.Name)
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
n := strings.TrimPrefix(path, cur.Dir)
if info.IsDir() {
her, err = here.Dir(path)
if err != nil {
return err
}
}
pt, err := pkger.Parse(n)
n := strings.TrimPrefix(path, her.Module.Dir)
pt, err := her.Parse(n)
if err != nil {
return err
}
pt.Pkg = cur.ImportPath
if _, ok := virtual[n]; ok {
if info.IsDir() {
return filepath.SkipDir
}
return nil
}
files = append(files, &File{
Abs: path,
Path: pt,
Here: cur,
Here: her,
})
return nil
})

View File

@ -1,7 +1,7 @@
package pkger
import (
"log"
"net/http"
"os"
"path/filepath"
"sync"
@ -15,14 +15,8 @@ var current pkging.Pkger
var gil = &sync.RWMutex{}
var disk = func() pkging.Pkger {
her, err := here.Current()
if err != nil {
log.Println(err)
}
n, err := stdos.New(her)
if err != nil {
log.Println(err)
}
her, _ := here.Current()
n, _ := stdos.New(her)
return n
}()
@ -35,21 +29,21 @@ func impl() pkging.Pkger {
return current
}
type Dir string
func (d Dir) Open(name string) (http.File, error) {
f, err := impl().Open(string(d))
if err != nil {
return nil, err
}
return f.Open(name)
}
// Parse the string in here.Path format.
func Parse(p string) (here.Path, error) {
return impl().Parse(p)
}
// Abs returns an absolute representation of path. If the path is not absolute it will be joined with the current working directory to turn it into an absolute path. The absolute path name for a given file is not guaranteed to be unique. Abs calls Clean on the result.
func Abs(p string) (string, error) {
return impl().Abs(p)
}
// AbsPath returns an absolute representation of here.Path. If the path is not absolute it will be joined with the current working directory to turn it into an absolute path. The absolute path name for a given file is not guaranteed to be unique. AbsPath calls Clean on the result.
func AbsPath(p here.Path) (string, error) {
return impl().AbsPath(p)
}
// Current returns the here.Info representing the current Pkger implementation.
func Current() (here.Info, error) {
return impl().Current()
@ -94,3 +88,8 @@ func Remove(name string) error {
func RemoveAll(name string) error {
return impl().RemoveAll(name)
}
// Include is a no-op that directs the pkger tool to include the desired file or folder.
func Include(name string) string {
return name
}

View File

@ -2,10 +2,8 @@ package pkger
import (
"os"
"path/filepath"
"testing"
"github.com/markbates/pkger/here"
"github.com/stretchr/testify/require"
)
@ -18,31 +16,6 @@ func Test_Parse(t *testing.T) {
r.Equal("/little", pt.Name)
}
func Test_Abs(t *testing.T) {
r := require.New(t)
s, err := Abs(":/rocket.ship")
r.NoError(err)
pwd, err := os.Getwd()
r.NoError(err)
r.Equal(filepath.Join(pwd, "rocket.ship"), s)
}
func Test_AbsPath(t *testing.T) {
r := require.New(t)
s, err := AbsPath(here.Path{
Pkg: "github.com/markbates/pkger",
Name: "/rocket.ship",
})
r.NoError(err)
pwd, err := os.Getwd()
r.NoError(err)
r.Equal(filepath.Join(pwd, "rocket.ship"), s)
}
func Test_Current(t *testing.T) {
r := require.New(t)
@ -66,7 +39,7 @@ func Test_Create(t *testing.T) {
defer RemoveAll("/tmp")
f, err := Create("/tmp/test.create")
r.NoError(err)
r.Equal("/tmp/test.create", f.Name())
r.Equal("github.com/markbates/pkger:/tmp/test.create", f.Name())
r.NoError(f.Close())
}
@ -80,7 +53,7 @@ func Test_MkdirAll(t *testing.T) {
f, err := Open("/tmp")
r.NoError(err)
r.Equal("/tmp", f.Name())
r.Equal("github.com/markbates/pkger:/tmp", f.Name())
r.NoError(f.Close())
}
@ -89,14 +62,14 @@ func Test_Stat(t *testing.T) {
info, err := Stat("/go.mod")
r.NoError(err)
r.Equal("/go.mod", info.Name())
r.Equal("go.mod", info.Name())
}
func Test_Walk(t *testing.T) {
r := require.New(t)
files := map[string]os.FileInfo{}
err := Walk("/pkging/pkgtest/internal/testdata/app", func(path string, info os.FileInfo, err error) error {
err := Walk("/pkging/pkgtest/testdata/ref", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
@ -115,7 +88,6 @@ func Test_Remove(t *testing.T) {
defer RemoveAll("/tmp")
f, err := Create("/tmp/test.create")
r.NoError(err)
r.Equal("/tmp/test.create", f.Name())
r.NoError(f.Close())
r.NoError(Remove("/tmp/test.create"))

View File

@ -4,17 +4,48 @@ import (
"bytes"
"compress/gzip"
"encoding/hex"
"encoding/json"
"io"
"github.com/markbates/pkger/here"
)
type Embedder interface {
MarshalEmbed() ([]byte, error)
func Decode(src []byte) ([]byte, error) {
dst := make([]byte, hex.DecodedLen(len(src)))
_, err := hex.Decode(dst, src)
if err != nil {
return nil, err
}
r, err := gzip.NewReader(bytes.NewReader(dst))
if err != nil {
return nil, err
}
bb := &bytes.Buffer{}
if _, err := io.Copy(bb, r); err != nil {
return nil, err
}
return bb.Bytes(), nil
}
type Unembedder interface {
UnmarshalEmbed([]byte) error
func Encode(b []byte) ([]byte, error) {
bb := &bytes.Buffer{}
gz := gzip.NewWriter(bb)
if _, err := gz.Write(b); err != nil {
return nil, err
}
if err := gz.Flush(); err != nil {
return nil, err
}
if err := gz.Close(); err != nil {
return nil, err
}
s := hex.EncodeToString(bb.Bytes())
return []byte(s), nil
}
type Data struct {
@ -22,37 +53,3 @@ type Data struct {
Files map[string]File `json:"files"`
Here here.Info `json:"here"`
}
func (d *Data) MarshalEmbed() ([]byte, error) {
bb := &bytes.Buffer{}
gz := gzip.NewWriter(bb)
defer gz.Close()
if err := json.NewEncoder(gz).Encode(d); err != nil {
return nil, err
}
if err := gz.Close(); err != nil {
return nil, err
}
s := hex.EncodeToString(bb.Bytes())
return []byte(s), nil
}
func (d *Data) UnmarshalEmbed(in []byte) error {
b := make([]byte, len(in))
if _, err := hex.Decode(b, in); err != nil {
return err
}
gz, err := gzip.NewReader(bytes.NewReader(b))
if err != nil {
return err
}
defer gz.Close()
p := &Data{}
if err := json.NewDecoder(gz).Decode(p); err != nil {
return err
}
(*d) = *p
return nil
}

View File

@ -0,0 +1,22 @@
package embed
import (
"testing"
"github.com/stretchr/testify/require"
)
func Test_Encoding(t *testing.T) {
r := require.New(t)
in := []byte("hi\n")
enc, err := Encode(in)
r.NoError(err)
r.NotEqual(in, enc)
dec, err := Decode(enc)
r.NoError(err)
r.Equal(in, dec)
}

View File

@ -1,5 +1,7 @@
package pkging
import "os"
type Adder interface {
Add(files ...File) error
Add(files ...*os.File) error
}

View File

@ -11,9 +11,6 @@ type File interface {
// Close closes the File, rendering it unusable for I/O.
Close() error
// Abs returns an absolute representation of the file. If the path is not absolute it will be joined with the current working directory to turn it into an absolute path. The absolute path name for a given file is not guaranteed to be unique. Abs calls Clean on the result.
Abs() (string, error)
// Info returns the here.Info of the file
Info() here.Info

View File

@ -3,7 +3,6 @@ package pkging
import (
"encoding/json"
"os"
"strings"
"time"
)
@ -15,6 +14,7 @@ type Details struct {
IsDir bool `json:"is_dir"`
Sys interface{} `json:"sys"`
}
type FileInfo struct {
Details `json:"details"`
}
@ -53,7 +53,7 @@ var _ os.FileInfo = &FileInfo{}
func NewFileInfo(info os.FileInfo) *FileInfo {
fi := &FileInfo{
Details: Details{
Name: cleanName(info.Name()),
Name: info.Name(),
Size: info.Size(),
Mode: info.Mode(),
ModTime: ModTime(info.ModTime()),
@ -63,29 +63,3 @@ func NewFileInfo(info os.FileInfo) *FileInfo {
}
return fi
}
func WithName(name string, info os.FileInfo) *FileInfo {
fo := NewFileInfo(info)
fo.Details.Name = cleanName(name)
return fo
}
func WithRelName(name string, info os.FileInfo) *FileInfo {
fo := NewFileInfo(info)
s := cleanName(name)
s = strings.TrimPrefix(s, "/")
fo.Details.Name = s
return fo
}
func cleanName(s string) string {
if strings.Contains(s, "\\") {
s = strings.Replace(s, "\\", "/", -1)
}
if !strings.HasPrefix(s, "/") {
s = "/" + s
}
return s
}

31
pkging/file_info_test.go Normal file
View File

@ -0,0 +1,31 @@
package pkging_test
import (
"os"
"path/filepath"
"testing"
"time"
"github.com/markbates/pkger/here"
"github.com/markbates/pkger/pkging"
"github.com/stretchr/testify/require"
)
func Test_NewFileInfo(t *testing.T) {
r := require.New(t)
her, err := here.Current()
r.NoError(err)
exp, err := os.Stat(filepath.Join(her.Dir, "go.mod"))
r.NoError(err)
act := pkging.NewFileInfo(exp)
r.Equal(exp.Name(), act.Name())
r.Equal(exp.Size(), act.Size())
r.Equal(exp.Mode(), act.Mode())
r.Equal(exp.IsDir(), act.IsDir())
r.Equal(exp.ModTime().Format(time.RFC3339), act.ModTime().Format(time.RFC3339))
}

View File

@ -1,82 +0,0 @@
package pkging
import (
"os"
"testing"
"github.com/stretchr/testify/require"
)
func Test_NewFileInfo(t *testing.T) {
in := []string{
"/public/images/img1.png",
"public/images/img1.png",
"/public\\images/img1.png",
"public/images\\img1.png",
"\\public\\images\\img1.png",
"public\\images\\img1.png",
"\\public/images\\img1.png",
"public\\images/img1.png",
"\\public\\images\\img1.png",
}
const exp = "/public/images/img1.png"
for _, n := range in {
t.Run(n, func(st *testing.T) {
r := require.New(st)
f1 := &FileInfo{
Details: Details{
Name: n,
Size: 42,
Mode: os.FileMode(0644),
IsDir: true,
},
}
f2 := NewFileInfo(f1)
r.Equal(exp, f2.Name())
r.Equal(f1.Size(), f2.Size())
r.Equal(f1.Mode(), f2.Mode())
r.Equal(f1.IsDir(), f2.IsDir())
})
}
}
func Test_WithName(t *testing.T) {
f1 := &FileInfo{
Details: Details{
Name: "/walls/crumbling",
Size: 42,
Mode: os.FileMode(0644),
IsDir: true,
},
}
const exp = "/public/images/img1.png"
in := []string{
"/public/images/img1.png",
"public/images/img1.png",
"/public\\images/img1.png",
"public/images\\img1.png",
"\\public\\images\\img1.png",
"public\\images\\img1.png",
"\\public/images\\img1.png",
"public\\images/img1.png",
"\\public\\images\\img1.png",
}
for _, n := range in {
t.Run(n, func(st *testing.T) {
r := require.New(st)
f2 := WithName(n, f1)
r.Equal(exp, f2.Name())
})
}
}

View File

@ -3,32 +3,88 @@ package mem
import (
"bytes"
"io"
"os"
"path/filepath"
"github.com/markbates/pkger/here"
"github.com/markbates/pkger/pkging"
)
var _ pkging.Adder = &Pkger{}
// Add copies the pkging.File into the *Pkger
func (fx *Pkger) Add(files ...pkging.File) error {
func (fx *Pkger) Add(files ...*os.File) error {
for _, f := range files {
info, err := f.Stat()
if err != nil {
return err
}
pt, err := fx.Parse(f.Name())
if err != nil {
return err
}
if f.Path().Pkg == fx.Here.ImportPath {
dir := filepath.Dir(f.Name())
if dir != "/" {
if err := fx.MkdirAll(dir, 0755); err != nil {
dir := f.Name()
if !info.IsDir() {
dir = filepath.Dir(dir)
}
her, err := here.Dir(dir)
if err != nil {
return err
}
if info.IsDir() {
err = filepath.Walk(f.Name(), func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
pt, err := fx.Parse(path)
if err != nil {
return err
}
her, err := here.Package(pt.Pkg)
if err != nil {
return err
}
mf := &File{
Here: her,
info: pkging.NewFileInfo(info),
path: pt,
pkging: fx,
}
if !info.IsDir() {
bb := &bytes.Buffer{}
_, err = io.Copy(bb, f)
if err != nil {
return err
}
mf.data = bb.Bytes()
}
fx.files.Store(mf.Path(), mf)
return nil
})
if err != nil {
return err
}
continue
}
mf := &File{
Here: f.Info(),
Here: her,
info: pkging.NewFileInfo(info),
path: f.Path(),
path: pt,
pkging: fx,
}

Some files were not shown because too many files have changed in this diff Show More