PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/forge/v1

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v1
Namespace
moul / forge
Files
18 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/forge/v1
gno
0.9

Files (18)

  • README.mdmarkdown
  • gnomod.tomltoml
  • change.gnogno
  • errors.gnogno
  • forge.gnogno
  • issue.gnogno
  • pkg.gnogno
  • ref.gnogno
  • release.gnogno
  • validate.gnogno
  • change_test.gnogno
  • forge_test.gnogno
  • helpers_test.gnogno
  • issue_test.gnogno
  • pkg_test.gnogno
  • ref_test.gnogno
  • release_test.gnogno
  • validate_test.gnogno
  • pkg_test.gnogno
    1package forge23import (4	"testing"56	"gno.land/p/nt/uassert/v0"7	"gno.land/p/nt/urequire/v0"8

    Functions

    not supported for pure packages by the node (vm/qfuncs)

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    )
    9
    10func TestValidPkgPath(t *testing.T) {
    11 cases := []struct {
    12 name string
    13 path string
    14 want bool
    15 }{
    16 {"a realm", "gno.land/r/moul/home", true},
    17 {"a pure package", "gno.land/p/moul/forge/v1", true},
    18 {"deep", "gno.land/r/moul/x/daily/asciiart/v0", true},
    19 {"an address namespace", "gno.land/r/g1abc/thing", true},
    20 {"underscores and dashes", "gno.land/r/ns/a-b_c", true},
    21 // Shape only. A realm cannot ask the chain whether a path is deployed,
    22 // so anything stricter would be a check that only sometimes works.
    23 {"not deployed but well formed", "gno.land/r/nobody/nothing", true},
    24 {"empty", "", false},
    25 {"two parts", "gno.land/r", false},
    26 {"a traversal", "gno.land/r/../etc", false},
    27 {"trailing slash", "gno.land/r/moul/home/", false},
    28 {"an empty element", "gno.land//r/moul", false},
    29 {"a space", "gno.land/r/moul/my home", false},
    30 {"a colon", "gno.land/r/moul/home:tab", false},
    31 }
    32 for _, tc := range cases {
    33 t.Run(tc.name, func(t *testing.T) {
    34 uassert.Equal(t, tc.want, ValidPkgPath(tc.path))
    35 })
    36 }
    37}
    38
    39func TestPublishPackageIndexesForgeWide(t *testing.T) {
    40 f, r := newRepo(t)
    41
    42 p, err := f.PublishPackage(carol, 200, r.ID, "gno.land/r/moul/home", "refs/heads/main", oid("a"), "")
    43 urequire.NoError(t, err)
    44 uassert.Equal(t, "gno.land/r/moul/home", p.Path)
    45 uassert.Equal(t, r.ID, p.RepoID)
    46 uassert.Equal(t, int64(200), p.PublishedAt)
    47
    48 // The lookup an explorer makes: it starts from the path and does not know
    49 // the repo yet, which is the whole reason the index is forge-wide.
    50 uassert.Equal(t, r.ID, f.PackageRepo("gno.land/r/moul/home"))
    51 uassert.Equal(t, "", f.PackageRepo("gno.land/r/someone/else"))
    52 uassert.Equal(t, 1, f.PackageCount())
    53 uassert.Equal(t, 1, r.PackageCount())
    54}
    55
    56// One repo publishes many paths: gno-contracts publishes 193.
    57func TestPublishManyPackages(t *testing.T) {
    58 f, r := newRepo(t)
    59
    60 paths := []string{
    61 "gno.land/r/moul/home",
    62 "gno.land/p/moul/forge/v1",
    63 "gno.land/r/moul/blog",
    64 }
    65 for _, path := range paths {
    66 _, err := f.PublishPackage(alice, 200, r.ID, path, "", "", "")
    67 urequire.NoError(t, err)
    68 }
    69 uassert.Equal(t, 3, r.PackageCount())
    70
    71 var seen []string
    72 r.IteratePackages(0, 0, func(p *Package) bool {
    73 seen = append(seen, p.Path)
    74 return false
    75 })
    76 // Path order, which is what the tree gives and what a file list wants.
    77 urequire.Equal(t, 3, len(seen))
    78 uassert.Equal(t, "gno.land/p/moul/forge/v1", seen[0])
    79 uassert.Equal(t, "gno.land/r/moul/blog", seen[1])
    80 uassert.Equal(t, "gno.land/r/moul/home", seen[2])
    81}
    82
    83// Re-publishing the same path from the same repo is a redeploy, and overwrites.
    84func TestRepublishOverwrites(t *testing.T) {
    85 f, r := newRepo(t)
    86
    87 _, err := f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", oid("a"), "v1.0.0")
    88 urequire.NoError(t, err)
    89 _, err = f.PublishPackage(alice, 300, r.ID, "gno.land/r/moul/home", "", oid("b"), "v1.1.0")
    90 urequire.NoError(t, err)
    91
    92 uassert.Equal(t, 1, f.PackageCount())
    93 got := f.PackageAt("gno.land/r/moul/home")
    94 urequire.True(t, got != nil)
    95 uassert.Equal(t, oid("b"), got.OID)
    96 uassert.Equal(t, "v1.1.0", got.Tag)
    97 uassert.Equal(t, int64(300), got.PublishedAt)
    98}
    99
    100// Silently moving a claimed path would let any repo owner capture another
    101// project's package in every explorer that reads this index.
    102func TestPublishRefusesAnotherReposPath(t *testing.T) {
    103 f, r := newRepo(t)
    104 _, err := f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "", "")
    105 urequire.NoError(t, err)
    106
    107 other, err := f.CreateRepo(eve, 210, "eve/squat", "", "")
    108 urequire.NoError(t, err)
    109
    110 _, err = f.PublishPackage(eve, 220, other.ID, "gno.land/r/moul/home", "", "", "")
    111 uassert.ErrorIs(t, err, ErrPackageClaimed)
    112 uassert.Equal(t, r.ID, f.PackageRepo("gno.land/r/moul/home"))
    113}
    114
    115func TestPublishAuthorityAndValidation(t *testing.T) {
    116 f, r := newRepo(t)
    117
    118 // dave is a reader, eve is nothing: neither may publish.
    119 _, err := f.PublishPackage(dave, 200, r.ID, "gno.land/r/moul/home", "", "", "")
    120 uassert.ErrorIs(t, err, ErrUnauthorized)
    121 _, err = f.PublishPackage(eve, 200, r.ID, "gno.land/r/moul/home", "", "", "")
    122 uassert.ErrorIs(t, err, ErrUnauthorized)
    123
    124 _, err = f.PublishPackage(alice, 200, "nobody/nothing", "gno.land/r/x/y", "", "", "")
    125 uassert.ErrorIs(t, err, ErrRepoNotFound)
    126
    127 _, err = f.PublishPackage(alice, 200, r.ID, "not a path", "", "", "")
    128 uassert.ErrorIs(t, err, ErrInvalidPkgPath)
    129
    130 _, err = f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "main", "", "")
    131 uassert.ErrorIs(t, err, ErrInvalidRefName)
    132
    133 _, err = f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "nothex", "")
    134 uassert.ErrorIs(t, err, ErrInvalidOID)
    135
    136 urequire.NoError(t, r.SetArchived(alice, true))
    137 _, err = f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "", "")
    138 uassert.ErrorIs(t, err, ErrRepoArchived)
    139}
    140
    141func TestUnpublishClearsBothHalvesOfTheIndex(t *testing.T) {
    142 f, r := newRepo(t)
    143 _, err := f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "", "")
    144 urequire.NoError(t, err)
    145
    146 uassert.ErrorIs(t, f.UnpublishPackage(dave, r.ID, "gno.land/r/moul/home"), ErrUnauthorized)
    147 uassert.ErrorIs(t, f.UnpublishPackage(alice, r.ID, "gno.land/r/nothing"), ErrPackageNotFound)
    148
    149 urequire.NoError(t, f.UnpublishPackage(alice, r.ID, "gno.land/r/moul/home"))
    150 uassert.Equal(t, 0, f.PackageCount())
    151 uassert.Equal(t, 0, r.PackageCount())
    152 uassert.Equal(t, "", f.PackageRepo("gno.land/r/moul/home"))
    153}
    154
    155// A fork is not a publisher of its parent's paths.
    156func TestForkInheritsNoPackages(t *testing.T) {
    157 f, r := newRepo(t)
    158 _, err := f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "", "")
    159 urequire.NoError(t, err)
    160
    161 child, err := f.Fork(eve, 210, r.ID, "eve/forge")
    162 urequire.NoError(t, err)
    163 uassert.Equal(t, 0, child.PackageCount())
    164 uassert.Equal(t, r.ID, f.PackageRepo("gno.land/r/moul/home"))
    165}
    166