todos and lint fixes; added hermit

This commit is contained in:
Zellyn Hunter 2021-07-31 22:44:04 -04:00
parent 7d036244af
commit 116f3781b5
16 changed files with 140 additions and 40 deletions

View File

@ -98,15 +98,16 @@ operations matrix is listed below. Anything that an actual user needs
will be likely to get priority. will be likely to get priority.
- [ ] Make `put` accept load address for appropriate filetypes. - [ ] Make `put` accept load address for appropriate filetypes.
- [ ] Fix `golint` errors
- [ ] Implement `GetFile` for prodos - [ ] Implement `GetFile` for prodos
- [x] Build per-platform binaries for Linux, MacOS, Windows. - [ ] Implement `Delete` for Super-Mon
- [x] Implement `GetFile` for DOS 3.3 - [ ] Implement `Delete` for DOS 3.3
- [ ] Implement `Delete` for ProDOS
- [ ] Add and implement the `-l` flag for `ls` - [ ] Add and implement the `-l` flag for `ls`
- [x] Add `Delete` to the `disk.Operator` interface - [ ] Make `OperatorFactory.SeemsToMatch` more sophisticated for ProDOS
- [ ] Implement it for Super-Mon - [ ] Make `OperatorFactory.SeemsToMatch` more sophisticated for DOS 3.3
- [ ] Implement it for DOS 3.3 - [ ] Make `OperatorFactory.SeemsToMatch` more sophisticated for NakedOS
- [ ] Add ProDOS support for all commands - [x] Build per-platform binaries for Linux, MacOS, Windows.
- [x] Make `filetypes` command use a tabwriter to write as a table
# Related tools # Related tools

View File

@ -186,6 +186,7 @@ func Decode(raw []byte) (Listing, error) {
return listing, nil return listing, nil
} }
/*
const ( const (
tokenREM = 0x5D tokenREM = 0x5D
tokenUnaryPlus = 0x35 tokenUnaryPlus = 0x35
@ -193,6 +194,7 @@ const (
tokenQuoteStart = 0x28 tokenQuoteStart = 0x28
tokenQuoteEnd = 0x29 tokenQuoteEnd = 0x29
) )
*/
func isalnum(b byte) bool { func isalnum(b byte) bool {
switch { switch {

View File

@ -39,6 +39,7 @@ var helloListing = ` 10 REM THIS IS A COMMENT
// TestParse tests the full parsing and output of a basic program from // TestParse tests the full parsing and output of a basic program from
// bytes. // bytes.
func TestParse(t *testing.T) { func TestParse(t *testing.T) {
t.Skip("ignoring for now")
listing, err := Decode(helloBinary) listing, err := Decode(helloBinary)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -46,6 +47,6 @@ func TestParse(t *testing.T) {
text := basic.ChevronControlCodes(listing.String()) text := basic.ChevronControlCodes(listing.String())
if text != helloListing { if text != helloListing {
// TODO(zellyn): actually test, once we understand how adding spaces works. // TODO(zellyn): actually test, once we understand how adding spaces works.
// t.Fatalf("Wrong listing; want:\n%s\ngot:\n%s", helloListing, text) t.Fatalf("Wrong listing; want:\n%s\ngot:\n%s", helloListing, text)
} }
} }

View File

@ -0,0 +1 @@
hermit

7
bin/README.hermit.md Normal file
View File

@ -0,0 +1,7 @@
# Hermit environment
This is a [Hermit](https://github.com/cashapp/hermit) bin directory.
The symlinks in this directory are managed by Hermit and will automatically
download and install Hermit itself as well as packages. These packages are
local to this environment.

19
bin/activate-hermit Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
# This file must be used with "source bin/activate-hermit" from bash or zsh.
# You cannot run it directly
if [ "${BASH_SOURCE-}" = "$0" ]; then
echo "You must source this script: \$ source $0" >&2
exit 33
fi
BIN_DIR="$(dirname "${BASH_SOURCE[0]:-${(%):-%x}}")"
if "${BIN_DIR}/hermit" noop > /dev/null; then
eval "$("${BIN_DIR}/hermit" activate "${BIN_DIR}/..")"
if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ]; then
hash -r 2>/dev/null
fi
echo "Hermit environment $("${HERMIT_ENV}"/bin/hermit env HERMIT_ENV) activated"
fi

1
bin/golangci-lint Symbolic link
View File

@ -0,0 +1 @@
.golangci-lint-1.41.1.pkg

26
bin/hermit Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
set -eo pipefail
if [ -z "${HERMIT_STATE_DIR}" ]; then
case "$(uname -s)" in
Darwin)
export HERMIT_STATE_DIR="${HOME}/Library/Caches/hermit"
;;
Linux)
export HERMIT_STATE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/hermit"
;;
esac
fi
export HERMIT_DIST_URL="${HERMIT_DIST_URL:-https://d1abdrezunyhdp.cloudfront.net/square}"
HERMIT_CHANNEL="$(basename "${HERMIT_DIST_URL}")"
export HERMIT_CHANNEL
export HERMIT_EXE=${HERMIT_EXE:-${HERMIT_STATE_DIR}/pkg/hermit@${HERMIT_CHANNEL}/hermit}
if [ ! -x "${HERMIT_EXE}" ]; then
echo "Bootstrapping ${HERMIT_EXE} from ${HERMIT_DIST_URL}" 1>&2
curl -fsSL "${HERMIT_DIST_URL}/install.sh" | /bin/bash 1>&2
fi
exec "${HERMIT_EXE}" --level=fatal exec "$0" -- "$@"

0
bin/hermit.hcl Normal file
View File

View File

@ -12,13 +12,21 @@ import (
type LsCmd struct { type LsCmd struct {
Order types.DiskOrder `kong:"default='auto',enum='auto,do,po',help='Logical-to-physical sector order.'"` Order types.DiskOrder `kong:"default='auto',enum='auto,do,po',help='Logical-to-physical sector order.'"`
System string `kong:"default='auto',enum='auto,dos3',help='DOS system used for image.'"` System string `kong:"default='auto',enum='auto,dos3,prodos,nakedos',help='DOS system used for image.'"`
ShortNames bool `kong:"short='s',help='Whether to print short filenames (only makes a difference on Super-Mon disks).'"` ShortNames bool `kong:"short='s',help='Whether to print short filenames (only makes a difference on Super-Mon disks).'"`
Image *os.File `kong:"arg,required,help='Disk/device image to read.'"` Image *os.File `kong:"arg,required,help='Disk/device image to read.'"`
Directory string `kong:"arg,optional,help='Directory to list (ProDOS only).'"` Directory string `kong:"arg,optional,help='Directory to list (ProDOS only).'"`
} }
func (l LsCmd) Help() string {
return `Examples:
# Simple ls of a disk image
diskii ls games.dsk
# Get really explicit about disk order and system
diskii ls --order do --system nakedos Super-Mon-2.0.dsk`
}
func (l *LsCmd) Run(globals *types.Globals) error { func (l *LsCmd) Run(globals *types.Globals) error {
op, order, err := disk.OpenFile(l.Image, l.Order, l.System, globals.DiskOperatorFactories, globals.Debug) op, order, err := disk.OpenFile(l.Image, l.Order, l.System, globals.DiskOperatorFactories, globals.Debug)
if err != nil { if err != nil {

View File

@ -32,7 +32,7 @@ func (ds DiskSector) GetTrack() byte {
} }
// SetTrack sets the track that a DiskSector was loaded from. // SetTrack sets the track that a DiskSector was loaded from.
func (ds DiskSector) SetTrack(track byte) { func (ds *DiskSector) SetTrack(track byte) {
ds.Track = track ds.Track = track
} }
@ -42,7 +42,7 @@ func (ds DiskSector) GetSector() byte {
} }
// SetSector sets the sector that a DiskSector was loaded from. // SetSector sets the sector that a DiskSector was loaded from.
func (ds DiskSector) SetSector(sector byte) { func (ds *DiskSector) SetSector(sector byte) {
ds.Sector = sector ds.Sector = sector
} }
@ -695,10 +695,7 @@ func (of OperatorFactory) Name() string {
func (of OperatorFactory) SeemsToMatch(diskbytes []byte, debug bool) bool { func (of OperatorFactory) SeemsToMatch(diskbytes []byte, debug bool) bool {
// For now, just return true if we can run Catalog successfully. // For now, just return true if we can run Catalog successfully.
_, _, err := ReadCatalog(diskbytes, debug) _, _, err := ReadCatalog(diskbytes, debug)
if err != nil { return err == nil
return false
}
return true
} }
// Operator returns an Operator for the []byte disk image. // Operator returns an Operator for the []byte disk image.

View File

@ -10,11 +10,14 @@ import (
// TestVTOCMarshalRoundtrip checks a simple roundtrip of VTOC data. // TestVTOCMarshalRoundtrip checks a simple roundtrip of VTOC data.
func TestVTOCMarshalRoundtrip(t *testing.T) { func TestVTOCMarshalRoundtrip(t *testing.T) {
buf := make([]byte, 256) buf := make([]byte, 256)
rand.Read(buf) _, _ = rand.Read(buf)
buf1 := make([]byte, 256) buf1 := make([]byte, 256)
copy(buf1, buf) copy(buf1, buf)
vtoc1 := &VTOC{} vtoc1 := &VTOC{}
vtoc1.FromSector(buf1) err := vtoc1.FromSector(buf1)
if err != nil {
t.Fatal(err)
}
buf2, err := vtoc1.ToSector() buf2, err := vtoc1.ToSector()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -23,7 +26,10 @@ func TestVTOCMarshalRoundtrip(t *testing.T) {
t.Errorf("Buffers differ: %v != %v", buf, buf2) t.Errorf("Buffers differ: %v != %v", buf, buf2)
} }
vtoc2 := &VTOC{} vtoc2 := &VTOC{}
vtoc2.FromSector(buf2) err = vtoc2.FromSector(buf2)
if err != nil {
t.Fatal(err)
}
if *vtoc1 != *vtoc2 { if *vtoc1 != *vtoc2 {
t.Errorf("Structs differ: %v != %v", vtoc1, vtoc2) t.Errorf("Structs differ: %v != %v", vtoc1, vtoc2)
} }
@ -32,11 +38,14 @@ func TestVTOCMarshalRoundtrip(t *testing.T) {
// TestCatalogSectorMarshalRoundtrip checks a simple roundtrip of CatalogSector data. // TestCatalogSectorMarshalRoundtrip checks a simple roundtrip of CatalogSector data.
func TestCatalogSectorMarshalRoundtrip(t *testing.T) { func TestCatalogSectorMarshalRoundtrip(t *testing.T) {
buf := make([]byte, 256) buf := make([]byte, 256)
rand.Read(buf) _, _ = rand.Read(buf)
buf1 := make([]byte, 256) buf1 := make([]byte, 256)
copy(buf1, buf) copy(buf1, buf)
cs1 := &CatalogSector{} cs1 := &CatalogSector{}
cs1.FromSector(buf1) err := cs1.FromSector(buf1)
if err != nil {
t.Fatal(err)
}
buf2, err := cs1.ToSector() buf2, err := cs1.ToSector()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -45,7 +54,10 @@ func TestCatalogSectorMarshalRoundtrip(t *testing.T) {
t.Errorf("Buffers differ: %v != %v", buf, buf2) t.Errorf("Buffers differ: %v != %v", buf, buf2)
} }
cs2 := &CatalogSector{} cs2 := &CatalogSector{}
cs2.FromSector(buf2) err = cs2.FromSector(buf2)
if err != nil {
t.Fatal(err)
}
if *cs1 != *cs2 { if *cs1 != *cs2 {
t.Errorf("Structs differ: %v != %v", cs1, cs2) t.Errorf("Structs differ: %v != %v", cs1, cs2)
} }
@ -54,11 +66,14 @@ func TestCatalogSectorMarshalRoundtrip(t *testing.T) {
// TestTrackSectorListMarshalRoundtrip checks a simple roundtrip of TrackSectorList data. // TestTrackSectorListMarshalRoundtrip checks a simple roundtrip of TrackSectorList data.
func TestTrackSectorListMarshalRoundtrip(t *testing.T) { func TestTrackSectorListMarshalRoundtrip(t *testing.T) {
buf := make([]byte, 256) buf := make([]byte, 256)
rand.Read(buf) _, _ = rand.Read(buf)
buf1 := make([]byte, 256) buf1 := make([]byte, 256)
copy(buf1, buf) copy(buf1, buf)
cs1 := &TrackSectorList{} cs1 := &TrackSectorList{}
cs1.FromSector(buf1) err := cs1.FromSector(buf1)
if err != nil {
t.Fatal(err)
}
buf2, err := cs1.ToSector() buf2, err := cs1.ToSector()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -67,7 +82,10 @@ func TestTrackSectorListMarshalRoundtrip(t *testing.T) {
t.Errorf("Buffers differ: %v != %v", buf, buf2) t.Errorf("Buffers differ: %v != %v", buf, buf2)
} }
cs2 := &TrackSectorList{} cs2 := &TrackSectorList{}
cs2.FromSector(buf2) err = cs2.FromSector(buf2)
if err != nil {
t.Fatal(err)
}
if *cs1 != *cs2 { if *cs1 != *cs2 {
t.Errorf("Structs differ: %v != %v", cs1, cs2) t.Errorf("Structs differ: %v != %v", cs1, cs2)
} }

View File

@ -926,10 +926,7 @@ func (of OperatorFactory) Name() string {
func (of OperatorFactory) SeemsToMatch(devicebytes []byte, debug bool) bool { func (of OperatorFactory) SeemsToMatch(devicebytes []byte, debug bool) bool {
// For now, just return true if we can run Catalog successfully. // For now, just return true if we can run Catalog successfully.
_, err := readVolume(devicebytes, 2, debug) _, err := readVolume(devicebytes, 2, debug)
if err != nil { return err == nil
return false
}
return true
} }
// Operator returns an Operator for the []byte disk image. // Operator returns an Operator for the []byte disk image.

View File

@ -11,7 +11,7 @@ import (
func randomBlock() disk.Block { func randomBlock() disk.Block {
var b1 disk.Block var b1 disk.Block
rand.Read(b1[:]) _, _ = rand.Read(b1[:])
return b1 return b1
} }
@ -19,7 +19,10 @@ func randomBlock() disk.Block {
func TestVolumeDirectoryKeyBlockMarshalRoundtrip(t *testing.T) { func TestVolumeDirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
b1 := randomBlock() b1 := randomBlock()
vdkb := &VolumeDirectoryKeyBlock{} vdkb := &VolumeDirectoryKeyBlock{}
vdkb.FromBlock(b1) err := vdkb.FromBlock(b1)
if err != nil {
t.Fatal(err)
}
b2, err := vdkb.ToBlock() b2, err := vdkb.ToBlock()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -28,7 +31,10 @@ func TestVolumeDirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; ")) t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; "))
} }
vdkb2 := &VolumeDirectoryKeyBlock{} vdkb2 := &VolumeDirectoryKeyBlock{}
vdkb2.FromBlock(b2) err = vdkb2.FromBlock(b2)
if err != nil {
t.Fatal(err)
}
if *vdkb != *vdkb2 { if *vdkb != *vdkb2 {
t.Errorf("Structs differ: %v != %v", vdkb, vdkb2) t.Errorf("Structs differ: %v != %v", vdkb, vdkb2)
} }
@ -38,7 +44,10 @@ func TestVolumeDirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
func TestVolumeDirectoryBlockMarshalRoundtrip(t *testing.T) { func TestVolumeDirectoryBlockMarshalRoundtrip(t *testing.T) {
b1 := randomBlock() b1 := randomBlock()
vdb := &VolumeDirectoryBlock{} vdb := &VolumeDirectoryBlock{}
vdb.FromBlock(b1) err := vdb.FromBlock(b1)
if err != nil {
t.Fatal(err)
}
b2, err := vdb.ToBlock() b2, err := vdb.ToBlock()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -47,7 +56,10 @@ func TestVolumeDirectoryBlockMarshalRoundtrip(t *testing.T) {
t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; ")) t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; "))
} }
vdb2 := &VolumeDirectoryBlock{} vdb2 := &VolumeDirectoryBlock{}
vdb2.FromBlock(b2) err = vdb2.FromBlock(b2)
if err != nil {
t.Fatal(err)
}
if *vdb != *vdb2 { if *vdb != *vdb2 {
t.Errorf("Structs differ: %v != %v", vdb, vdb2) t.Errorf("Structs differ: %v != %v", vdb, vdb2)
} }
@ -57,7 +69,10 @@ func TestVolumeDirectoryBlockMarshalRoundtrip(t *testing.T) {
func TestSubdirectoryKeyBlockMarshalRoundtrip(t *testing.T) { func TestSubdirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
b1 := randomBlock() b1 := randomBlock()
skb := &SubdirectoryKeyBlock{} skb := &SubdirectoryKeyBlock{}
skb.FromBlock(b1) err := skb.FromBlock(b1)
if err != nil {
t.Fatal(err)
}
b2, err := skb.ToBlock() b2, err := skb.ToBlock()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -66,7 +81,10 @@ func TestSubdirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; ")) t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; "))
} }
skb2 := &SubdirectoryKeyBlock{} skb2 := &SubdirectoryKeyBlock{}
skb2.FromBlock(b2) err = skb2.FromBlock(b2)
if err != nil {
t.Fatal(err)
}
if *skb != *skb2 { if *skb != *skb2 {
t.Errorf("Structs differ: %v != %v", skb, skb2) t.Errorf("Structs differ: %v != %v", skb, skb2)
} }
@ -76,7 +94,10 @@ func TestSubdirectoryKeyBlockMarshalRoundtrip(t *testing.T) {
func TestSubdirectoryBlockMarshalRoundtrip(t *testing.T) { func TestSubdirectoryBlockMarshalRoundtrip(t *testing.T) {
b1 := randomBlock() b1 := randomBlock()
sb := &SubdirectoryBlock{} sb := &SubdirectoryBlock{}
sb.FromBlock(b1) err := sb.FromBlock(b1)
if err != nil {
t.Fatal(err)
}
b2, err := sb.ToBlock() b2, err := sb.ToBlock()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -85,7 +106,10 @@ func TestSubdirectoryBlockMarshalRoundtrip(t *testing.T) {
t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; ")) t.Fatalf("Blocks differ: %s", strings.Join(pretty.Diff(b1[:], b2[:]), "; "))
} }
sb2 := &SubdirectoryBlock{} sb2 := &SubdirectoryBlock{}
sb2.FromBlock(b2) err = sb2.FromBlock(b2)
if err != nil {
t.Fatal(err)
}
if *sb != *sb2 { if *sb != *sb2 {
t.Errorf("Structs differ: %v != %v", sb, sb2) t.Errorf("Structs differ: %v != %v", sb, sb2)
} }

View File

@ -61,7 +61,7 @@ func (sm SectorMap) FirstFreeFile() byte {
return 0 return 0
} }
// Persist writes the current contenst of a sector map back back to // Persist writes the current contents of a sector map back back to
// disk. // disk.
func (sm SectorMap) Persist(diskbytes []byte) error { func (sm SectorMap) Persist(diskbytes []byte) error {
sector09, err := disk.ReadSector(diskbytes, 0, 9) sector09, err := disk.ReadSector(diskbytes, 0, 9)

View File

@ -129,8 +129,6 @@ func (d *decoder) parseChunk() (done bool, err error) {
default: default:
return false, d.parseUnknown(string(d.tmp[:4]), length) return false, d.parseUnknown(string(d.tmp[:4]), length)
} }
return false, nil
} }
func (d *decoder) parseINFO(length uint32) error { func (d *decoder) parseINFO(length uint32) error {