Skip to content

Commit

Permalink
NOISSUE - Add Continous Integration (#9)
Browse files Browse the repository at this point in the history
* feat: Add CI

Signed-off-by: 1998-felix <felix.gateru@gmail.com>

* ci: Add linter, dependabot and ci config

Signed-off-by: 1998-felix <felix.gateru@gmail.com>

* ci: refactor config for linter settings

Signed-off-by: 1998-felix <felix.gateru@gmail.com>

* fix: fix failing linter

Signed-off-by: 1998-felix <felix.gateru@gmail.com>

* refactor: clean up variable names

Signed-off-by: 1998-felix <felix.gateru@gmail.com>

* refactor: refactor error definition to inline

Signed-off-by: 1998-felix <felix.gateru@gmail.com>

* refactor: refactor parse code, remove inline errors

Signed-off-by: 1998-felix <felix.gateru@gmail.com>

* refactor: refactor parseCode for error handling

Signed-off-by: 1998-felix <felix.gateru@gmail.com>

---------

Signed-off-by: 1998-felix <felix.gateru@gmail.com>
  • Loading branch information
felixgateru committed May 8, 2024
1 parent e0e6275 commit aef7d93
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 50 deletions.
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

version: 2
updates:
- package-ecosystem: "github-actions"
directory: ".github/workflows"
schedule:
interval: "monthly"

- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "monthly"
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

name: Continuous Integration

on:
pull_request:
branches:
- master
push:
branches:
- master

jobs:
lint-and-build:
name: Lint and Build
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: 1.22.x
cache-dependency-path: "go.sum"

- name: Check linting
uses: golangci/golangci-lint-action@v4
with:
version: v1.56.2

- name: Build Binaries
run: |
make all -j $(nproc)
75 changes: 75 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

run:
concurrency: 4
timeout: 1m

linters-settings:
importas:
no-unaliased: true
no-extra-aliases: false
gocritic:
enabled-checks:
- importShadow
- httpNoBody
- paramTypeCombine
- emptyStringTest
- builtinShadow
- exposedSyncMutex
disabled-checks:
- appendAssign
enabled-tags:
- diagnostic
disabled-tags:
- performance
- style
- experimental
- opinionated
stylecheck:
checks: ["-ST1000", "-ST1003", "-ST1020", "-ST1021", "-ST1022"]
goheader:
template: |-
Copyright (c) Abstract Machines
SPDX-License-Identifier: Apache-2.0
linters:
disable-all: true
fast: true
enable:
- gocritic
- gosimple
- errcheck
- govet
- unused
- goconst
- godot
- godox
- ineffassign
- misspell
- stylecheck
- whitespace
- gci
- gofmt
- goimports
- loggercheck
- goheader
- asasalint
- asciicheck
- bidichk
- contextcheck
- decorder
- dogsled
- errchkjson
- errname
- execinquery
- exportloopref
- ginkgolinter
- gocheckcompilerdirectives
- gofumpt
- goprintffuncname
- importas
- makezero
- mirror
- nakedret
- dupword
129 changes: 80 additions & 49 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0

package main

import (
Expand All @@ -18,13 +21,6 @@ import (
"github.com/plgd-dev/go-coap/v2/udp/message/pool"
)

const (
get = "GET"
put = "PUT"
post = "POST"
delete = "DELETE"
)

const (
helpCmd = `Use "coap-cli --help" for help.`
helpMsg = `
Expand All @@ -44,18 +40,38 @@ coap-cli post channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -a
`
)

var (
errCreateClient = errors.New("failed to create client")
errSendMessage = errors.New("failed to send message")
errInvalidObsOpt = errors.New("invalid observe option")
errFailedObserve = errors.New("failed to observe resource")
errTerminatedObs = errors.New("observation terminated")
errCancelObs = errors.New("failed to cancel observation")
errCodeNotSupported = errors.New("message can be GET, POST, PUT or DELETE")
)

type request struct {
code codes.Code
path string
host *string
port *string
cf *int
data *string
auth *string
obs *bool
}

func parseCode(code string) (codes.Code, error) {
switch code {
case get:
return codes.GET, nil
case put:
return codes.PUT, nil
case post:
return codes.POST, nil
case delete:
return codes.DELETE, nil
}
return 0, errors.New("Message can be GET, POST, PUT or DELETE")
ret, err := codes.ToCode(code)
if err != nil {
return 0, err
}
switch ret {
case codes.GET, codes.POST, codes.PUT, codes.DELETE:
return ret, nil
default:
return 0, errCodeNotSupported
}
}

func printMsg(m *pool.Message) {
Expand All @@ -70,67 +86,82 @@ func main() {
}
help := strings.ToLower(os.Args[1])
if help == "-h" || help == "--help" {
log.Println(helpMsg)
os.Exit(0)
log.Print(helpMsg)
return
}

code, err := parseCode(strings.ToUpper(os.Args[1]))
req := request{}
var err error
req.code, err = parseCode(strings.ToUpper(os.Args[1]))
if err != nil {
log.Fatalf("Can't read request code: %s\n%s", err, helpCmd)
}

if len(os.Args) < 3 {
log.Fatalf("CoAP URL must not be empty.\n%s", helpCmd)
}
path := os.Args[2]
if strings.HasPrefix(path, "-") {
req.path = os.Args[2]
if strings.HasPrefix(req.path, "-") {
log.Fatalf("Please enter a valid CoAP URL.\n%s", helpCmd)
}

os.Args = os.Args[2:]
o := flag.Bool("o", false, "Observe")
h := flag.String("h", "localhost", "Host")
p := flag.String("p", "5683", "Port")
req.obs = flag.Bool("o", false, "Observe")
req.host = flag.String("h", "localhost", "Host")
req.port = flag.String("p", "5683", "Port")
// Default type is JSON.
cf := flag.Int("cf", 50, "Content format")
d := flag.String("d", "", "Message data")
a := flag.String("auth", "", "Auth token")
req.cf = flag.Int("cf", 50, "Content format")
req.data = flag.String("d", "", "Message data")
req.auth = flag.String("auth", "", "Auth token")
flag.Parse()

client, err := coap.New(*h + ":" + *p)
if err = makeRequest(req); err != nil {
log.Fatal(err)
}
}

func makeRequest(req request) error {
client, err := coap.New(*req.host + ":" + *req.port)
if err != nil {
log.Fatal("Error creating client: ", err)
return errors.Join(errCreateClient, err)
}
var opts coapmsg.Options
if a != nil {
opts = append(opts, coapmsg.Option{ID: coapmsg.URIQuery, Value: []byte(fmt.Sprintf("auth=%s", *a))})
if req.auth != nil {
opts = append(opts, coapmsg.Option{ID: coapmsg.URIQuery, Value: []byte(fmt.Sprintf("auth=%s", *req.auth))})
}

if o == nil || (!*o) {
pld := strings.NewReader(*d)
if req.obs == nil || (!*req.obs) {
pld := strings.NewReader(*req.data)

res, err := client.Send(path, code, message.MediaType(*cf), pld, opts...)
res, err := client.Send(req.path, req.code, message.MediaType(*req.cf), pld, opts...)
if err != nil {
log.Fatal("Error sending message: ", err)
return errors.Join(errSendMessage, err)
}
printMsg(res)
return
return nil
}
if code != codes.GET {
log.Fatal("Only GET requests accept observe option.")
if req.code != codes.GET {
return errInvalidObsOpt
}
obs, err := client.Receive(path, opts...)
obs, err := client.Receive(req.path, opts...)
if err != nil {
log.Fatal("Error observing resource: ", err)
return errors.Join(errFailedObserve, err)
}
errs := make(chan error, 2)

errs := make(chan error, 1)
go func() {
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGINT)
errs <- fmt.Errorf("%s", <-c)
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT)

sig := <-sigChan
errs <- fmt.Errorf("%v", sig)
}()

err = <-errs
obs.Cancel(context.Background())
log.Fatal("Observation terminated: ", err)
if err != nil {
return errors.Join(errTerminatedObs, err)
}
if err := obs.Cancel(context.Background()); err != nil {
return errors.Join(errCancelObs, err)
}
return nil
}
9 changes: 8 additions & 1 deletion coap/client.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0

package coap

import (
Expand All @@ -15,6 +18,8 @@ import (
"github.com/plgd-dev/go-coap/v2/udp/message/pool"
)

var errInvalidMsgCode = errors.New("message can be GET, POST, PUT or DELETE")

// Client represents CoAP client.
type Client struct {
conn *client.ClientConn
Expand Down Expand Up @@ -44,8 +49,9 @@ func (c Client) Send(path string, msgCode codes.Code, cf message.MediaType, payl
return c.conn.Put(ctx, path, cf, payload, opts...)
case codes.DELETE:
return c.conn.Delete(ctx, path, opts...)
default:
return nil, errInvalidMsgCode
}
return nil, errors.New("Invalid message code")
}

// Receive receives a message.
Expand All @@ -58,6 +64,7 @@ func (c Client) Receive(path string, opts ...message.Option) (*client.Observatio
body, err := res.ReadBody()
if err != nil {
fmt.Println("Error reading message body: ", err)

return
}
if len(body) > 0 {
Expand Down

0 comments on commit aef7d93

Please sign in to comment.