Initial Commit
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing

This commit is contained in:
2023-07-19 21:44:02 +02:00
commit 3777c49ee9
18 changed files with 4961 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
package dockerCompose
type Equalable interface {
Equal(equalable Equalable) bool
}
// Contains returns true when sliceA is in sliceB.
func Contains[R Equalable](sliceA, sliceB []R) bool {
switch {
case sliceA == nil && sliceB == nil:
return true
case sliceA != nil && sliceB == nil:
return false
case sliceA == nil && sliceB != nil:
return false
default:
LOOP:
for i := range sliceA {
for j := range sliceB {
if sliceA[i].Equal(sliceB[j]) {
continue LOOP
}
}
return false
}
return true
}
}
// Equal returns true when sliceA and sliceB are equal.
func Equal[R Equalable](sliceA, sliceB []R) bool {
return Contains(sliceA, sliceB) &&
Contains(sliceB, sliceA) &&
len(sliceA) == len(sliceB)
}
// Equal returns true when booth string maps of Equalable are equal.
func EqualStringMap[R Equalable](mapA, mapB map[string]R) bool {
equalFunc := func(mapA, mapB map[string]R) bool {
LOOP:
for keyA, valueA := range mapA {
for keyB, valueB := range mapB {
if keyA == keyB &&
valueA.Equal(valueB) {
continue LOOP
}
}
return false
}
return true
}
return equalFunc(mapA, mapB) && equalFunc(mapB, mapA)
}
// ExistsInMap returns true if object of type any exists under the passed name.
func ExistsInMap[T any](m map[string]T, name string) bool {
switch {
case m == nil:
return false
default:
_, present := m[name]
return present
}
}

99
pkg/fetcher/fetcher.go Normal file
View File

@ -0,0 +1,99 @@
package fetcher
import (
"errors"
"fmt"
"net/http"
"net/url"
"os"
"git.cryptic.systems/volker.raschek/dcmerge/pkg/domain/dockerCompose"
"gopkg.in/yaml.v3"
)
func Fetch(urls ...string) ([]*dockerCompose.Config, error) {
dockerComposeConfigs := make([]*dockerCompose.Config, 0)
for _, rawURL := range urls {
dockerComposeURL, err := url.Parse(rawURL)
if err != nil {
return nil, err
}
switch {
case dockerComposeURL.Scheme == "http" || dockerComposeURL.Scheme == "https":
dockerComposeConfig, err := getDockerComposeViaHTTP(dockerComposeURL.String())
if err != nil {
return nil, err
}
dockerComposeConfigs = append(dockerComposeConfigs, dockerComposeConfig)
case dockerComposeURL.Scheme == "file":
fallthrough
default:
dockerComposeConfig, err := readDockerComposeFromFile(dockerComposeURL.Path)
if err != nil {
return nil, err
}
dockerComposeConfigs = append(dockerComposeConfigs, dockerComposeConfig)
}
}
return dockerComposeConfigs, nil
}
var ErrorPathIsDir error = errors.New("Path is a directory")
func getDockerComposeViaHTTP(url string) (*dockerCompose.Config, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Received unexpected HTTP-Statuscode %v", resp.StatusCode)
}
dockerCompose := dockerCompose.NewConfig()
yamlDecoder := yaml.NewDecoder(resp.Body)
err = yamlDecoder.Decode(&dockerCompose)
if err != nil {
return nil, err
}
return dockerCompose, nil
}
func readDockerComposeFromFile(name string) (*dockerCompose.Config, error) {
fileStat, err := os.Stat(name)
switch {
case errors.Is(err, os.ErrNotExist):
return nil, err
case fileStat.IsDir():
return nil, fmt.Errorf("%w: %s", ErrorPathIsDir, name)
}
file, err := os.Open(name)
if err != nil {
return nil, err
}
defer file.Close()
dockerCompose := dockerCompose.NewConfig()
yamlDecoder := yaml.NewDecoder(file)
err = yamlDecoder.Decode(&dockerCompose)
if err != nil {
return nil, err
}
return dockerCompose, nil
}