diff --git a/main.go b/main.go index e028382..1884cf8 100644 --- a/main.go +++ b/main.go @@ -2,11 +2,13 @@ package main import ( "context" + "flag" "fmt" "log" "os" "slices" "sort" + "strconv" "strings" "sync" "time" @@ -34,6 +36,12 @@ type VersionPath struct { Version string } +var userIdFlag = flag.String("user-id", "", "The Matrix user ID to use. (EnvVar: MRVC_USER_ID)") +var tokenFlag = flag.String("token", "", "The Matrix access token to use. (EnvVar: MRVC_TOKEN)") +var roomFlag = flag.String("room", "", "The Matrix room to check. (EnvVar: MRVC_ROOM)") +var printHomeserverMemberCountFlag = flag.Bool("print-homeserver-member-count", false, "Print the member count for each homeserver. (EnvVar: MRVC_PRINT_HOMESERVER_MEMBER_COUNT)") +var homeserverVersionInfoTimeoutFlag = flag.Duration("homeserver-version-info-timeout", time.Second*5, "Timeout for getting the homeservers version information per homeserver. (EnvVar: MRVC_HOMESERVER_VERSION_INFO_TIMEOUT)") + var unknownServerVersionInfo = fclient.Version{ Server: struct { Name string `json:"name"` @@ -281,11 +289,68 @@ func compareVersionStrings(a, b string) int { } func main() { - userIdString := os.Getenv("MATRIX_USER_ID") - token := os.Getenv("MATRIX_TOKEN") - room := os.Getenv("MATRIX_ROOM") - verbose := false - timeoutSeconds := 5 + flag.Parse() + + // Configuration variables. + var userIdString, token, room string + var printHomeserverMemberCount bool + var homeserverVersionInfoTimeout time.Duration + + visitedFlags := make(map[string]bool) + flag.Visit(func(visitedFlag *flag.Flag) { + visitedFlags[visitedFlag.Name] = true + }) + + // Assign flag and environment variable values to configuration variables. + // Flags take precedence over environment variables. + // This also ensures some configuration options got explicitly set. + if visitedFlags["user-id"] { + userIdString = *userIdFlag + } else if userIdEnvVar, ok := os.LookupEnv("MRVC_USER_ID"); ok { + userIdString = userIdEnvVar + } else { + log.Fatal("A Matrix user ID must be provided.") + } + if visitedFlags["token"] { + token = *tokenFlag + } else if tokenEnvVar, ok := os.LookupEnv("MRVC_TOKEN"); ok { + token = tokenEnvVar + } else { + log.Fatal("A Matrix access token must be provided.") + } + if visitedFlags["room"] { + room = *roomFlag + } else if roomEnvVar, ok := os.LookupEnv("MRVC_ROOM"); ok { + room = roomEnvVar + } else { + log.Fatal("A Matrix room must be provided.") + } + if visitedFlags["print-homeserver-member-count"] { + printHomeserverMemberCount = *printHomeserverMemberCountFlag + } else if printHomeserverMemberCountEnvVar, ok := os.LookupEnv("MRVC_PRINT_HOMESERVER_MEMBER_COUNT"); ok { + parsedPrintHomeserverMemberCountEnvVar, err := strconv.ParseBool(printHomeserverMemberCountEnvVar) + if err != nil { + log.Println("Error parsing MRVC_PRINT_HOMESERVER_MEMBER_COUNT:") + log.Fatal(err) + } + printHomeserverMemberCount = parsedPrintHomeserverMemberCountEnvVar + } else { + // The flag holds the default value. + printHomeserverMemberCount = *printHomeserverMemberCountFlag + } + if visitedFlags["homeserver-version-info-timeout"] { + homeserverVersionInfoTimeout = *homeserverVersionInfoTimeoutFlag + } else if homeserverVersionInfoTimeoutEnvVar, ok := os.LookupEnv("MRVC_HOMESERVER_VERSION_INFO_TIMEOUT"); ok { + parsedHomeserverVersionInfoTimeoutEnvVar, err := time.ParseDuration(homeserverVersionInfoTimeoutEnvVar) + if err != nil { + log.Println("Error parsing MRVC_HOMESERVER_VERSION_INFO_TIMEOUT:") + log.Fatal(err) + } + homeserverVersionInfoTimeout = parsedHomeserverVersionInfoTimeoutEnvVar + } else { + // The flag holds the default value. + homeserverVersionInfoTimeout = *homeserverVersionInfoTimeoutFlag + } userId := id.UserID(userIdString) _, homeserver, err := userId.ParseAndValidate() @@ -302,7 +367,7 @@ func main() { } federationClient := fclient.NewClient( fclient.WithWellKnownSRVLookups(true), - fclient.WithTimeout(time.Second*time.Duration(timeoutSeconds)), + fclient.WithTimeout(homeserverVersionInfoTimeout), ) joinedMembers, err := client.JoinedMembers(context.Background(), id.RoomID(room)) @@ -393,7 +458,7 @@ func main() { fmt.Printf(" %s -> %d\n", versionKey, membersByVersionPath[VersionPath{maxRoomVersionKey, serverKey, versionKey}]) - if verbose { + if printHomeserverMemberCount { homeserverKeys := make([]string, 0, len(versionValue)) for key := range versionValue { homeserverKeys = append(homeserverKeys, key)