Skip to content

Commit b8ebb94

Browse files
committed
on home page, show (with title) which apparent mirrors are not listed, and in dashboard mark module paths that won't match due to being on the skip list
for issue #22
1 parent af87f71 commit b8ebb94

File tree

5 files changed

+55
-23
lines changed

5 files changed

+55
-23
lines changed

api.go

+20-15
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,7 @@ type Overview struct {
748748
UpdatesUnsubscribed bool
749749
Backoff string
750750
BackoffUntil time.Time
751+
SkipModulePaths []string
751752

752753
Subscriptions []Subscription
753754
ModuleUpdates []ModuleUpdateURLs
@@ -765,6 +766,8 @@ type ModuleUpdateURLs struct {
765766
func (API) Overview(ctx context.Context) (overview Overview) {
766767
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
767768

769+
overview.SkipModulePaths = config.SkipModulePaths
770+
768771
err := database.Read(ctx, func(tx *bstore.Tx) error {
769772
u := User{ID: reqInfo.UserID}
770773
err := tx.Get(&u)
@@ -978,16 +981,17 @@ type Recent struct {
978981
}
979982

980983
type Home struct {
981-
Version string
982-
GoVersion string
983-
GoOS string
984-
GoArch string
985-
ServiceName string
986-
AdminName string
987-
AdminEmail string
988-
Note string
989-
SignupNote string
990-
Recents []Recent
984+
Version string
985+
GoVersion string
986+
GoOS string
987+
GoArch string
988+
ServiceName string
989+
AdminName string
990+
AdminEmail string
991+
Note string
992+
SignupNote string
993+
SkipModulePrefixes []string
994+
Recents []Recent
991995
}
992996

993997
func _recents(ctx context.Context, n int) (recents []Recent) {
@@ -1011,11 +1015,12 @@ func _recents(ctx context.Context, n int) (recents []Recent) {
10111015
// Home returns data for the home page.
10121016
func (API) Home(ctx context.Context) (home Home) {
10131017
home = Home{
1014-
Version: version,
1015-
GoVersion: runtime.Version(),
1016-
GoOS: runtime.GOOS,
1017-
GoArch: runtime.GOARCH,
1018-
ServiceName: config.ServiceName,
1018+
Version: version,
1019+
GoVersion: runtime.Version(),
1020+
GoOS: runtime.GOOS,
1021+
GoArch: runtime.GOARCH,
1022+
ServiceName: config.ServiceName,
1023+
SkipModulePrefixes: config.SkipModulePrefixes,
10191024
}
10201025

10211026
home.Recents = _recents(ctx, 15)

api.json

+16
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,14 @@
437437
"timestamp"
438438
]
439439
},
440+
{
441+
"Name": "SkipModulePaths",
442+
"Docs": "",
443+
"Typewords": [
444+
"[]",
445+
"string"
446+
]
447+
},
440448
{
441449
"Name": "Subscriptions",
442450
"Docs": "",
@@ -757,6 +765,14 @@
757765
"string"
758766
]
759767
},
768+
{
769+
"Name": "SkipModulePrefixes",
770+
"Docs": "",
771+
"Typewords": [
772+
"[]",
773+
"string"
774+
]
775+
},
760776
{
761777
"Name": "Recents",
762778
"Docs": "",

api.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface Overview {
99
UpdatesUnsubscribed: boolean
1010
Backoff: string
1111
BackoffUntil: Date
12+
SkipModulePaths?: string[] | null
1213
Subscriptions?: Subscription[] | null
1314
ModuleUpdates?: ModuleUpdateURLs[] | null
1415
UserLogs?: UserLog[] | null
@@ -67,6 +68,7 @@ export interface Home {
6768
AdminEmail: string
6869
Note: string
6970
SignupNote: string
71+
SkipModulePrefixes?: string[] | null
7072
Recents?: Recent[] | null
7173
}
7274

@@ -91,12 +93,12 @@ export const structTypes: {[typename: string]: boolean} = {"Home":true,"ModuleUp
9193
export const stringsTypes: {[typename: string]: boolean} = {"Interval":true}
9294
export const intsTypes: {[typename: string]: boolean} = {}
9395
export const types: TypenameMap = {
94-
"Overview": {"Name":"Overview","Docs":"","Fields":[{"Name":"Email","Docs":"","Typewords":["string"]},{"Name":"UpdateInterval","Docs":"","Typewords":["Interval"]},{"Name":"MetaUnsubscribed","Docs":"","Typewords":["bool"]},{"Name":"UpdatesUnsubscribed","Docs":"","Typewords":["bool"]},{"Name":"Backoff","Docs":"","Typewords":["string"]},{"Name":"BackoffUntil","Docs":"","Typewords":["timestamp"]},{"Name":"Subscriptions","Docs":"","Typewords":["[]","Subscription"]},{"Name":"ModuleUpdates","Docs":"","Typewords":["[]","ModuleUpdateURLs"]},{"Name":"UserLogs","Docs":"","Typewords":["[]","UserLog"]}]},
96+
"Overview": {"Name":"Overview","Docs":"","Fields":[{"Name":"Email","Docs":"","Typewords":["string"]},{"Name":"UpdateInterval","Docs":"","Typewords":["Interval"]},{"Name":"MetaUnsubscribed","Docs":"","Typewords":["bool"]},{"Name":"UpdatesUnsubscribed","Docs":"","Typewords":["bool"]},{"Name":"Backoff","Docs":"","Typewords":["string"]},{"Name":"BackoffUntil","Docs":"","Typewords":["timestamp"]},{"Name":"SkipModulePaths","Docs":"","Typewords":["[]","string"]},{"Name":"Subscriptions","Docs":"","Typewords":["[]","Subscription"]},{"Name":"ModuleUpdates","Docs":"","Typewords":["[]","ModuleUpdateURLs"]},{"Name":"UserLogs","Docs":"","Typewords":["[]","UserLog"]}]},
9597
"Subscription": {"Name":"Subscription","Docs":"","Fields":[{"Name":"ID","Docs":"","Typewords":["int64"]},{"Name":"Module","Docs":"","Typewords":["string"]},{"Name":"BelowModule","Docs":"","Typewords":["bool"]},{"Name":"OlderVersions","Docs":"","Typewords":["bool"]},{"Name":"Prerelease","Docs":"","Typewords":["bool"]},{"Name":"Pseudo","Docs":"","Typewords":["bool"]},{"Name":"Comment","Docs":"","Typewords":["string"]}]},
9698
"ModuleUpdateURLs": {"Name":"ModuleUpdateURLs","Docs":"","Fields":[{"Name":"ID","Docs":"","Typewords":["int64"]},{"Name":"UserID","Docs":"","Typewords":["int64"]},{"Name":"SubscriptionID","Docs":"","Typewords":["int64"]},{"Name":"LogRecordID","Docs":"","Typewords":["int64"]},{"Name":"Discovered","Docs":"","Typewords":["timestamp"]},{"Name":"Module","Docs":"","Typewords":["string"]},{"Name":"Version","Docs":"","Typewords":["string"]},{"Name":"MessageID","Docs":"","Typewords":["int64"]},{"Name":"RepoURL","Docs":"","Typewords":["string"]},{"Name":"TagURL","Docs":"","Typewords":["string"]},{"Name":"DocURL","Docs":"","Typewords":["string"]}]},
9799
"UserLog": {"Name":"UserLog","Docs":"","Fields":[{"Name":"ID","Docs":"","Typewords":["int64"]},{"Name":"UserID","Docs":"","Typewords":["int64"]},{"Name":"Time","Docs":"","Typewords":["timestamp"]},{"Name":"Text","Docs":"","Typewords":["string"]}]},
98100
"SubscriptionImport": {"Name":"SubscriptionImport","Docs":"","Fields":[{"Name":"GoMod","Docs":"","Typewords":["string"]},{"Name":"BelowModule","Docs":"","Typewords":["bool"]},{"Name":"OlderVersions","Docs":"","Typewords":["bool"]},{"Name":"Prerelease","Docs":"","Typewords":["bool"]},{"Name":"Pseudo","Docs":"","Typewords":["bool"]},{"Name":"Comment","Docs":"","Typewords":["string"]},{"Name":"Indirect","Docs":"","Typewords":["bool"]}]},
99-
"Home": {"Name":"Home","Docs":"","Fields":[{"Name":"Version","Docs":"","Typewords":["string"]},{"Name":"GoVersion","Docs":"","Typewords":["string"]},{"Name":"GoOS","Docs":"","Typewords":["string"]},{"Name":"GoArch","Docs":"","Typewords":["string"]},{"Name":"ServiceName","Docs":"","Typewords":["string"]},{"Name":"AdminName","Docs":"","Typewords":["string"]},{"Name":"AdminEmail","Docs":"","Typewords":["string"]},{"Name":"Note","Docs":"","Typewords":["string"]},{"Name":"SignupNote","Docs":"","Typewords":["string"]},{"Name":"Recents","Docs":"","Typewords":["[]","Recent"]}]},
101+
"Home": {"Name":"Home","Docs":"","Fields":[{"Name":"Version","Docs":"","Typewords":["string"]},{"Name":"GoVersion","Docs":"","Typewords":["string"]},{"Name":"GoOS","Docs":"","Typewords":["string"]},{"Name":"GoArch","Docs":"","Typewords":["string"]},{"Name":"ServiceName","Docs":"","Typewords":["string"]},{"Name":"AdminName","Docs":"","Typewords":["string"]},{"Name":"AdminEmail","Docs":"","Typewords":["string"]},{"Name":"Note","Docs":"","Typewords":["string"]},{"Name":"SignupNote","Docs":"","Typewords":["string"]},{"Name":"SkipModulePrefixes","Docs":"","Typewords":["[]","string"]},{"Name":"Recents","Docs":"","Typewords":["[]","Recent"]}]},
100102
"Recent": {"Name":"Recent","Docs":"","Fields":[{"Name":"Module","Docs":"","Typewords":["string"]},{"Name":"Version","Docs":"","Typewords":["string"]},{"Name":"Discovered","Docs":"","Typewords":["timestamp"]},{"Name":"RepoURL","Docs":"","Typewords":["string"]},{"Name":"TagURL","Docs":"","Typewords":["string"]},{"Name":"DocURL","Docs":"","Typewords":["string"]}]},
101103
"Interval": {"Name":"Interval","Docs":"","Values":[{"Name":"IntervalImmediate","Value":"immediate","Docs":""},{"Name":"IntervalHour","Value":"hour","Docs":""},{"Name":"IntervalDay","Value":"day","Docs":""},{"Name":"IntervalWeek","Value":"week","Docs":""}]},
102104
}

index.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ var api;
1414
api.stringsTypes = { "Interval": true };
1515
api.intsTypes = {};
1616
api.types = {
17-
"Overview": { "Name": "Overview", "Docs": "", "Fields": [{ "Name": "Email", "Docs": "", "Typewords": ["string"] }, { "Name": "UpdateInterval", "Docs": "", "Typewords": ["Interval"] }, { "Name": "MetaUnsubscribed", "Docs": "", "Typewords": ["bool"] }, { "Name": "UpdatesUnsubscribed", "Docs": "", "Typewords": ["bool"] }, { "Name": "Backoff", "Docs": "", "Typewords": ["string"] }, { "Name": "BackoffUntil", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "Subscriptions", "Docs": "", "Typewords": ["[]", "Subscription"] }, { "Name": "ModuleUpdates", "Docs": "", "Typewords": ["[]", "ModuleUpdateURLs"] }, { "Name": "UserLogs", "Docs": "", "Typewords": ["[]", "UserLog"] }] },
17+
"Overview": { "Name": "Overview", "Docs": "", "Fields": [{ "Name": "Email", "Docs": "", "Typewords": ["string"] }, { "Name": "UpdateInterval", "Docs": "", "Typewords": ["Interval"] }, { "Name": "MetaUnsubscribed", "Docs": "", "Typewords": ["bool"] }, { "Name": "UpdatesUnsubscribed", "Docs": "", "Typewords": ["bool"] }, { "Name": "Backoff", "Docs": "", "Typewords": ["string"] }, { "Name": "BackoffUntil", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "SkipModulePaths", "Docs": "", "Typewords": ["[]", "string"] }, { "Name": "Subscriptions", "Docs": "", "Typewords": ["[]", "Subscription"] }, { "Name": "ModuleUpdates", "Docs": "", "Typewords": ["[]", "ModuleUpdateURLs"] }, { "Name": "UserLogs", "Docs": "", "Typewords": ["[]", "UserLog"] }] },
1818
"Subscription": { "Name": "Subscription", "Docs": "", "Fields": [{ "Name": "ID", "Docs": "", "Typewords": ["int64"] }, { "Name": "Module", "Docs": "", "Typewords": ["string"] }, { "Name": "BelowModule", "Docs": "", "Typewords": ["bool"] }, { "Name": "OlderVersions", "Docs": "", "Typewords": ["bool"] }, { "Name": "Prerelease", "Docs": "", "Typewords": ["bool"] }, { "Name": "Pseudo", "Docs": "", "Typewords": ["bool"] }, { "Name": "Comment", "Docs": "", "Typewords": ["string"] }] },
1919
"ModuleUpdateURLs": { "Name": "ModuleUpdateURLs", "Docs": "", "Fields": [{ "Name": "ID", "Docs": "", "Typewords": ["int64"] }, { "Name": "UserID", "Docs": "", "Typewords": ["int64"] }, { "Name": "SubscriptionID", "Docs": "", "Typewords": ["int64"] }, { "Name": "LogRecordID", "Docs": "", "Typewords": ["int64"] }, { "Name": "Discovered", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "Module", "Docs": "", "Typewords": ["string"] }, { "Name": "Version", "Docs": "", "Typewords": ["string"] }, { "Name": "MessageID", "Docs": "", "Typewords": ["int64"] }, { "Name": "RepoURL", "Docs": "", "Typewords": ["string"] }, { "Name": "TagURL", "Docs": "", "Typewords": ["string"] }, { "Name": "DocURL", "Docs": "", "Typewords": ["string"] }] },
2020
"UserLog": { "Name": "UserLog", "Docs": "", "Fields": [{ "Name": "ID", "Docs": "", "Typewords": ["int64"] }, { "Name": "UserID", "Docs": "", "Typewords": ["int64"] }, { "Name": "Time", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "Text", "Docs": "", "Typewords": ["string"] }] },
2121
"SubscriptionImport": { "Name": "SubscriptionImport", "Docs": "", "Fields": [{ "Name": "GoMod", "Docs": "", "Typewords": ["string"] }, { "Name": "BelowModule", "Docs": "", "Typewords": ["bool"] }, { "Name": "OlderVersions", "Docs": "", "Typewords": ["bool"] }, { "Name": "Prerelease", "Docs": "", "Typewords": ["bool"] }, { "Name": "Pseudo", "Docs": "", "Typewords": ["bool"] }, { "Name": "Comment", "Docs": "", "Typewords": ["string"] }, { "Name": "Indirect", "Docs": "", "Typewords": ["bool"] }] },
22-
"Home": { "Name": "Home", "Docs": "", "Fields": [{ "Name": "Version", "Docs": "", "Typewords": ["string"] }, { "Name": "GoVersion", "Docs": "", "Typewords": ["string"] }, { "Name": "GoOS", "Docs": "", "Typewords": ["string"] }, { "Name": "GoArch", "Docs": "", "Typewords": ["string"] }, { "Name": "ServiceName", "Docs": "", "Typewords": ["string"] }, { "Name": "AdminName", "Docs": "", "Typewords": ["string"] }, { "Name": "AdminEmail", "Docs": "", "Typewords": ["string"] }, { "Name": "Note", "Docs": "", "Typewords": ["string"] }, { "Name": "SignupNote", "Docs": "", "Typewords": ["string"] }, { "Name": "Recents", "Docs": "", "Typewords": ["[]", "Recent"] }] },
22+
"Home": { "Name": "Home", "Docs": "", "Fields": [{ "Name": "Version", "Docs": "", "Typewords": ["string"] }, { "Name": "GoVersion", "Docs": "", "Typewords": ["string"] }, { "Name": "GoOS", "Docs": "", "Typewords": ["string"] }, { "Name": "GoArch", "Docs": "", "Typewords": ["string"] }, { "Name": "ServiceName", "Docs": "", "Typewords": ["string"] }, { "Name": "AdminName", "Docs": "", "Typewords": ["string"] }, { "Name": "AdminEmail", "Docs": "", "Typewords": ["string"] }, { "Name": "Note", "Docs": "", "Typewords": ["string"] }, { "Name": "SignupNote", "Docs": "", "Typewords": ["string"] }, { "Name": "SkipModulePrefixes", "Docs": "", "Typewords": ["[]", "string"] }, { "Name": "Recents", "Docs": "", "Typewords": ["[]", "Recent"] }] },
2323
"Recent": { "Name": "Recent", "Docs": "", "Fields": [{ "Name": "Module", "Docs": "", "Typewords": ["string"] }, { "Name": "Version", "Docs": "", "Typewords": ["string"] }, { "Name": "Discovered", "Docs": "", "Typewords": ["timestamp"] }, { "Name": "RepoURL", "Docs": "", "Typewords": ["string"] }, { "Name": "TagURL", "Docs": "", "Typewords": ["string"] }, { "Name": "DocURL", "Docs": "", "Typewords": ["string"] }] },
2424
"Interval": { "Name": "Interval", "Docs": "", "Values": [{ "Name": "IntervalImmediate", "Value": "immediate", "Docs": "" }, { "Name": "IntervalHour", "Value": "hour", "Docs": "" }, { "Name": "IntervalDay", "Value": "day", "Docs": "" }, { "Name": "IntervalWeek", "Value": "week", "Docs": "" }] },
2525
};
@@ -1023,7 +1023,10 @@ const overview = async () => {
10231023
let moduptbody;
10241024
const render = () => {
10251025
const nsubs = dom.tbody(subscriptions.length === 0 ? dom.tr(dom.td(attr.colspan('7'), 'No subscriptions yet, add the first one!')) : [], subscriptions.map(sub => {
1026-
const row = dom.tr(dom.td(sub.Module), dom.td(sub.BelowModule ? 'Yes' : 'No'), dom.td(sub.OlderVersions ? 'Yes' : 'No'), dom.td(sub.Prerelease ? 'Yes' : 'No'), dom.td(sub.Pseudo ? 'Yes' : 'No'), dom.td(style({ maxWidth: '40em' }), sub.Comment), dom.td(dom.clickbutton('Edit', function click() { subscriptionPopup(sub, subscriptions, render); }), ' ', dom.clickbutton('Remove', async function click(e) {
1026+
const row = dom.tr((overview.SkipModulePaths || []).includes(sub.Module) ? [
1027+
attr.title('Module will not match because it is on the list of skipped module paths:\n' + (overview.SkipModulePaths || []).join('\n')),
1028+
style({ color: '#888' })
1029+
] : [], dom.td(sub.Module), dom.td(sub.BelowModule ? 'Yes' : 'No'), dom.td(sub.OlderVersions ? 'Yes' : 'No'), dom.td(sub.Prerelease ? 'Yes' : 'No'), dom.td(sub.Pseudo ? 'Yes' : 'No'), dom.td(style({ maxWidth: '40em' }), sub.Comment), dom.td(dom.clickbutton('Edit', function click() { subscriptionPopup(sub, subscriptions, render); }), ' ', dom.clickbutton('Remove', async function click(e) {
10271030
if (!window.confirm('Are you sure?')) {
10281031
return;
10291032
}
@@ -1173,7 +1176,7 @@ const home = async () => {
11731176
})) : []);
11741177
};
11751178
renderRecents(home.Recents || [], true);
1176-
dom._kids(document.body, dom.div(dom._class('home'), dom._class('page'), dom.div(style({ textAlign: 'right' }), dom.a(attr.href('#overview'), 'Login')), dom.h1('GopherWatch'), dom.p('Keep tabs on Go modules.'), dom.p('Subscribe to Go module paths and receive an email when a new module/version is published through the Go module proxy.'), dom.h2('How does it work?'), dom.p('In Go, you use ', dom.span('"go get"', attr.title('Or related commands, such as "go install", "go mod tidy" and more')), ' to download Go modules to use as a dependency. Looking up a module is done through the ', dom.a(attr.href('https://sum.golang.org'), attr.rel('noopener'), 'Go checksum database'), ': A ', dom.a(attr.href('https://research.swtch.com/tlog'), attr.rel('noopener'), 'transparency log'), ' that proves it is not tampered with, providing high assurance that you get the correct code. It is an append-only public log of all unique Go modules/versions ever requested through "go get". It is just like certificate transparency logs for TLS certificates.'), dom.p('GopherWatch follows the modules/versions appended to the Go sum database. You can subscribe to modules. GopherWatch sends you an email whenever a new matching module/version appears in the append-only log.'), dom.h2('Recent modules'), dom.p(dom.span('Prerelease versions ', attr.title('semver version with a dash, such as v1.2.3-20060102150405-652ceb448533')), ' and apparent mirrors not shown.'), dom.table(dom._class('recents'), dom._class('mono'), dom.thead(dom.tr(dom.th('Module', attr.title('Repo URLs are guesses and may be wrong.')), dom.th('Version', attr.title('Tag URLs are guesses and may be wrong.')), dom.th('Age'), dom.th('Docs', attr.title('Doc URLs are guesses and may be wrong.')))), recentsElem), dom.br(), dom.h2('Get started'), dom.p(dom.clickbutton('Create account', function click() {
1179+
dom._kids(document.body, dom.div(dom._class('home'), dom._class('page'), dom.div(style({ textAlign: 'right' }), dom.a(attr.href('#overview'), 'Login')), dom.h1('GopherWatch'), dom.p('Keep tabs on Go modules.'), dom.p('Subscribe to Go module paths and receive an email when a new module/version is published through the Go module proxy.'), dom.h2('How does it work?'), dom.p('In Go, you use ', dom.span('"go get"', attr.title('Or related commands, such as "go install", "go mod tidy" and more')), ' to download Go modules to use as a dependency. Looking up a module is done through the ', dom.a(attr.href('https://sum.golang.org'), attr.rel('noopener'), 'Go checksum database'), ': A ', dom.a(attr.href('https://research.swtch.com/tlog'), attr.rel('noopener'), 'transparency log'), ' that proves it is not tampered with, providing high assurance that you get the correct code. It is an append-only public log of all unique Go modules/versions ever requested through "go get". It is just like certificate transparency logs for TLS certificates.'), dom.p('GopherWatch follows the modules/versions appended to the Go sum database. You can subscribe to modules. GopherWatch sends you an email whenever a new matching module/version appears in the append-only log.'), dom.h2('Recent modules'), dom.p(dom.span('Prerelease versions ', attr.title('semver version with a dash, such as v1.2.3-20060102150405-652ceb448533')), ' and ', dom.span('apparent mirrors', attr.title((home.SkipModulePrefixes || []).join('\n'))), ' not shown.'), dom.table(dom._class('recents'), dom._class('mono'), dom.thead(dom.tr(dom.th('Module', attr.title('Repo URLs are guesses and may be wrong.')), dom.th('Version', attr.title('Tag URLs are guesses and may be wrong.')), dom.th('Age'), dom.th('Docs', attr.title('Doc URLs are guesses and may be wrong.')))), recentsElem), dom.br(), dom.h2('Get started'), dom.p(dom.clickbutton('Create account', function click() {
11771180
signup(home.SignupNote);
11781181
}), ' Do it.'), dom.h2('FAQ'), dom.dl(dom.dt(dom.h3("How does this compare to other mechanism to stay updated on modules?")), dom.dd(dom.p('You have several options for tracking dependencies for a Go project:'), dom.ul(dom.li('Just running "get get -u" to update dependencies to the latest versions.'), dom.li('You can find dependencies that really need to be upgraded with "govulncheck". It helpfully only mentions modules if you are using vulnerable code.'), dom.li('You could also "watch" a repository on e.g. github. But it\'ll be different for each "software forge". On github, it only works if "releases" are created. You cannot watch new tagged versions with the "watch" feature. Though you can watch tags using RSS. The point is, software forges are different, some do not help you.')), dom.br(), dom.p('GopherWatch works regardless of where the software is "hosted". GopherWatch can also notify repositories that match a module prefix, e.g. all modules/versions in an organization, perhaps your own.'), dom.p('GopherWatch can not report on a module if it is never requested through the Go module proxy.'), dom.p('GopherWatch does not currently watch the depedencies of modules you are subscribed to. That could be a good next step: Each time a module version is released, fetch the new go.mod and start monitoring dependencies for new versions. Patches welcome!'))), home.Note ? [
11791182
dom.h2('Notes'),

0 commit comments

Comments
 (0)