Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions nitric/lifecycle/lifecycle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2024, Nitric Technologies Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lifecycle

import (
"fmt"
"os"
)

// LifecycleStage represents the different stages of Nitric execution
type LifecycleStage string

const (
// LocalRun represents local development run (using nitric run/start)
LocalRun LifecycleStage = "run"
// Build represents local development requirements building/collection (using nitric up)
Build LifecycleStage = "build"
// Cloud represents when the code is running in a deployed environment
Cloud LifecycleStage = "cloud"
)

const (
// NITRIC_ENVIRONMENT is the environment variable key used to determine the current Nitric lifecycle
NITRIC_ENVIRONMENT = "NITRIC_ENVIRONMENT"
)

// GetCurrentLifecycle returns the current lifecycle stage
func GetCurrentLifecycle() (LifecycleStage, error) {
lifecycle := os.Getenv(NITRIC_ENVIRONMENT)
if lifecycle == "" {
return "", fmt.Errorf("unable to determine the current Nitric lifecycle, please ensure the %s environment variable is set", NITRIC_ENVIRONMENT)
}

stage := LifecycleStage(lifecycle)
switch stage {
case LocalRun, Build, Cloud:
return stage, nil
default:
return "", fmt.Errorf("invalid lifecycle stage: %s", lifecycle)
}
}

// IsInLifecycle checks if the current environment is one of the provided stages
func IsInLifecycle(stages ...LifecycleStage) bool {
currentStage, err := GetCurrentLifecycle()
if err != nil {
return false
}

for _, stage := range stages {
if currentStage == stage {
return true
}
}
return false
}

// WhenInLifecycles executes the provided callback if the current environment is one of the provided stages
func WhenInLifecycles[T any](stages []LifecycleStage, callback func() T) T {
if IsInLifecycle(stages...) {
return callback()
}
var zero T
return zero
}

// WhenRunning executes the provided callback if the current environment is running (LocalRun or Cloud)
func WhenRunning[T any](callback func() T) T {
return WhenInLifecycles([]LifecycleStage{LocalRun, Cloud}, callback)
}

// WhenCollecting executes the provided callback if the current environment is collecting requirements (Build)
func WhenCollecting[T any](callback func() T) T {
return WhenInLifecycles([]LifecycleStage{Build}, callback)
}

// IsRunning checks if the current lifecycle is running the app (LocalRun or Cloud)
func IsRunning() bool {
return IsInLifecycle(LocalRun, Cloud)
}

// IsCollecting checks if the current lifecycle is collecting application requirements (Build)
func IsCollecting() bool {
return IsInLifecycle(Build)
}
27 changes: 27 additions & 0 deletions nitric/lifecycle/lifecycle_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2024, Nitric Technologies Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lifecycle_test

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestLifecycle(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Lifecycle Suite")
}
165 changes: 165 additions & 0 deletions nitric/lifecycle/lifecycle_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Copyright 2024, Nitric Technologies Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lifecycle_test

import (
"os"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"github.com/nitrictech/go-sdk/nitric/lifecycle"
)

var _ = Describe("Lifecycle", func() {
BeforeEach(func() {
// Clear environment before each test
os.Unsetenv(lifecycle.NITRIC_ENVIRONMENT)
})

Describe("GetCurrentLifecycle", func() {
Context("when environment variable is set to valid stages", func() {
It("should return LocalRun stage", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "run")
stage, err := lifecycle.GetCurrentLifecycle()
Expect(err).NotTo(HaveOccurred())
Expect(stage).To(Equal(lifecycle.LocalRun))
})

It("should return Build stage", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "build")
stage, err := lifecycle.GetCurrentLifecycle()
Expect(err).NotTo(HaveOccurred())
Expect(stage).To(Equal(lifecycle.Build))
})

It("should return Cloud stage", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "cloud")
stage, err := lifecycle.GetCurrentLifecycle()
Expect(err).NotTo(HaveOccurred())
Expect(stage).To(Equal(lifecycle.Cloud))
})
})

Context("when environment variable is not set", func() {
It("should return an error", func() {
stage, err := lifecycle.GetCurrentLifecycle()
Expect(err).To(HaveOccurred())
Expect(stage).To(BeEmpty())
})
})

Context("when environment variable is set to invalid stage", func() {
It("should return an error", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "invalid")
stage, err := lifecycle.GetCurrentLifecycle()
Expect(err).To(HaveOccurred())
Expect(stage).To(BeEmpty())
})
})
})

Describe("IsInLifecycle", func() {
Context("when current stage matches one of the provided stages", func() {
It("should return true for LocalRun", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "run")
result := lifecycle.IsInLifecycle(lifecycle.LocalRun, lifecycle.Cloud)
Expect(result).To(BeTrue())
})

It("should return true for Cloud", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "cloud")
result := lifecycle.IsInLifecycle(lifecycle.LocalRun, lifecycle.Cloud)
Expect(result).To(BeTrue())
})
})

Context("when current stage does not match any of the provided stages", func() {
It("should return false", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "build")
result := lifecycle.IsInLifecycle(lifecycle.LocalRun, lifecycle.Cloud)
Expect(result).To(BeFalse())
})
})
})

Describe("WhenInLifecycles", func() {
Context("when current stage matches one of the provided stages", func() {
It("should execute the callback", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "run")
result := lifecycle.WhenInLifecycles([]lifecycle.LifecycleStage{lifecycle.LocalRun, lifecycle.Cloud}, func() string {
return "executed"
})
Expect(result).To(Equal("executed"))
})
})

Context("when current stage does not match any of the provided stages", func() {
It("should not execute the callback and return zero value", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "build")
result := lifecycle.WhenInLifecycles([]lifecycle.LifecycleStage{lifecycle.LocalRun, lifecycle.Cloud}, func() string {
return "executed"
})
Expect(result).To(BeEmpty())
})
})
})

Describe("IsRunning", func() {
Context("when in LocalRun stage", func() {
It("should return true", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "run")
Expect(lifecycle.IsRunning()).To(BeTrue())
})
})

Context("when in Cloud stage", func() {
It("should return true", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "cloud")
Expect(lifecycle.IsRunning()).To(BeTrue())
})
})

Context("when in Build stage", func() {
It("should return false", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "build")
Expect(lifecycle.IsRunning()).To(BeFalse())
})
})
})

Describe("IsCollecting", func() {
Context("when in Build stage", func() {
It("should return true", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "build")
Expect(lifecycle.IsCollecting()).To(BeTrue())
})
})

Context("when in LocalRun stage", func() {
It("should return false", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "run")
Expect(lifecycle.IsCollecting()).To(BeFalse())
})
})

Context("when in Cloud stage", func() {
It("should return false", func() {
os.Setenv(lifecycle.NITRIC_ENVIRONMENT, "cloud")
Expect(lifecycle.IsCollecting()).To(BeFalse())
})
})
})
})