Repository: meshery/meshkit

Issue:
Linting issues in multiple files
### Current Behavior
<!-- A brief description of the issue. -->
Linting issues in several files
### Expected Behavior
<!-- A brief description of what you expected to happen. -->

### Screenshots/Logs
<!-- Add screenshots, if applicable, to help explain your problem. -->

### Environment

- **Host OS:** Linux 
- **Platform:** Docker or Kubernetes
- **Meshery Server Version:** stable-v
- **Meshery Client Version:** stable-v

<!-- Optional
### To Reproduce
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
-->

---
### Contributor [Guides](https://docs.meshery.io/project/contributing) and [Handbook](https://meshery.io/community#handbook)
- 🛠 [Meshery Build & Release Strategy](https://docs.meshery.io/project/contributing/build-and-release)
- 📚 [Instructions for contributing to documentation](https://github.com/meshery/meshery/blob/master/CONTRIBUTING.md#documentation-contribution-flow)
   - Meshery documentation [site](https://docs.meshery.io/) and [source](https://github.com/meshery/meshery/tree/master/docs)
- 🎨 Wireframes and [designs for Meshery UI](https://www.figma.com/file/SMP3zxOjZztdOLtgN4dS2W/Meshery-UI) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9)
- 🙋🏾🙋🏼 Questions: [Discussion Forum](http://discuss.meshery.io) and [Community Slack](https://slack.meshery.io)


Discussion:
@welcome: Thanks for opening this issue. A contributor will be by to give feedback soon. In the meantime, please review the [Contributors' Welcome Guide](https://docs.meshery.io/project/community), engage in the [discussion forum](http://discuss.meshery.io), and be sure to join the [community Slack](http://slack.meshery.io/).
@abohoss: Hi @n2h9 ,
please check those PRs when convenient to you


Solution patch:
diff --git a/broker/nats/nats.go b/broker/nats/nats.go
index 224a066..b18b586 100644
--- a/broker/nats/nats.go
+++ b/broker/nats/nats.go
@@ -1,12 +1,16 @@
 package nats
 
 import (
+	"context"
+	"encoding/json"
+	"fmt"
 	"log"
 	"strings"
 	"sync"
 	"time"
 
 	"github.com/meshery/meshkit/broker"
+	"github.com/meshery/meshkit/logger"
 	nats "github.com/nats-io/nats.go"
 )
 
@@ -21,12 +25,16 @@ type Options struct {
 	Password       string
 	ReconnectWait  time.Duration
 	MaxReconnect   int
+	Logger         logger.Handler
 }
 
 // Nats will implement Nats subscribe and publish functionality
 type Nats struct {
-	ec *nats.EncodedConn
-	wg *sync.WaitGroup
+	nc     *nats.Conn
+	wg     *sync.WaitGroup
+	ctx    context.Context
+	cancel context.CancelFunc
+	log    logger.Handler
 }
 
 // New - constructor
@@ -37,102 +45,217 @@ func New(opts Options) (broker.Handler, error) {
 		nats.MaxReconnects(opts.MaxReconnect),
 		nats.UserInfo(opts.Username, opts.Password),
 		nats.DisconnectErrHandler(func(_ *nats.Conn, err error) {
-			log.Printf("client disconnected: %v", err)
+			if opts.Logger != nil {
+				opts.Logger.Error(err)
+			} else {
+				log.Printf("client disconnected: %v", err)
+			}
 		}),
 		nats.ReconnectHandler(func(_ *nats.Conn) {
-			log.Printf("client reconnected")
+			if opts.Logger != nil {
+				opts.Logger.Info("client reconnected")
+			} else {
+				log.Printf("client reconnected")
+			}
 		}),
 		nats.ClosedHandler(func(_ *nats.Conn) {
-			log.Printf("client closed")
+			if opts.Logger != nil {
+				opts.Logger.Info("client closed")
+			} else {
+				log.Printf("client closed")
+			}
 		}),
 		nats.DiscoveredServersHandler(func(nc *nats.Conn) {
-			log.Printf("Known servers: %v\n", nc.Servers())
-			log.Printf("Discovered servers: %v\n", nc.DiscoveredServers())
+			msg := fmt.Sprintf("Known servers: %v", nc.Servers())
+			if opts.Logger != nil {
+				opts.Logger.Info(msg)
+			} else {
+				log.Printf("%s", msg)
+			}
+			msg2 := fmt.Sprintf("Discovered servers: %v", nc.DiscoveredServers())
+			if opts.Logger != nil {
+				opts.Logger.Info(msg2)
+			} else {
+				log.Printf("%s", msg2)
+			}
 		}),
 		nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
-			log.Printf("Error: %v", err)
+			if opts.Logger != nil {
+				opts.Logger.Error(err)
+			} else {
+				log.Printf("Error: %v", err)
+			}
 		}),
 	)
 	if err != nil {
 		return nil, ErrConnect(err)
 	}
+	ctx, cancel := context.WithCancel(context.Background())
 
-	ec, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
-	if err != nil {
-		return nil, ErrEncodedConn(err)
+	// Use provided logger or create a default one
+	lg := opts.Logger
+	if lg == nil {
+		var lerr error
+		lg, lerr = logger.New("nats-handler", logger.Options{
+			Format:   logger.TerminalLogFormat,
+			LogLevel: 4, // Info
+		})
+		if lerr != nil {
+			// fallback to nil; we'll use std log where necessary
+			lg = nil
+		}
 	}
 
-	return &Nats{ec: ec}, nil
+	return &Nats{nc: nc, wg: &sync.WaitGroup{}, ctx: ctx, cancel: cancel, log: lg}, nil
 }
+
 func (n *Nats) ConnectedEndpoints() (endpoints []string) {
-	for _, server := range n.ec.Conn.Servers() {
+	if n == nil || n.nc == nil {
+		return
+	}
+	for _, server := range n.nc.Servers() {
 		endpoints = append(endpoints, strings.TrimPrefix(server, "nats://"))
 	}
 	return
 }
 
 func (n *Nats) Info() string {
-	if n.ec == nil || n.ec.Conn == nil {
+	if n == nil || n.nc == nil {
 		return broker.NotConnected
 	}
-	return n.ec.Conn.Opts.Name
+	return n.nc.Opts.Name
 }
 
 func (n *Nats) CloseConnection() {
-	n.ec.Close()
+	if n == nil {
+		return
+	}
+	// Cancel background go routines first
+	if n.cancel != nil {
+		n.cancel()
+	}
+	if n.nc != nil {
+		n.nc.Close()
+	}
 }
 
-// Publish - to publish messages
+// Publish - to publish messages (uses JSON encoding)
 func (n *Nats) Publish(subject string, message *broker.Message) error {
-	err := n.ec.Publish(subject, message)
+	if n == nil || n.nc == nil {
+		return ErrPublish(fmt.Errorf("nats connection is not initialized"))
+	}
+
+	data, err := json.Marshal(message)
 	if err != nil {
+		if n.log != nil {
+			n.log.Error(err)
+		} else {
+			log.Printf("failed to marshal message: %v", err)
+		}
+		return ErrPublish(err)
+	}
+
+	if err := n.nc.Publish(subject, data); err != nil {
+		if n.log != nil {
+			n.log.Error(err)
+		} else {
+			log.Printf("failed to publish: %v", err)
+		}
 		return ErrPublish(err)
 	}
 	return nil
 }
 
-// PublishWithChannel - to publish messages with channel
+// PublishWithChannel - publishes all messages from channel
 func (n *Nats) PublishWithChannel(subject string, msgch chan *broker.Message) error {
-	err := n.ec.BindSendChan(subject, msgch)
-	if err != nil {
-		return ErrPublish(err)
+	if n == nil {
+		return ErrPublish(fmt.Errorf("nats handler is nil"))
 	}
+	go func() {
+		for {
+			select {
+			case <-n.ctx.Done():
+				return
+			case msg, ok := <-msgch:
+				if !ok {
+					return
+				}
+				if err := n.Publish(subject, msg); err != nil {
+					if n.log != nil {
+						n.log.Error(err)
+					} else {
+						log.Printf("failed to publish message: %v", err)
+					}
+				}
+			}
+		}
+	}()
 	return nil
 }
 
-// Subscribe - for subscribing messages
-// TODO Ques: Do we want to unsubscribe
-// TODO will the method-user just subsribe, how will it handle the received messages?
+// Subscribe - for subscribing messages (blocking)
 func (n *Nats) Subscribe(subject, queue string, message []byte) error {
+	if n == nil || n.nc == nil {
+		return ErrQueueSubscribe(fmt.Errorf("nats connection is not initialized"))
+	}
+
 	n.wg.Add(1)
-	_, err := n.ec.QueueSubscribe(subject, queue, func(msg *nats.Msg) {
-		message = msg.Data
+	_, err := n.nc.QueueSubscribe(subject, queue, func(msg *nats.Msg) {
+		copied := copy(message, msg.Data)
+		if copied < len(msg.Data) {
+			if n.log != nil {
+				n.log.Info(fmt.Sprintf("warning: message truncated in Subscribe. buffer size: %d, message size: %d", len(message), len(msg.Data)))
+			} else {
+				log.Printf("warning: message truncated in Subscribe. buffer size: %d, message size: %d", len(message), len(msg.Data))
+			}
+		}
 		n.wg.Done()
 	})
 	if err != nil {
+		if n.log != nil {
+			n.log.Error(err)
+		} else {
+			log.Printf("queue subscribe error: %v", err)
+		}
 		return ErrQueueSubscribe(err)
 	}
 	n.wg.Wait()
-
 	return nil
 }
 
-// SubscribeWithChannel will publish all the messages received to the given channel
+// SubscribeWithChannel - for subscribing and forwarding to channel (decodes JSON)
 func (n *Nats) SubscribeWithChannel(subject, queue string, msgch chan *broker.Message) error {
-	_, err := n.ec.BindRecvQueueChan(subject, queue, msgch)
+	if n == nil || n.nc == nil {
+		return ErrQueueSubscribe(fmt.Errorf("nats connection is not initialized"))
+	}
+
+	_, err := n.nc.QueueSubscribe(subject, queue, func(msg *nats.Msg) {
+		var parsed broker.Message
+		if err := json.Unmarshal(msg.Data, &parsed); err != nil {
+			if n.log != nil {
+				n.log.Error(err)
+			} else {
+				log.Printf("failed to decode message: %v", err)
+			}
+			return
+		}
+		msgch <- &parsed
+	})
 	if err != nil {
+		if n.log != nil {
+			n.log.Error(err)
+		} else {
+			log.Printf("queue subscribe error: %v", err)
+		}
 		return ErrQueueSubscribe(err)
 	}
-
 	return nil
 }
 
-// DeepCopyInto is a deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Nats) DeepCopyInto(out broker.Handler) {
 	*out.(*Nats) = *in
 }
 
-// DeepCopy is a deepcopy function, copying the receiver, creating a new Nats.
 func (in *Nats) DeepCopy() *Nats {
 	if in == nil {
 		return nil
@@ -142,7 +265,6 @@ func (in *Nats) DeepCopy() *Nats {
 	return out
 }
 
-// DeepCopyObject is a deepcopy function, copying the receiver, creating a new broker.Handler.
 func (in *Nats) DeepCopyObject() broker.Handler {
 	if c := in.DeepCopy(); c != nil {
 		return c
@@ -150,11 +272,9 @@ func (in *Nats) DeepCopyObject() broker.Handler {
 	return nil
 }
 
-// Check if the connection object is empty
 func (in *Nats) IsEmpty() bool {
-	empty := &Nats{}
-	if in == nil || *in == *empty {
+	if in == nil {
 		return true
 	}
-	return false
-}
+	return in.nc == nil && in.wg == nil && in.ctx == nil && in.cancel == nil
+}
\ No newline at end of file
diff --git a/generators/github/url.go b/generators/github/url.go
index 1b09757..3797b04 100644
--- a/generators/github/url.go
+++ b/generators/github/url.go
@@ -3,7 +3,7 @@ package github
 import (
 	"bufio"
 	"io"
-
+	"fmt"
 	"net/url"
 	"os"
 	"path/filepath"
@@ -55,6 +55,9 @@ func (u URL) GetContent() (models.Package, error) {
 	if strings.HasSuffix(url, ".yml") || strings.HasSuffix(url, ".yaml") {
 
 		data, err := os.ReadFile(downloadfilePath)
+		if err != nil {
+			return nil, fmt.Errorf("failed to read file %s: %w", downloadfilePath, err)
+		}
 		_, err = w.Write(data)
 		if err != nil {
 			return nil, err



Test patch:
diff --git a/converter/tests/helm_test.go b/converter/tests/helm_test.go
index 6c1e249..7c4f2f9 100644
--- a/converter/tests/helm_test.go
+++ b/converter/tests/helm_test.go
@@ -4,6 +4,7 @@ import (
 	"archive/tar"
 	"bytes"
 	"compress/gzip"
+	"fmt"
 	"io"
 	"os"
 	"strings"
@@ -139,7 +140,9 @@ func extractManifestFromChart(chartData []byte) (bool, string) {
 		}
 		if strings.HasSuffix(hdr.Name, "templates/manifest.yaml") {
 			buf := new(bytes.Buffer)
-			io.Copy(buf, tr)
+			if _, err := io.Copy(buf, tr); err != nil {
+				return false, fmt.Sprintf("failed to copy manifest content: %v", err)
+			}
 			return true, buf.String()
 		}
 	}