You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2026/09/22 09:39:00 UTC
(camel-k) 01/04: Fix #6829: drop support for kamel run --dev/--sync
This is an automated email from the ASF dual-hosted git repository.
squakez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit abe7b82ebded4a6b6274e2a93a45fc38d9b0f4a8
Author: Suhail Hany <su...@gmail.com>
AuthorDate: Sat Sep 19 13:48:52 2026 +0300
Fix #6829: drop support for kamel run --dev/--sync
Both flags were deprecated in v2.9.0. Removes the flags, the
runCmdOptions fields behind them, and the code that existed only to
serve them: syncIntegration, filterFileLocation, the pkg/util/sync
package and DeleteIntegration.
--logs and --wait keep their current behaviour.
---
.../ROOT/pages/configuration/dependencies.adoc | 2 +-
pkg/cmd/run.go | 125 +--------------------
pkg/cmd/run_support.go | 12 --
pkg/cmd/run_support_test.go | 17 ---
pkg/cmd/run_test.go | 26 -----
pkg/cmd/util.go | 12 --
pkg/util/sync/file.go | 56 ---------
pkg/util/sync/file_test.go | 68 -----------
8 files changed, 6 insertions(+), 312 deletions(-)
diff --git a/docs/modules/ROOT/pages/configuration/dependencies.adoc b/docs/modules/ROOT/pages/configuration/dependencies.adoc
index c02c00fa4..c46699682 100644
--- a/docs/modules/ROOT/pages/configuration/dependencies.adoc
+++ b/docs/modules/ROOT/pages/configuration/dependencies.adoc
@@ -11,7 +11,7 @@ from("imap://admin@myserver.com")
Since the integration has a endpoint starting with the **"imap:" prefix**, Camel K is able to **automatically add the "camel-mail" component** to the list of required dependencies. The `seda:` endpoint belongs to `camel-core` that is automatically added to all integrations, so Camel K will not add additional dependencies for it. This dependency resolution mechanism is transparent to the user, that will just see the integration running.
-Automatic resolution is also a nice feature in _dev mode_, because you are allowed to add all components you need *without exiting the dev loop*.
+Automatic resolution is also a nice feature while you iterate on an integration, because you are allowed to add all components you need *without editing the list of dependencies by hand*.
NOTE: Camel K won't be able to resolve automatically the dependencies when your routes specify dynamic URIs.
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 877d4d070..cd0ae229e 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -24,12 +24,10 @@ import (
"fmt"
"net/url"
"os"
- "os/signal"
"path"
"reflect"
"strconv"
"strings"
- "syscall"
"github.com/magiconair/properties"
@@ -54,7 +52,6 @@ import (
k8slog "github.com/apache/camel-k/v2/pkg/util/kubernetes/log"
"github.com/apache/camel-k/v2/pkg/util/property"
"github.com/apache/camel-k/v2/pkg/util/resource"
- "github.com/apache/camel-k/v2/pkg/util/sync"
"github.com/apache/camel-k/v2/pkg/util/watch"
)
@@ -93,8 +90,6 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions)
"key optionally represents the configmap/secret key to be filtered and path represents the destination path)")
cmd.Flags().StringArray("maven-repository", nil, "Add a maven repository")
cmd.Flags().Bool("logs", false, "Print integration logs")
- cmd.Flags().Bool("sync", false, "[Deprecated] Synchronize the local source file with the cluster, republishing at each change")
- cmd.Flags().Bool("dev", false, "[Deprecated] Enable Dev mode (equivalent to \"-w --logs --sync\")")
cmd.Flags().Bool("use-flows", true, "Write yaml sources as Flow objects in the integration custom resource")
cmd.Flags().StringP("operator-id", "x", "", "Operator id selected to manage this integration.")
cmd.Flags().String("profile", "", "Trait profile used for deployment")
@@ -129,12 +124,8 @@ type runCmdOptions struct {
Compression bool `mapstructure:"compression" yaml:",omitempty"`
Wait bool `mapstructure:"wait" yaml:",omitempty"`
Logs bool `mapstructure:"logs" yaml:",omitempty"`
- // Deprecated: won't be supported in the future
- Sync bool `mapstructure:"sync" yaml:",omitempty"`
- // Deprecated: won't be supported in the future
- Dev bool `mapstructure:"dev" yaml:",omitempty"`
- UseFlows bool `mapstructure:"use-flows" yaml:",omitempty"`
- Save bool `kamel:"omitsave" mapstructure:"save" yaml:",omitempty"`
+ UseFlows bool `mapstructure:"use-flows" yaml:",omitempty"`
+ Save bool `kamel:"omitsave" mapstructure:"save" yaml:",omitempty"`
// Deprecated: won't be supported in the future
IntegrationKit string `mapstructure:"kit" yaml:",omitempty"`
IntegrationName string `mapstructure:"name" yaml:",omitempty"`
@@ -259,10 +250,6 @@ func (o *runCmdOptions) validate(cmd *cobra.Command) error {
return err
}
- if o.OutputFormat != "" && o.Dev {
- return errors.New("cannot use --dev with -o/--output option")
- }
-
for _, label := range o.Labels {
parts := strings.Split(label, "=")
if len(parts) != 2 {
@@ -299,11 +286,6 @@ func (o *runCmdOptions) validate(cmd *cobra.Command) error {
fmt.Fprintf(cmd.OutOrStdout(), "Compression property is deprecated. It will be removed from future releases.\n")
}
- // Deprecated: to be removed
- if o.Sync || o.Dev {
- fmt.Fprintf(cmd.OutOrStdout(), "Dev and Sync properties are deprecated. They will be removed from future releases.\n")
- }
-
var client client.Client
if !isOfflineCommand(cmd) {
client, err = o.GetCmdClient()
@@ -348,32 +330,7 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error {
return err
}
- if o.Dev {
- cs := make(chan os.Signal, 1)
- signal.Notify(cs, os.Interrupt, syscall.SIGTERM)
- go func() {
- <-cs
- if o.Context.Err() != nil {
- // Context canceled
- return
- }
- fmt.Fprintln(cmd.OutOrStdout(), "Run integration terminating")
- err := DeleteIntegration(o.Context, c, integration.Name, integration.Namespace)
- if err != nil {
- fmt.Fprintln(cmd.ErrOrStderr(), err)
- os.Exit(1)
- }
- os.Exit(0)
- }()
- }
-
- if o.Sync || o.Dev {
- err = o.syncIntegration(cmd, c, args)
- if err != nil {
- return err
- }
- }
- if o.Logs || o.Dev || o.Wait {
+ if o.Logs || o.Wait {
//nolint:errcheck
go watch.HandleIntegrationEvents(o.Context, c, integration, func(event *corev1.Event) bool {
fmt.Fprintln(cmd.OutOrStdout(), event.Message)
@@ -381,7 +338,7 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error {
return true
})
}
- if o.Wait || o.Dev {
+ if o.Wait {
phase := v1.IntegrationPhaseRunning
if o.DontRunAfterBuild {
phase = v1.IntegrationPhaseBuildComplete
@@ -409,14 +366,11 @@ func (o *runCmdOptions) run(cmd *cobra.Command, args []string) error {
integration.ResourceVersion = existing.ResourceVersion
}
}
- if o.Logs || o.Dev {
+ if o.Logs {
err = k8slog.Print(o.Context, cmd, c, integration, nil, cmd.OutOrStdout())
if err != nil {
return err
}
- }
-
- if o.Sync || o.Logs || o.Dev {
// Let's add a Wait point, otherwise the script terminates
<-o.RootContext.Done()
}
@@ -467,75 +421,6 @@ func (o *runCmdOptions) waitForIntegrationPhase(cmd *cobra.Command, c client.Cli
return watch.HandleIntegrationStateChanges(o.Context, c, integration, handler)
}
-func (o *runCmdOptions) syncIntegration(cmd *cobra.Command, c client.Client, sources []string) error {
- // Let's watch all relevant files when in dev mode
- res := filterFileLocation(o.Resources)
- cfg := filterFileLocation(o.Configs)
- prop := filterFileLocation(o.Properties)
- buildProp := filterFileLocation(o.BuildProperties)
-
- files := make([]string, 0,
- len(sources)+len(res)+len(cfg)+len(prop)+len(buildProp),
- )
-
- files = append(files, sources...)
- files = append(files, res...)
- files = append(files, cfg...)
- files = append(files, prop...)
- files = append(files, buildProp...)
-
- for _, s := range files {
- ok, err := source.IsLocalAndFileExists(s)
- if err != nil {
- return err
- }
- if ok {
- changes, err := sync.File(o.Context, s)
- if err != nil {
- return err
- }
- go func() {
- for {
- select {
- case <-o.Context.Done():
- return
- case <-changes:
- // let's create a new command to parse modeline changes and update our integration
- newCmd, _, err := createKamelWithModelineCommand(o.RootContext, os.Args[1:])
- newCmd.SetOut(cmd.OutOrStdout())
- newCmd.SetErr(cmd.ErrOrStderr())
- if err != nil {
- fmt.Fprintln(newCmd.ErrOrStderr(), "Unable to sync integration: ", err.Error())
-
- continue
- }
- newCmd.Args = o.validateArgs
- newCmd.PreRunE = o.decode
- newCmd.RunE = func(cmd *cobra.Command, args []string) error {
- _, err := o.createOrUpdateIntegration(cmd, c, sources)
-
- return err
- }
- newCmd.PostRunE = nil
-
- // cancel the existing command to release watchers
- o.ContextCancel()
- // run the new one
- err = newCmd.Execute()
- if err != nil {
- fmt.Fprintln(newCmd.ErrOrStderr(), "Unable to sync integration: ", err.Error())
- }
- }
- }
- }()
- } else {
- fmt.Fprintf(cmd.ErrOrStderr(), "Warning: the following URL will not be watched for changes: %s\n", s)
- }
- }
-
- return nil
-}
-
func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.Client, sources []string) (*v1.Integration, error) {
namespace := o.Namespace
name, err := o.GetIntegrationName(sources)
diff --git a/pkg/cmd/run_support.go b/pkg/cmd/run_support.go
index acc35e58c..4ee28c9a8 100644
--- a/pkg/cmd/run_support.go
+++ b/pkg/cmd/run_support.go
@@ -64,18 +64,6 @@ func parseConfig(ctx context.Context, cmd *cobra.Command, c client.Client, confi
return nil
}
-func filterFileLocation(maybeFileLocations []string) []string {
- filteredOptions := make([]string, 0)
- for _, option := range maybeFileLocations {
- if strings.HasPrefix(option, "file:") {
- localPath, _ := resource.ParseFileValue(strings.Replace(option, "file:", "", 1))
- filteredOptions = append(filteredOptions, localPath)
- }
- }
-
- return filteredOptions
-}
-
func keyValueProps(value string) (*properties.Properties, error) {
return properties.Load([]byte(value), properties.UTF8)
}
diff --git a/pkg/cmd/run_support_test.go b/pkg/cmd/run_support_test.go
index 81d208855..9afd8d50f 100644
--- a/pkg/cmd/run_support_test.go
+++ b/pkg/cmd/run_support_test.go
@@ -23,23 +23,6 @@ import (
"github.com/stretchr/testify/assert"
)
-func TestFilterFileLocation(t *testing.T) {
- optionFileLocations := []string{
- "file:/path/to/valid/file",
- "file:app.properties",
- "configmap:my-configmap",
- "secret:my-secret",
- "file:/validfile@/tmp/destination",
- }
-
- filteredOptions := filterFileLocation(optionFileLocations)
-
- assert.Equal(t, 3, len(filteredOptions))
- assert.Equal(t, "/path/to/valid/file", filteredOptions[0])
- assert.Equal(t, "app.properties", filteredOptions[1])
- assert.Equal(t, "/validfile", filteredOptions[2])
-}
-
func TestExtractTraitNames(t *testing.T) {
traitProps := []string{"container.enabled=true", "no-trait.noval=1", "nothing"}
tn := extractTraitNames(traitProps)
diff --git a/pkg/cmd/run_test.go b/pkg/cmd/run_test.go
index a811ac6b8..98dabb531 100644
--- a/pkg/cmd/run_test.go
+++ b/pkg/cmd/run_test.go
@@ -105,8 +105,6 @@ func TestRunNoFlag(t *testing.T) {
// Check default expected values
assert.False(t, runCmdOptions.Wait)
assert.False(t, runCmdOptions.Logs)
- assert.False(t, runCmdOptions.Sync)
- assert.False(t, runCmdOptions.Dev)
assert.True(t, runCmdOptions.UseFlows)
assert.False(t, runCmdOptions.Compression)
assert.False(t, runCmdOptions.Save)
@@ -139,23 +137,6 @@ func TestRunDependencyFlag(t *testing.T) {
assert.Equal(t, "dependency3", runCmdOptions.Dependencies[2])
}
-func TestRunDevFlag(t *testing.T) {
- runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t)
- _, err := ExecuteCommand(rootCmd, cmdRun, "--dev", integrationSource)
- require.NoError(t, err)
- assert.True(t, runCmdOptions.Dev)
-}
-
-func TestRunDevModeOutputFlag(t *testing.T) {
- runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t)
- _, err := ExecuteCommand(rootCmd, cmdRun, "--dev", "-o", "yaml", integrationSource)
- assert.True(t, runCmdOptions.Dev)
- assert.Equal(t, "yaml", runCmdOptions.OutputFormat)
- require.Error(t, err)
- assert.Equal(t, "cannot use --dev with -o/--output option",
- err.Error())
-}
-
func TestRunEnvFlag(t *testing.T) {
runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t)
_, err := ExecuteCommand(rootCmd, cmdRun,
@@ -382,13 +363,6 @@ func TestRunSourceFlag(t *testing.T) {
assert.Equal(t, "source1", runCmdOptions.Sources[0])
}
-func TestRunSyncFlag(t *testing.T) {
- runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t)
- _, err := ExecuteCommand(rootCmd, cmdRun, "--sync", integrationSource)
- require.NoError(t, err)
- assert.True(t, runCmdOptions.Sync)
-}
-
func TestRunExistingTraitFlag(t *testing.T) {
runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t)
_, err := ExecuteCommand(rootCmd, cmdRun,
diff --git a/pkg/cmd/util.go b/pkg/cmd/util.go
index ba5807d8f..cbea754fc 100644
--- a/pkg/cmd/util.go
+++ b/pkg/cmd/util.go
@@ -43,18 +43,6 @@ const (
offlineCommandLabel = "camel.apache.org/cmd.offline"
)
-// DeleteIntegration --.
-func DeleteIntegration(ctx context.Context, c client.Client, name string, namespace string) error {
- integration := v1.Integration{
- Kind: v1.IntegrationKind,
- APIVersion: v1.SchemeGroupVersion.String(),
- Namespace: namespace,
- Name: name,
- }
-
- return c.Delete(ctx, &integration)
-}
-
func bindPFlagsHierarchy(cmd *cobra.Command, v *viper.Viper) error {
for _, c := range cmd.Commands() {
if err := bindPFlags(c, v); err != nil {
diff --git a/pkg/util/sync/file.go b/pkg/util/sync/file.go
deleted file mode 100644
index bb9aee226..000000000
--- a/pkg/util/sync/file.go
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements. See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You 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 sync provides useful tools to get notified when a file system resource changes
-package sync
-
-import (
- "context"
-
- "github.com/fsnotify/fsnotify"
-)
-
-// File returns a channel that signals each time the content of the file changes.
-func File(ctx context.Context, path string) (<-chan bool, error) {
- watcher, err := fsnotify.NewWatcher()
- if err != nil {
- return nil, err
- }
-
- out := make(chan bool)
-
- // Start listening for events.
- go func() {
- for {
- select {
- case <-ctx.Done():
- return
- case event := <-watcher.Events:
- if event.Has(fsnotify.Write) {
- out <- true
- }
- }
- }
- }()
-
- err = watcher.Add(path)
- if err != nil {
- return nil, err
- }
-
- return out, nil
-}
diff --git a/pkg/util/sync/file_test.go b/pkg/util/sync/file_test.go
deleted file mode 100644
index 6ae7f1cd7..000000000
--- a/pkg/util/sync/file_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements. See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You 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 sync
-
-import (
- "context"
- "os"
- "strconv"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestFile(t *testing.T) {
- tempDir := t.TempDir()
- file, err := os.CreateTemp(tempDir, "camel-k-test-*")
- require.NoError(t, err)
- defer func() {
- _ = os.Remove(file.Name())
- }()
-
- ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(100*time.Second))
- defer cancel()
- changes, err := File(ctx, file.Name())
- require.NoError(t, err)
-
- time.Sleep(100 * time.Millisecond)
- expectedNumChanges := 3
- for i := 0; i < expectedNumChanges; i++ {
- if err := os.WriteFile(file.Name(), []byte("data-"+strconv.Itoa(i)), 0o600); err != nil {
- t.Error(err)
- }
- time.Sleep(350 * time.Millisecond)
- }
-
- numChanges := 0
-watch:
- for {
- select {
- case <-ctx.Done():
- return
- case <-changes:
- numChanges++
- if numChanges == expectedNumChanges {
- break watch
- }
- }
- }
-
- assert.Equal(t, expectedNumChanges, numChanges)
-}