Make `transpile inventory` work the way I expected

This commit is contained in:
Neale Pickett 2021-03-26 18:20:49 -06:00
parent 7595f36100
commit 17a8b7f9cb
6 changed files with 48 additions and 32 deletions

View File

@ -7,11 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [unreleased] ## [unreleased]
### Changed ### Changed
- example/5/draggable.js fix for FireFox to prevent dropping a draggable trying to load a URL - example/5/draggable.js fix for FireFox to prevent dropping a draggable trying to load a URL
- `transpile` arguments now work the same way for the transpile binary as they do for mkpuzzle
- `transpile inventory` does what you expect: inventory of current category, not inventory of all categories
## [v4.1.1] ### Fixed
- `transpile` will now run `mkcategory` and `mkpuzzle` when invoked without `-dir`
## [v4.1.1] - 2020-03-02
### Removed ### Removed
- ppc64le and i386 builds of github, because ppc64le keep failing mysteriously, and we don't need them anyhow. - ppc64le and i386 builds of github, because ppc64le keep failing mysteriously, and we don't need them anyhow.
## [v4.1.0] - 2020-03-02 ## [v4.1.0] - 2020-03-02
### Added ### Added
- `transpile` now has a `markdown` command, - `transpile` now has a `markdown` command,
@ -50,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- More detailed [API documntation](docs/api.md) - More detailed [API documntation](docs/api.md)
- Transpiler warning if `mkpuzzle` exists but is not executable - Transpiler warning if `mkpuzzle` exists but is not executable
## [v4.0.0] - 2020-10-14 ## [v4.0.0] - 2020-10-14
### Fixed ### Fixed
- Multiple bugs preventing production server from working properly - Multiple bugs preventing production server from working properly
@ -62,6 +70,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Documented the HTTP API - Documented the HTTP API
- Added a drawing of how things fit together - Added a drawing of how things fit together
## [v4.0-rc1] - 2020-10-13 ## [v4.0-rc1] - 2020-10-13
### Changed ### Changed
- Major rewrite/refactor of `mothd` - Major rewrite/refactor of `mothd`
@ -95,13 +104,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Security ### Security
## [v3.5.1] - 2020-03-16 ## [v3.5.1] - 2020-03-16
### Fixed ### Fixed
- Support insta-checking for legacy puzzles - Support insta-checking for legacy puzzles
## [v3.5.0] - 2020-03-13 ## [v3.5.0] - 2020-03-13
### Changed ### Changed
- We are now using SHA256 instead of djb2hash - We are now using SHA256 instead of djb2hash
### Added ### Added
- URL parameter to points.json to allow returning only the JSON for a single - URL parameter to points.json to allow returning only the JSON for a single
team by its team id (e.g., points.json?id=abc123). team by its team id (e.g., points.json?id=abc123).
@ -113,24 +125,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Mothballs can now specify `X-Answer-Pattern` header fields, which allow `*` - Mothballs can now specify `X-Answer-Pattern` header fields, which allow `*`
at the beginning, end, or both, of an answer. This is `X-` because we at the beginning, end, or both, of an answer. This is `X-` because we
are hoping to change how this works in the future. are hoping to change how this works in the future.
### Fixed ### Fixed
- Handle cases where non-legacy puzzles don't have an `author` attribute - Handle cases where non-legacy puzzles don't have an `author` attribute
- Handle YAML-formatted file and script lists as expected - Handle YAML-formatted file and script lists as expected
- YAML-formatted example puzzle actually works as expected - YAML-formatted example puzzle actually works as expected
- points.log will now always be sorted chronologically - points.log will now always be sorted chronologically
## [3.4.3] - 2019-11-20 ## [3.4.3] - 2019-11-20
### Fixed ### Fixed
- Made top-scoring teams full-width - Made top-scoring teams full-width
## [3.4.2] - 2019-11-18 ## [3.4.2] - 2019-11-18
### Fixed ### Fixed
- Issue with multiple answers in devel server and YAML-format .moth - Issue with multiple answers in devel server and YAML-format .moth
## [3.4.1] - 2019-11-17 ## [3.4.1] - 2019-11-17
### Fixed ### Fixed
- Scoreboard was double-counting points - Scoreboard was double-counting points
## [3.4] - 2019-11-13 ## [3.4] - 2019-11-13
### Added ### Added
- A changelog - A changelog
@ -139,5 +156,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Embedded graph in scoreboard - Embedded graph in scoreboard
- Optional tracking of participant IDs - Optional tracking of participant IDs
- New `notices.html` file for sending broadcast messages to players - New `notices.html` file for sending broadcast messages to players
### Changed ### Changed
- Use native JS URL objects instead of wrangling everything by hand - Use native JS URL objects instead of wrangling everything by hand

View File

@ -99,30 +99,31 @@ func (t *T) ParseArgs() (Command, error) {
// PrintInventory prints a puzzle inventory to stdout // PrintInventory prints a puzzle inventory to stdout
func (t *T) PrintInventory() error { func (t *T) PrintInventory() error {
inv, err := transpile.FsInventory(t.fs) c := transpile.NewFsCategory(t.fs, "")
inv, err := c.Inventory()
if err != nil {
return err
}
sort.Ints(inv)
jinv, err := json.Marshal(
transpile.InventoryResponse{
Puzzles: inv,
},
)
if err != nil { if err != nil {
return err return err
} }
cats := make([]string, 0, len(inv)) t.Stdout.Write(jinv)
for cat := range inv {
cats = append(cats, cat)
}
sort.Strings(cats)
for _, cat := range cats {
puzzles := inv[cat]
fmt.Fprint(t.Stdout, cat)
for _, p := range puzzles {
fmt.Fprint(t.Stdout, " ", p)
}
fmt.Fprintln(t.Stdout)
}
return nil return nil
} }
// DumpPuzzle writes a puzzle's JSON to the writer. // DumpPuzzle writes a puzzle's JSON to the writer.
func (t *T) DumpPuzzle() error { func (t *T) DumpPuzzle() error {
log.Println("Hello!")
puzzle := transpile.NewFsPuzzle(t.fs) puzzle := transpile.NewFsPuzzle(t.fs)
log.Println("Hello!")
p, err := puzzle.Puzzle() p, err := puzzle.Puzzle()
if err != nil { if err != nil {

View File

@ -61,10 +61,10 @@ func TestTranspilerEverything(t *testing.T) {
BaseFs: newTestFs(), BaseFs: newTestFs(),
} }
if err := tp.Run("inventory"); err != nil { if err := tp.Run("inventory", "-dir=cat0"); err != nil {
t.Error(err) t.Error(err)
} }
if stdout.String() != "cat0 1 2 3 4 5 10\nunbroken 1 2\n" { if stdout.String() != "{\"Puzzles\":[1,2,3,4,5,10]}" {
t.Errorf("Bad inventory: %#v", stdout.String()) t.Errorf("Bad inventory: %#v", stdout.String())
} }

View File

@ -39,10 +39,13 @@ func (b *RecursiveBasePathFs) RealPath(name string) (path string, err error) {
bpath := filepath.Clean(b.path) bpath := filepath.Clean(b.path)
path = filepath.Clean(filepath.Join(bpath, name)) path = filepath.Clean(filepath.Join(bpath, name))
if parentRecursiveBasePathFs, ok := b.source.(*RecursiveBasePathFs); ok { switch pfs := b.source.(type) {
return parentRecursiveBasePathFs.RealPath(path) case *RecursiveBasePathFs:
} else if parentRecursiveBasePathFs, ok := b.source.(*afero.BasePathFs); ok { return pfs.RealPath(path)
return parentRecursiveBasePathFs.RealPath(path) case *afero.BasePathFs:
return pfs.RealPath(path)
case *afero.OsFs:
return path, nil
} }
if !strings.HasPrefix(path, bpath) { if !strings.HasPrefix(path, bpath) {

View File

@ -56,7 +56,7 @@ func NewFsCategory(fs afero.Fs, cat string) Category {
bfs := NewRecursiveBasePathFs(fs, cat) bfs := NewRecursiveBasePathFs(fs, cat)
if info, err := bfs.Stat("mkcategory"); (err == nil) && (info.Mode()&0100 != 0) { if info, err := bfs.Stat("mkcategory"); (err == nil) && (info.Mode()&0100 != 0) {
if command, err := bfs.RealPath(info.Name()); err != nil { if command, err := bfs.RealPath(info.Name()); err != nil {
log.Println("Unable to resolve full path to", info.Name(), bfs) log.Println("Unable to resolve full path to", info.Name())
} else { } else {
return FsCommandCategory{ return FsCommandCategory{
fs: bfs, fs: bfs,

View File

@ -134,17 +134,11 @@ type PuzzleProvider interface {
func NewFsPuzzle(fs afero.Fs) PuzzleProvider { func NewFsPuzzle(fs afero.Fs) PuzzleProvider {
var command string var command string
if info, err := fs.Stat("mkpuzzle"); !os.IsNotExist(err) { bfs := NewRecursiveBasePathFs(fs, "")
if info, err := bfs.Stat("mkpuzzle"); !os.IsNotExist(err) {
if (info.Mode() & 0100) != 0 { if (info.Mode() & 0100) != 0 {
// Try to get the actual path to the executable if command, err = bfs.RealPath(info.Name()); err != nil {
if pfs, ok := fs.(*RecursiveBasePathFs); ok { log.Println("WARN: Unable to resolve full path to", info.Name())
if command, err = pfs.RealPath(info.Name()); err != nil {
log.Println("WARN: Unable to resolve full path to", info.Name(), pfs)
}
} else if pfs, ok := fs.(*afero.BasePathFs); ok {
if command, err = pfs.RealPath(info.Name()); err != nil {
log.Println("WARN: Unable to resolve full path to", info.Name(), pfs)
}
} }
} else { } else {
log.Println("WARN: mkpuzzle exists, but isn't executable.") log.Println("WARN: mkpuzzle exists, but isn't executable.")