Переглянути джерело

chore: minor refactors based on static checks

- unchecked returns fixed (most)
- remove unused constants
- remove unsed structs
- function parameters unused or incorrectly used
- removed if else chains for error checks
- use regex MustCompile instead of compile
- spell checks
- preallocate slice cap when size known
- scope issues inside range
Rohan Verma 5 роки тому
батько
коміт
712ad2d517
15 змінених файлів з 67 додано та 49 видалено
  1. 1 1
      admin.go
  2. 7 4
      campaigns.go
  3. 0 3
      handlers.go
  4. 1 2
      install.go
  5. 7 3
      lists.go
  6. 24 10
      main.go
  7. 3 3
      manager/manager.go
  8. 3 4
      media.go
  9. 2 1
      messenger/emailer.go
  10. 1 1
      messenger/messenger.go
  11. 1 1
      public.go
  12. 2 2
      subimporter/importer.go
  13. 5 2
      subscribers.go
  14. 5 7
      templates.go
  15. 5 5
      utils.go

+ 1 - 1
admin.go

@@ -38,7 +38,7 @@ func handleGetConfigScript(c echo.Context) error {
 	)
 
 	b.Write([]byte(`var CONFIG = `))
-	j.Encode(out)
+	_ = j.Encode(out)
 	return c.Blob(http.StatusOK, "application/javascript", b.Bytes())
 }
 

+ 7 - 4
campaigns.go

@@ -85,9 +85,11 @@ func handleGetCampaigns(c echo.Context) error {
 	if err != nil {
 		return echo.NewHTTPError(http.StatusInternalServerError,
 			fmt.Sprintf("Error fetching campaigns: %s", pqErrMsg(err)))
-	} else if single && len(out.Results) == 0 {
+	}
+	if single && len(out.Results) == 0 {
 		return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.")
-	} else if len(out.Results) == 0 {
+	}
+	if len(out.Results) == 0 {
 		out.Results = make([]models.Campaign, 0)
 		return c.JSON(http.StatusOK, out)
 	}
@@ -492,7 +494,8 @@ func handleTestCampaign(c echo.Context) error {
 
 	// Send the test messages.
 	for _, s := range subs {
-		if err := sendTestMessage(&s, &camp, app); err != nil {
+		sub := s
+		if err := sendTestMessage(&sub, &camp, app); err != nil {
 			return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Error sending test: %v", err))
 		}
 	}
@@ -500,7 +503,7 @@ func handleTestCampaign(c echo.Context) error {
 	return c.JSON(http.StatusOK, okResp{true})
 }
 
-// sendTestMessage takes a campaign and a subsriber and sends out a sample campain message.
+// sendTestMessage takes a campaign and a subsriber and sends out a sample campaign message.
 func sendTestMessage(sub *models.Subscriber, camp *models.Campaign, app *App) error {
 	if err := camp.CompileTemplate(app.Manager.TemplateFuncs(camp)); err != nil {
 		return fmt.Errorf("Error compiling template: %v", err)

+ 0 - 3
handlers.go

@@ -13,9 +13,6 @@ const (
 	// stdInputMaxLen is the maximum allowed length for a standard input field.
 	stdInputMaxLen = 200
 
-	// bodyMaxLen is the maximum allowed length for e-mail bodies.
-	bodyMaxLen = 1000000
-
 	// defaultPerPage is the default number of results returned in an GET call.
 	defaultPerPage = 20
 

+ 1 - 2
install.go

@@ -141,6 +141,5 @@ func newConfigFile() error {
 		return fmt.Errorf("error reading sample config (is binary stuffed?): %v", err)
 	}
 
-	ioutil.WriteFile("config.toml", b, 0644)
-	return nil
+	return ioutil.WriteFile("config.toml", b, 0644)
 }

+ 7 - 3
lists.go

@@ -41,9 +41,11 @@ func handleGetLists(c echo.Context) error {
 	if err != nil {
 		return echo.NewHTTPError(http.StatusInternalServerError,
 			fmt.Sprintf("Error fetching lists: %s", pqErrMsg(err)))
-	} else if single && len(out.Results) == 0 {
+	}
+	if single && len(out.Results) == 0 {
 		return echo.NewHTTPError(http.StatusBadRequest, "List not found.")
-	} else if len(out.Results) == 0 {
+	}
+	if len(out.Results) == 0 {
 		return c.JSON(http.StatusOK, okResp{[]struct{}{}})
 	}
 
@@ -141,7 +143,9 @@ func handleDeleteLists(c echo.Context) error {
 	)
 
 	// Read the list IDs if they were sent in the body.
-	c.Bind(&ids)
+	if err := c.Bind(&ids); err != nil {
+		return err
+	}
 
 	if id < 1 && len(ids) == 0 {
 		return echo.NewHTTPError(http.StatusBadRequest, "Invalid ID.")

+ 24 - 10
main.go

@@ -84,7 +84,9 @@ func init() {
 	f.Bool("new-config", false, "Generate sample config file")
 
 	// Process flags.
-	f.Parse(os.Args[1:])
+	if err := f.Parse(os.Args[1:]); err != nil {
+		logger.Fatalf("error loading flags: %v", err)
+	}
 
 	// Display version.
 	if v, _ := f.GetBool("version"); v {
@@ -120,13 +122,15 @@ func init() {
 	}), nil); err != nil {
 		logger.Fatalf("error loading config from env: %v", err)
 	}
-	ko.Load(posflag.Provider(f, ".", ko), nil)
+	if err := ko.Load(posflag.Provider(f, ".", ko), nil); err != nil {
+		logger.Fatalf("error loading config: %v", err)
+	}
 }
 
 // initFileSystem initializes the stuffbin FileSystem to provide
 // access to bunded static assets to the app.
 func initFileSystem(binPath string) (stuffbin.FileSystem, error) {
-	fs, err := stuffbin.UnStuff(os.Args[0])
+	fs, err := stuffbin.UnStuff(binPath)
 	if err == nil {
 		return fs, nil
 	}
@@ -158,17 +162,23 @@ func initFileSystem(binPath string) (stuffbin.FileSystem, error) {
 // initMessengers initializes various messaging backends.
 func initMessengers(r *manager.Manager) messenger.Messenger {
 	// Load SMTP configurations for the default e-mail Messenger.
-	var srv []messenger.Server
-	for _, name := range ko.MapKeys("smtp") {
+	var (
+		mapKeys = ko.MapKeys("smtp")
+		srv     = make([]messenger.Server, 0, len(mapKeys))
+	)
+
+	for _, name := range mapKeys {
 		if !ko.Bool(fmt.Sprintf("smtp.%s.enabled", name)) {
 			logger.Printf("skipped SMTP: %s", name)
 			continue
 		}
 
 		var s messenger.Server
-		ko.Unmarshal("smtp."+name, &s)
+		if err := ko.Unmarshal("smtp."+name, &s); err != nil {
+			logger.Fatalf("error loading SMTP: %v", err)
+		}
 		s.Name = name
-		s.SendTimeout = s.SendTimeout * time.Millisecond
+		s.SendTimeout *= time.Millisecond
 		srv = append(srv, s)
 
 		logger.Printf("loaded SMTP: %s (%s@%s)", s.Name, s.Username, s.Host)
@@ -199,8 +209,12 @@ func main() {
 	defer db.Close()
 
 	var c constants
-	ko.Unmarshal("app", &c)
-	ko.Unmarshal("privacy", &c.Privacy)
+	if err := ko.Unmarshal("app", &c); err != nil {
+		log.Fatalf("error loading app config: %v", err)
+	}
+	if err := ko.Unmarshal("privacy", &c.Privacy); err != nil {
+		log.Fatalf("error loading app config: %v", err)
+	}
 	c.RootURL = strings.TrimRight(c.RootURL, "/")
 	c.UploadURI = filepath.Clean(c.UploadURI)
 	c.UploadPath = filepath.Clean(c.UploadPath)
@@ -286,7 +300,7 @@ func main() {
 	app.Messenger = initMessengers(app.Manager)
 
 	// Initialize the workers that push out messages.
-	go m.Run(time.Duration(time.Second * 5))
+	go m.Run(time.Second * 5)
 	m.SpawnWorkers()
 
 	// Initialize the HTTP server.

+ 3 - 3
manager/manager.go

@@ -91,8 +91,8 @@ func New(cfg Config, src DataSource, notifCB models.AdminNotifCallback, l *log.L
 		notifCB:        notifCB,
 		logger:         l,
 		messengers:     make(map[string]messenger.Messenger),
-		camps:          make(map[int]*models.Campaign, 0),
-		links:          make(map[string]string, 0),
+		camps:          make(map[int]*models.Campaign),
+		links:          make(map[string]string),
 		subFetchQueue:  make(chan *models.Campaign, cfg.Concurrency),
 		msgQueue:       make(chan *Message, cfg.Concurrency),
 		msgErrorQueue:  make(chan msgError, cfg.MaxSendErrors),
@@ -125,7 +125,7 @@ func (m *Manager) AddMessenger(msg messenger.Messenger) error {
 
 // GetMessengerNames returns the list of registered messengers.
 func (m *Manager) GetMessengerNames() []string {
-	var names []string
+	names := make([]string, 0, len(m.messengers))
 	for n := range m.messengers {
 		names = append(names, n)
 	}

+ 3 - 4
media.go

@@ -16,9 +16,8 @@ import (
 var imageMimes = []string{"image/jpg", "image/jpeg", "image/png", "image/svg", "image/gif"}
 
 const (
-	thumbPrefix = "thumb_"
-	thumbWidth  = 90
-	thumbHeight = 90
+	thumbPrefix   = "thumb_"
+	thumbnailSize = 90
 )
 
 // handleUploadMedia handles media file uploads.
@@ -52,7 +51,7 @@ func handleUploadMedia(c echo.Context) error {
 			fmt.Sprintf("Error opening image for resizing: %s", err))
 	}
 
-	t := imaging.Resize(src, thumbWidth, 0, imaging.Lanczos)
+	t := imaging.Resize(src, thumbnailSize, 0, imaging.Lanczos)
 	if err := imaging.Save(t, fmt.Sprintf("%s/%s%s", app.Constants.UploadPath, thumbPrefix, fName)); err != nil {
 		cleanUp = true
 		return echo.NewHTTPError(http.StatusInternalServerError,

+ 2 - 1
messenger/emailer.go

@@ -38,7 +38,8 @@ func NewEmailer(srv ...Server) (Messenger, error) {
 		servers: make(map[string]*Server),
 	}
 
-	for _, s := range srv {
+	for _, server := range srv {
+		s := server
 		var auth smtp.Auth
 		if s.AuthProtocol == "cram" {
 			auth = smtp.CRAMMD5Auth(s.Username, s.Password)

+ 1 - 1
messenger/messenger.go

@@ -29,6 +29,6 @@ func MakeAttachmentHeader(filename, encoding string) textproto.MIMEHeader {
 	h := textproto.MIMEHeader{}
 	h.Set("Content-Disposition", "attachment; filename="+filename)
 	h.Set("Content-Type", "application/json; name=\""+filename+"\"")
-	h.Set("Content-Transfer-Encoding", "base64")
+	h.Set("Content-Transfer-Encoding", encoding)
 	return h
 }

+ 1 - 1
public.go

@@ -232,6 +232,6 @@ func drawTransparentImage(h, w int) []byte {
 		img = image.NewRGBA(image.Rect(0, 0, w, h))
 		out = &bytes.Buffer{}
 	)
-	png.Encode(out, img)
+	_ = png.Encode(out, img)
 	return out.Bytes()
 }

+ 2 - 2
subimporter/importer.go

@@ -335,7 +335,7 @@ func (s *Session) ExtractZIP(srcPath string, maxCSVs int) (string, []string, err
 		return "", nil, err
 	}
 
-	var files []string
+	files := make([]string, 0, len(z.File))
 	for _, f := range z.File {
 		fName := f.FileInfo().Name()
 
@@ -421,7 +421,7 @@ func (s *Session) LoadCSV(srcPath string, delim rune) error {
 	s.im.Unlock()
 
 	// Rewind, now that we've done a linecount on the same handler.
-	f.Seek(0, 0)
+	_, _ = f.Seek(0, 0)
 	rd := csv.NewReader(f)
 	rd.Comma = delim
 

+ 5 - 2
subscribers.go

@@ -69,10 +69,13 @@ func handleGetSubscriber(c echo.Context) error {
 	if err != nil {
 		return echo.NewHTTPError(http.StatusInternalServerError,
 			fmt.Sprintf("Error fetching subscriber: %s", pqErrMsg(err)))
-	} else if len(out) == 0 {
+	}
+	if len(out) == 0 {
 		return echo.NewHTTPError(http.StatusBadRequest, "Subscriber not found.")
 	}
-	out.LoadLists(app.Queries.GetSubscriberLists)
+	if err := out.LoadLists(app.Queries.GetSubscriberLists); err != nil {
+		return echo.NewHTTPError(http.StatusInternalServerError, "Error loading lists for subscriber.")
+	}
 
 	return c.JSON(http.StatusOK, okResp{out[0]})
 }

+ 5 - 7
templates.go

@@ -28,10 +28,6 @@ const (
 		<p>Here is a link to <a href="https://listmonk.app" target="_blank">listmonk</a>.</p>`
 )
 
-type dummyMessage struct {
-	UnsubscribeURL string
-}
-
 var (
 	regexpTplTag = regexp.MustCompile(`{{(\s+)?template\s+?"content"(\s+)?\.(\s+)?}}`)
 )
@@ -56,12 +52,14 @@ func handleGetTemplates(c echo.Context) error {
 	if err != nil {
 		return echo.NewHTTPError(http.StatusInternalServerError,
 			fmt.Sprintf("Error fetching templates: %s", pqErrMsg(err)))
-	} else if single && len(out) == 0 {
+	}
+	if single && len(out) == 0 {
 		return echo.NewHTTPError(http.StatusBadRequest, "Template not found.")
-	} else if len(out) == 0 {
-		return c.JSON(http.StatusOK, okResp{[]struct{}{}})
 	}
 
+	if len(out) == 0 {
+		return c.JSON(http.StatusOK, okResp{[]struct{}{}})
+	}
 	if single {
 		return c.JSON(http.StatusOK, okResp{out[0]})
 	}

+ 5 - 5
utils.go

@@ -27,11 +27,11 @@ var (
 	// filename_(number). The number is incremented in case
 	// new file uploads conflict with existing filenames
 	// on the filesystem.
-	fnameRegexp, _ = regexp.Compile(`(.+?)_([0-9]+)$`)
+	fnameRegexp = regexp.MustCompile(`(.+?)_([0-9]+)$`)
 
 	// This replaces all special characters
-	tagRegexp, _       = regexp.Compile(`[^a-z0-9\-\s]`)
-	tagRegexpSpaces, _ = regexp.Compile(`[\s]+`)
+	tagRegexp       = regexp.MustCompile(`[^a-z0-9\-\s]`)
+	tagRegexpSpaces = regexp.MustCompile(`[\s]+`)
 )
 
 // ScanToStruct prepares a given set of Queries and assigns the resulting
@@ -248,7 +248,7 @@ func normalizeTags(tags []string) []string {
 
 // makeMsgTpl takes a page title, heading, and message and returns
 // a msgTpl that can be rendered as a HTML view. This is used for
-// rendering aribtrary HTML views with error and success messages.
+// rendering arbitrary HTML views with error and success messages.
 func makeMsgTpl(pageTitle, heading, msg string) msgTpl {
 	if heading == "" {
 		heading = pageTitle
@@ -265,7 +265,7 @@ func makeMsgTpl(pageTitle, heading, msg string) msgTpl {
 // parses each number into an int64 and returns a slice of the
 // resultant values.
 func parseStringIDs(s []string) ([]int64, error) {
-	var vals []int64
+	vals := make([]int64, 0, len(s))
 
 	for _, v := range s {
 		i, err := strconv.ParseInt(v, 10, 64)