Repository: openshift/odo
Pull request #3963 (2020-09-15 20:06:49)

Update odo debug --help screen
**What type of PR is this?**

/kind cleanup

**What does does this PR do / why we need it**:

Updates the debug output of `odo debug --help` to the following:

```sh
github.com/openshift/odo  debugging-docs-update ✔                                                                                                                                                                                                                                                                                                                      53m
▶ ./odo debug --help
Debug allows you to remotely debug your application.

Usage:
  odo debug [flags]
  odo debug [command]

Aliases:
  debug, d

Examples:
  # Listen on default port and forwarding to the default port in the pod
  odo debug port-forward

  # Listen on the 5000 port locally, forwarding to default port in the pod
  odo debug port-forward --local-port 5000

  # Get information regarding any debug session of the component
  odo debug info

Available Commands:
  info         Displays debug info of a component
  port-forward Forward one or more local ports to a pod

Flags:
  -h, --help   Help for debug

Additional Flags:
  -v, --v Level              Number for the log level verbosity. Level varies from 0 to 9 (default 0).
      --vmodule moduleSpec   Comma-separated list of pattern=N settings for file-filtered logging

Use "odo debug [command] --help" for more information about a command.
```

**Which issue(s) this PR fixes**:

Closes https://github.com/openshift/odo/issues/3871

**PR acceptance criteria**:

- [ ] Unit test

- [ ] Integration test

- [ ] Documentation

- [ ] I have read the [test guidelines](https://github.com/openshift/odo/blob/master/docs/dev/test-architecture.adoc)

**How to test changes / Special notes to the reviewer**:

openshift-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **cdrage**
You can assign the PR to them by writing `/assign @cdrage` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=openshift%2Fodo).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/openshift/odo/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["cdrage"]} -->
girishramnani: /approve
openshift-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/openshift/odo/pull/3963#issuecomment-693575380" title="Approved">girishramnani</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=openshift%2Fodo).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/openshift/odo/blob/master/OWNERS)~~ [girishramnani]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/docs/file-reference/index.md b/docs/file-reference/index.md
index 87827f186..e2059ca2e 100644
--- a/docs/file-reference/index.md
+++ b/docs/file-reference/index.md
@@ -101,8 +101,8 @@ starterProjects:
 
 ```yaml
 components:
-  - container:
-      name: appsodyrun
+  - name: appsodyrun
+    container:
       image: 'ajymau/java-openliberty-dev:latest'
       memoryLimit: 1512Mi
       mountSources: true
@@ -130,7 +130,8 @@ components:
 
 ```yaml
 commands:
-  - exec:
+  - id: devBuild
+    exec:
       id: devBuild
       commandLine: "/artifacts/bin/build-container-full.sh"
       component: tools
@@ -138,8 +139,8 @@ commands:
       group:
         kind: build
         isDefault: true
-  - exec:
-      id: devRun
+  - id: devRun
+    exec:
       commandLine: "/artifacts/bin/start-server.sh"
       component: runtime
       workingDir: /
@@ -159,28 +160,28 @@ commands:
 
 ```yaml
 commands:
-  - exec:
-      id: copy
+  - id: copy
+    exec:
       commandLine: "cp /tools/myfile.txt tools.txt"
       component: tools
       workingDir: /
-  - exec:
-      id: initCache
+  - id: initCache
+    exec:
       commandLine: "./init_cache.sh"
       component: tools
       workingDir: /
-  - exec:
-      id: connectDB
+  - id: connectDB
+    exec:
       commandLine: "./connect_db.sh"
       component: runtime
       workingDir: /
-  - exec:
-      id: disconnectDB
+  - id: disconnectDB
+    exec:
       commandLine: "./disconnect_db.sh"
       component: runtime
       workingDir: /
-  - exec:
-      id: cleanup
+  - id: cleanup
+    exec:
       commandLine: "./cleanup.sh"
       component: tools
       workingDir: /
@@ -336,8 +337,8 @@ starterProjects:
 
 ```yaml
 components:
-  - container:
-      name: appsodyrun
+  - name: appsodyrun
+    container:
       image: 'ajymau/java-openliberty-dev:latest'
 ```
 
@@ -355,8 +356,8 @@ Each component must use the `container` object.
 
 ```yaml
 components:
-  - container:
-      name: appsodyrun
+  - name: appsodyrun
+    container:
       image: 'ajymau/java-openliberty-dev:latest'
       memoryLimit: 1512Mi
       mountSources: true
@@ -392,8 +393,8 @@ components:
 
 ```yaml
 components:
-  - container:
-      name: appsodyrun
+  - name: appsodyrun
+    container:
       image: 'ajymau/java-openliberty-dev:latest'
       endpoints:
         - name: 9080/tcp
@@ -419,8 +420,8 @@ components:
 
 ```yaml
 components:
-  - container:
-      name: tools
+  - name: tools
+    container:
       image: maysunfaisal/springbootbuild
       memoryLimit: 768Mi
       command: ['tail']
@@ -443,8 +444,8 @@ components:
 
 ```yaml
 commands:
-  - exec:
-      id: devBuild
+  - id: devBuild
+    exec:
       component: tools
       commandLine: "/artifacts/bin/build-container-full.sh"
       workingDir: /projects/springbootproject
@@ -465,8 +466,8 @@ Each command must use the `exec` object.
 
 ```yaml
 commands:
-  - exec:
-      id: devBuild
+  - id: devBuild
+    exec:
       commandLine: "/artifacts/bin/build-container-full.sh"
       component: tools
       workingDir: /projects/springbootproject
@@ -494,8 +495,8 @@ commands:
 
 ```yaml
 commands:
-  - exec:
-      id: devBuild
+  - id: devBuild
+    exec:
       commandLine: "/artifacts/bin/build-container-full.sh"
       group:
         kind: build
@@ -513,28 +514,28 @@ commands:
 
 ```yaml
 commands:
-  - exec:
-      id: copy
+  - id: copy
+    exec:
       commandLine: "cp /tools/myfile.txt tools.txt"
       component: tools
       workingDir: /
-  - exec:
-      id: initCache
+  - id: initCache
+    exec:
       commandLine: "./init_cache.sh"
       component: tools
       workingDir: /
-  - exec:
-      id: connectDB
+  - id: connectDB
+    exec:
       commandLine: "./connect_db.sh"
       component: runtime
       workingDir: /
-  - exec:
-      id: disconnectDB
+  - id: disconnectDB
+    exec:
       commandLine: "./disconnect_db.sh"
       component: runtime
       workingDir: /
-  - exec:
-      id: cleanup
+  - id: cleanup
+    exec:
       commandLine: "./cleanup.sh"
       component: tools
       workingDir: /
@@ -572,8 +573,8 @@ List of objects which are found in multiple parts of devfile. For example, the [
 
 ```yaml
 components:
-  - container:
-      name: appsodyrun
+  - name: appsodyrun
+    container:
       image: 'ajymau/java-openliberty-dev:latest'
           targetPort: 9080
       env:
@@ -587,8 +588,8 @@ components:
 
 ```yaml
 commands:
-  - exec:
-      id: devBuild
+  - id: devBuild
+    exec:
       commandLine: "/artifacts/bin/build-container-full.sh"
       env:
         - name: FOO
diff --git a/docs/public/community.adoc b/docs/public/community.adoc
index 17b68ef1f..2f7fd54a8 100644
--- a/docs/public/community.adoc
+++ b/docs/public/community.adoc
@@ -55,8 +55,7 @@ https://groups.google.com/forum/#!forum/odo-dev[odo-dev Google group].
 
 === Where do I start?
 
-odo is a complex project that touches both Kubernetes, OpenShift and
-Docker. We have a list of
+odo is a complex project that touches both Kubernetes and OpenShift. We have a list of
 https://github.com/openshift/odo/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22[good
 first issues] to help start.
 
diff --git a/docs/public/debugging-using-devfile.adoc b/docs/public/debugging-using-devfile.adoc
index 237be8b11..641c80273 100644
--- a/docs/public/debugging-using-devfile.adoc
+++ b/docs/public/debugging-using-devfile.adoc
@@ -5,46 +5,50 @@
 In order to use `odo debug` your devfile is required to have a `debugrun` step. Example of a nodejs devfile with a debugrun step:
 
 ```yaml
-apiVersion: 1.0.0
+schemaVersion: 2.0.0
 metadata:
-  name: test-devfile
-projects:
-  -
-    name: nodejs-starter
-    source:
-      type: git
-      location: "https://github.com/che-samples/web-nodejs-sample.git"
+  name: nodejs
+  version: 1.0.0
+starterProjects:
+  - name: nodejs-starter
+    git:
+      remotes:
+        origin: "https://github.com/odo-devfiles/nodejs-ex.git"
 components:
-  - type: dockerimage
-    image: quay.io/eclipse/che-nodejs10-ubi:nightly
-    endpoints:
-      - name: "3000/tcp"
-        port: 3000
-    alias: runtime
-    env:
-      - name: FOO
-        value: "bar"
-    memoryLimit: 1024Mi
-    mountSources: true
+  - name: runtime
+    container:
+      image: registry.access.redhat.com/ubi8/nodejs-12:1-45
+      memoryLimit: 1024Mi
+      mountSources: true
+      sourceMapping: /project
+      endpoints:
+        - name: http-3000
+          targetPort: 3000
 commands:
-  - name: devbuild
-    actions:
-      - type: exec
-        component: runtime
-        command: "npm install"
-        workdir: ${PROJECTS_ROOT}/nodejs-starter/app
-  - name: devrun
-    actions:
-      - type: exec
-        component: runtime
-        command: "nodemon app.js"
-        workdir: ${PROJECTS_ROOT}/nodejs-starter/app
-  - name: debugrun
-    actions:
-      - type: exec
-        component: runtime
-        command: "nodemon --inspect=${DEBUG_PORT}"
-        workdir: ${PROJECTS_ROOT}/nodejs-starter/
+  - id: install
+    exec:
+      component: runtime
+      commandLine: npm install
+      workingDir: /project
+      group:
+        kind: build
+        isDefault: true
+  - id: run
+    exec:
+      component: runtime
+      commandLine: npm start
+      workingDir: /project
+      group:
+        kind: run
+        isDefault: true
+  - id: debug
+    exec:
+      component: runtime
+      commandLine: npm run debug
+      workingDir: /project
+      group:
+        kind: debug
+        isDefault: true
 ```
 
 - Now we need to create the component using `odo create nodejs`
diff --git a/docs/public/deploying-a-devfile-using-odo.adoc b/docs/public/deploying-a-devfile-using-odo.adoc
index df9883c0c..e04b3971b 100644
--- a/docs/public/deploying-a-devfile-using-odo.adoc
+++ b/docs/public/deploying-a-devfile-using-odo.adoc
@@ -10,7 +10,7 @@ With a devfile you can describe:
 * A list of pre-defined commands that can be run
 * Projects to initially clone
 
-odo takes this devfile and transforms it into a workspace of multiple containers running on OpenShift, Kubernetes or Docker.
+odo takes this devfile and transforms it into a workspace of multiple containers running on Kubernetes or OpenShift.
 
 Devfiles are YAML files with a defined https://devfile.github.io/devfile/_attachments/api-reference.html[schema].
 
diff --git a/docs/public/installing-odo.adoc b/docs/public/installing-odo.adoc
index 6fae53420..22ba7220b 100644
--- a/docs/public/installing-odo.adoc
+++ b/docs/public/installing-odo.adoc
@@ -1,8 +1,8 @@
 = Installing odo
 
-The following section describes how to install `odo` on different platforms using the CLI.
+The following section describes how to install `odo` on different platforms via CLI as well as IDEs.
 
-= Installing v2.0.0-beta-1 of odo
+= Installing the odo command-line tool (v2.0.0-beta-1)
 
 v2.0.0-beta-1 of odo uses **devfile** as its default deployment mechanism.
 
@@ -10,18 +10,20 @@ v2.0.0-beta-1 of odo uses **devfile** as its default deployment mechanism.
 
 === Binary installation
 
+[source,sh]
 ----
-# curl -L https://github.com/openshift/odo/releases/download/v2.0.0-beta-1/odo-linux-amd64 -o /usr/local/bin/odo
-# chmod +x /usr/local/bin/odo
+  # curl -L https://github.com/openshift/odo/releases/download/v2.0.0-beta-1/odo-linux-amd64 -o /usr/local/bin/odo
+  # chmod +x /usr/local/bin/odo
 ----
 
 == Installing odo on macOS
 
 === Binary installation
 
+[source,sh]
 ----
-# curl -L https://github.com/openshift/odo/releases/download/v2.0.0-beta-1/odo-darwin-amd64 -o /usr/local/bin/odo
-# chmod +x /usr/local/bin/odo
+  # curl -L https://github.com/openshift/odo/releases/download/v2.0.0-beta-1/odo-darwin-amd64 -o /usr/local/bin/odo
+  # chmod +x /usr/local/bin/odo
 ----
 
 == Installing odo on Windows
@@ -51,8 +53,17 @@ The following example demonstrates how to set up a path variable. Your binaries
 . Select *Path* from the *Variable* section and click *Edit*.
 . Click *New* and type `C:\go-bin` into the field or click *Browse* and select the directory, and click *OK*.
 
-= Installing v1.2.5 of odo
+= Installing odo in Visual Studio Code (VSCode)
 
-v1.2.5 of odo uses **Source-to-Image** as its default deployment mechanism.
+The https://marketplace.visualstudio.com/items?itemName=redhat.vscode-openshift-connector[OpenShift VSCode extension] uses both `odo` and the `oc` binary to interact with your Kubernetes or OpenShift cluster.
 
-Visit the latest link:https://docs.openshift.com/container-platform/4.5/cli_reference/developer_cli_odo/installing-odo.html[OpenShift documentation] for installation details.
+== Plugin installation
+
+. Launch VS Code Quick Open (Ctrl+P)
+
+. Paste the following command:
++
+[source,sh]
+----
+  $ ext install redhat.vscode-openshift-connector
+----
diff --git a/docs/public/s2i-to-devfile.adoc b/docs/public/s2i-to-devfile.adoc
new file mode 100644
index 000000000..7d619251b
--- /dev/null
+++ b/docs/public/s2i-to-devfile.adoc
@@ -0,0 +1,90 @@
+== Migrating from S2I (Source-to-Image) components to Devfile components
+
+https://devfile.github.io/[Devfiles] are new way of deploying component with odo.
+
+Existing users using S2I based components can migrate to a devfile component by following the below steps:
+
+. Change to the component directory you want to migrate:
++
+[source,sh]
+----
+ $ cd <directory-name>
+----
+
+. List the component status 
++
+[source,sh]
+----
+ $ odo list
+
+Openshift Components: 
+APP     NAME      PROJECT        TYPE       SOURCETYPE     STATE
+app     myapp     myproject      nodejs     local          Pushed
+
+----
+
+. Convert the S2I component to a devfile component by running the following command:
++
+[source,sh]
+----
+ $ odo utils convert-to-devfile
+ 
+ devfile.yaml is available in the current directory.
+
+----
+
+. Push the newly generated devfile component:
++
+[source,sh]
+----
+ $ odo push 
+ 
+ Validation
+  ✓  Validating the devfile [40136ns]
+
+ Creating Kubernetes resources for component myapp
+  ✓  Waiting for component to start [12s]
+
+ Applying URL changes
+  ✓  URL myapp-8080: http://myapp-8080-example.com/ created
+
+ Syncing to component myapp
+  ✓  Checking files for pushing [499419ns]
+  ✓  Syncing files to the component [155ms]
+
+ Executing devfile commands for component myapp
+  ✓  Executing s2i-assemble command "/opt/odo/bin/s2i-setup && /opt/odo/bin/assemble-and-restart" [47s]
+  ✓  Executing s2i-run command "/opt/odo/bin/run" [1s]
+
+ Pushing devfile component myapp
+  ✓  Changes successfully pushed to component
+
+----
+
+. Check the component status, there should be two components running both S2I and devfile:
++
+[source,sh]
+----
+ $ odo list 
+ 
+ Devfile Components: 
+ APP     NAME      PROJECT        TYPE      STATE
+ app     myapp     myproject      myapp     Pushed
+
+ Openshift Components: 
+ APP     NAME      PROJECT        TYPE       SOURCETYPE     STATE
+ app     myapp     myproject      nodejs     local          Pushed
+----
+
+. Delete the unused S2I component:
+
++
+[source,sh]
+----
+ $ odo delete --s2i --all --force
+ ✓  Deleting component myapp [277ms]
+ ✓  Component myapp from application app has been deleted
+ ✓  Config for the Component myapp has been deleted
+
+----
+
diff --git a/docs/public/using-devfile-lifecycle-events.adoc b/docs/public/using-devfile-lifecycle-events.adoc
index 79cd8bdbb..f3e7c3ffe 100644
--- a/docs/public/using-devfile-lifecycle-events.adoc
+++ b/docs/public/using-devfile-lifecycle-events.adoc
@@ -6,8 +6,8 @@ Each event is an array of devfile commands to be executed. The devfile command t
 
 ```yaml
 components:
-  - container:
-      name: runtime
+  - name: runtime
+    container:
       image: quay.io/eclipse/che-nodejs10-ubi:nightly
       memoryLimit: 1024Mi
       endpoints:
@@ -16,39 +16,39 @@ components:
       mountSources: true
       command: ['tail']
       args: [ '-f', '/dev/null']
-  - container:
-      name: "tools"
+  - name: "tools"
+    container:
       image: quay.io/eclipse/che-nodejs10-ubi:nightly
       mountSources: true
       memoryLimit: 1024Mi
 commands:
-  - exec:
-      id: copy
+  - id: copy
+    exec:
       commandLine: "cp /tools/myfile.txt tools.txt"
       component: tools
       workingDir: /
-  - exec:
-      id: initCache
+  - id: initCache
+    exec:
       commandLine: "./init_cache.sh"
       component: tools
       workingDir: /
-  - exec:
-      id: connectDB
+  - id: connectDB
+    exec:
       commandLine: "./connect_db.sh"
       component: runtime
       workingDir: /
-  - exec:
-      id: disconnectDB
+  - id: disconnectDB
+    exec:
       commandLine: "./disconnect_db.sh"
       component: runtime
       workingDir: /
-  - exec:
-      id: cleanup
+  - id: cleanup
+    exec:
       commandLine: "./cleanup.sh"
       component: tools
       workingDir: /
-  - composite:
-      id: postStartCompositeCmd
+  - id: postStartCompositeCmd
+    composite:
       label: Copy and Init Cache
       commands:
         - copy
diff --git a/go.mod b/go.mod
index 4e6c85b1f..17cbed70a 100644
--- a/go.mod
+++ b/go.mod
@@ -58,6 +58,7 @@ require (
 )
 
 replace (
+	bitbucket.org/ww/goautoneg => github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d
 	github.com/apcera/gssapi => github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b
 	github.com/containers/image => github.com/openshift/containers-image v0.0.0-20190130162819-76de87591e9d
 	github.com/docker/docker => github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
diff --git a/go.sum b/go.sum
index c9960a8c9..239000769 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,4 @@
 bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM=
-bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c/go.mod h1:1vhO7Mn/FZMgOgDVGLy5X1mE6rq1HbkBdkF/yj8zkcg=
 bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg=
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
diff --git a/pkg/devfile/adapters/common/command.go b/pkg/devfile/adapters/common/command.go
index ad6426872..7e2b3afef 100644
--- a/pkg/devfile/adapters/common/command.go
+++ b/pkg/devfile/adapters/common/command.go
@@ -75,7 +75,7 @@ func getCommandFromDevfile(data data.DevfileData, groupType common.DevfileComman
 		cmdGroup := command.GetGroup()
 		if cmdGroup != nil && cmdGroup.Kind == groupType {
 			if cmdGroup.IsDefault {
-				return command, ValidateCommand(data, command)
+				return command, nil
 			} else if reflect.DeepEqual(onlyCommand, common.DevfileCommand{}) {
 				// return the only remaining command for the group if there is no default command
 				// NOTE: we return outside the for loop since the next iteration can have a default command
@@ -86,7 +86,7 @@ func getCommandFromDevfile(data data.DevfileData, groupType common.DevfileComman
 
 	// if default command is not found return the first command found for the matching type.
 	if !reflect.DeepEqual(onlyCommand, common.DevfileCommand{}) {
-		return onlyCommand, ValidateCommand(data, onlyCommand)
+		return onlyCommand, nil
 	}
 
 	msg := fmt.Sprintf("the command group of kind \"%v\" is not found in the devfile", groupType)
@@ -121,7 +121,7 @@ func getCommandFromFlag(data data.DevfileData, groupType common.DevfileCommandGr
 				return command, fmt.Errorf("command group mismatched, command %s is of group %v in devfile.yaml", commandName, command.Exec.Group.Kind)
 			}
 
-			return command, ValidateCommand(data, command)
+			return command, nil
 		}
 	}
 
@@ -160,94 +160,6 @@ func validateCommandsForGroup(data data.DevfileData, groupType common.DevfileCom
 	return nil
 }
 
-// ValidateCommand validates the given command
-// 1. command has to be of type exec or composite, if composite command is validated further
-// 2. component should be present
-// 3. commandline should be present
-// 4. command must map to a valid container component
-func ValidateCommand(data data.DevfileData, command common.DevfileCommand) (err error) {
-
-	// type must be exec or composite
-	if command.Exec == nil && command.Composite == nil {
-		return fmt.Errorf("command must be of type \"exec\" or \"composite\"")
-	}
-
-	// If the command is a composite command, need to validate that it is valid
-	if command.Composite != nil {
-		parentCommands := make(map[string]string)
-		commandsMap := data.GetCommands()
-		return validateCompositeCommand(data, &command, parentCommands, commandsMap)
-	}
-
-	// component must be specified
-	if command.Exec.Component == "" {
-		return fmt.Errorf("exec commands must reference a component")
-	}
-
-	// must specify a command
-	if command.Exec.CommandLine == "" {
-		return fmt.Errorf("exec commands must have a command")
-	}
-
-	// must map to a container component
-	components := GetDevfileContainerComponents(data)
-
-	isComponentValid := false
-	for _, component := range components {
-		if command.Exec.Component == component.Name {
-			isComponentValid = true
-		}
-	}
-	if !isComponentValid {
-		return fmt.Errorf("the command does not map to a supported component")
-	}
-
-	return
-}
-
-// validateCompositeCommand checks that the specified composite command is valid
-func validateCompositeCommand(data data.DevfileData, compositeCommand *common.DevfileCommand, parentCommands map[string]string, devfileCommands map[string]common.DevfileCommand) error {
-	if compositeCommand.Composite.Group != nil && compositeCommand.Composite.Group.Kind == common.RunCommandGroupType {
-		return fmt.Errorf("composite commands of run Kind are not supported currently")
-	}
-
-	// Store the command ID in a map of parent commands
-	parentCommands[compositeCommand.Id] = compositeCommand.Id
-
-	// Loop over the commands and validate that each command points to a command that's in the devfile
-	for _, command := range compositeCommand.Composite.Commands {
-		if strings.ToLower(command) == compositeCommand.Id {
-			return fmt.Errorf("the composite command %q cannot reference itself", compositeCommand.Id)
-		}
-
-		// Don't allow commands to indirectly reference themselves, so check if the command equals any of the parent commands in the command tree
-		_, ok := parentCommands[strings.ToLower(command)]
-		if ok {
-			return fmt.Errorf("the composite command %q cannot indirectly reference itself", compositeCommand.Id)
-		}
-
-		subCommand, ok := devfileCommands[strings.ToLower(command)]
-		if !ok {
-			return fmt.Errorf("the command %q mentioned in the composite command %q does not exist in the devfile", command, compositeCommand.Id)
-		}
-
-		if subCommand.Composite != nil {
-			// Recursively validate the composite subcommand
-			err := validateCompositeCommand(data, &subCommand, parentCommands, devfileCommands)
-			if err != nil {
-				// Don't wrap the error message here to make the error message more readable to the user
-				return err
-			}
-		} else {
-			err := ValidateCommand(data, subCommand)
-			if err != nil {
-				return errors.Wrapf(err, "the composite command %q references an invalid command %q", compositeCommand.Id, subCommand.GetID())
-			}
-		}
-	}
-	return nil
-}
-
 // GetBuildCommand iterates through the components in the devfile and returns the build command
 func GetBuildCommand(data data.DevfileData, devfileBuildCmd string) (buildCommand common.DevfileCommand, err error) {
 
diff --git a/pkg/devfile/adapters/common/utils.go b/pkg/devfile/adapters/common/utils.go
index e55bd78e4..9d1155dec 100644
--- a/pkg/devfile/adapters/common/utils.go
+++ b/pkg/devfile/adapters/common/utils.go
@@ -61,7 +61,7 @@ const (
 	// BinBash The path to sh executable
 	BinBash = "/bin/sh"
 
-	// Default volume size for volumes defined in a devfile
+	// DefaultVolumeSize Default volume size for volumes defined in a devfile
 	DefaultVolumeSize = "1Gi"
 
 	// EnvProjectsRoot is the env defined for /projects where component mountSources=true
@@ -107,25 +107,6 @@ type CommandNames struct {
 	AdapterName string
 }
 
-// isContainer checks if the component is a container
-func isContainer(component common.DevfileComponent) bool {
-	// Currently odo only uses devfile components of type container, since most of the Che registry devfiles use it
-	if component.Container != nil {
-		klog.V(2).Infof("Found component \"%v\" with name \"%v\"\n", common.ContainerComponentType, component.Name)
-		return true
-	}
-	return false
-}
-
-// isVolume checks if the component is a volume
-func isVolume(component common.DevfileComponent) bool {
-	if component.Volume != nil {
-		klog.V(2).Infof("Found component \"%v\" with name \"%v\"\n", common.VolumeComponentType, component.Name)
-		return true
-	}
-	return false
-}
-
 // GetBootstrapperImage returns the odo-init bootstrapper image
 func GetBootstrapperImage() string {
 	if env, ok := os.LookupEnv(bootstrapperImageEnvName); ok {
@@ -139,7 +120,7 @@ func GetDevfileContainerComponents(data data.DevfileData) []common.DevfileCompon
 	var components []common.DevfileComponent
 	// Only components with aliases are considered because without an alias commands cannot reference them
 	for _, comp := range data.GetAliasedComponents() {
-		if isContainer(comp) {
+		if comp.IsContainer() {
 			components = append(components, comp)
 		}
 	}
@@ -151,7 +132,7 @@ func GetDevfileVolumeComponents(data data.DevfileData) map[string]common.Devfile
 	volumeNameToVolumeComponent := make(map[string]common.DevfileComponent)
 	// Only components with aliases are considered because without an alias commands cannot reference them
 	for _, comp := range data.GetComponents() {
-		if isVolume(comp) {
+		if comp.IsVolume() {
 			volumeNameToVolumeComponent[comp.Name] = comp
 		}
 	}
diff --git a/pkg/devfile/parse.go b/pkg/devfile/parse.go
index 05b40ca44..296d3a20a 100644
--- a/pkg/devfile/parse.go
+++ b/pkg/devfile/parse.go
@@ -22,12 +22,8 @@ func ParseFromURLAndValidate(url string) (d parser.DevfileObj, err error) {
 
 	// odo specific validation on devfile content
 	err = validate.ValidateDevfileData(d.Data)
-	if err != nil {
-		return d, err
-	}
 
-	// Successful
-	return d, nil
+	return d, err
 }
 
 // ParseFromDataAndValidate func parses the devfile data
@@ -43,12 +39,8 @@ func ParseFromDataAndValidate(data []byte) (d parser.DevfileObj, err error) {
 
 	// odo specific validation on devfile content
 	err = validate.ValidateDevfileData(d.Data)
-	if err != nil {
-		return d, err
-	}
 
-	// Successful
-	return d, nil
+	return d, err
 }
 
 // ParseAndValidate func parses the devfile data
@@ -65,10 +57,6 @@ func ParseAndValidate(path string) (d parser.DevfileObj, err error) {
 
 	// odo specific validation on devfile content
 	err = validate.ValidateDevfileData(d.Data)
-	if err != nil {
-		return d, err
-	}
 
-	// Successful
-	return d, nil
+	return d, err
 }
diff --git a/pkg/devfile/parser/data/2.0.0/components.go b/pkg/devfile/parser/data/2.0.0/components.go
index febc940a0..9377539f8 100644
--- a/pkg/devfile/parser/data/2.0.0/components.go
+++ b/pkg/devfile/parser/data/2.0.0/components.go
@@ -140,7 +140,6 @@ func (d *Devfile200) GetCommands() map[string]common.DevfileCommand {
 		// cases efficiently without being error prone
 		// we also convert the odo push commands from build-command and run-command flags
 		commands[command.SetIDToLower()] = command
-
 	}
 
 	return commands
diff --git a/pkg/devfile/parser/data/common/component_helper.go b/pkg/devfile/parser/data/common/component_helper.go
new file mode 100644
index 000000000..d7509ad74
--- /dev/null
+++ b/pkg/devfile/parser/data/common/component_helper.go
@@ -0,0 +1,22 @@
+package common
+
+import "k8s.io/klog"
+
+// IsContainer checks if the component is a container
+func (component DevfileComponent) IsContainer() bool {
+	// Currently odo only uses devfile components of type container, since most of the Che registry devfiles use it
+	if component.Container != nil {
+		klog.V(2).Infof("Found component \"%v\" with name \"%v\"\n", ContainerComponentType, component.Name)
+		return true
+	}
+	return false
+}
+
+// IsVolume checks if the component is a volume
+func (component DevfileComponent) IsVolume() bool {
+	if component.Volume != nil {
+		klog.V(2).Infof("Found component \"%v\" with name \"%v\"\n", VolumeComponentType, component.Name)
+		return true
+	}
+	return false
+}
diff --git a/pkg/devfile/validate/commands.go b/pkg/devfile/validate/commands.go
new file mode 100644
index 000000000..a54150173
--- /dev/null
+++ b/pkg/devfile/validate/commands.go
@@ -0,0 +1,105 @@
+package validate
+
+import (
+	"strings"
+
+	"github.com/openshift/odo/pkg/devfile/parser/data/common"
+)
+
+// validateCommands validates all the devfile commands
+func validateCommands(commands map[string]common.DevfileCommand, components []common.DevfileComponent) (err error) {
+
+	for _, command := range commands {
+		err = validateCommand(command, commands, components)
+		if err != nil {
+			return err
+		}
+	}
+
+	return
+}
+
+// validateCommand validates the given command
+// 1. command has to be of type exec or composite, if composite command is validated further
+// 2. component should be present
+// 3. commandline should be present
+// 4. command must map to a valid container component
+func validateCommand(command common.DevfileCommand, devfileCommands map[string]common.DevfileCommand, components []common.DevfileComponent) (err error) {
+
+	// type must be exec or composite
+	if command.Exec == nil && command.Composite == nil {
+		return &UnsupportedOdoCommandError{commandId: command.GetID()}
+	}
+
+	// If the command is a composite command, need to validate that it is valid
+	if command.Composite != nil {
+		parentCommands := make(map[string]string)
+		return validateCompositeCommand(&command, parentCommands, devfileCommands, components)
+	}
+
+	// component must be specified
+	if command.Exec.Component == "" {
+		return &ExecCommandMissingComponentError{commandId: command.GetID()}
+	}
+
+	// must specify a command
+	if command.Exec.CommandLine == "" {
+		return &ExecCommandMissingCommandLineError{commandId: command.GetID()}
+	}
+
+	// must map to a container component
+	isComponentValid := false
+	for _, component := range components {
+		if component.IsContainer() && command.Exec.Component == component.Name {
+			isComponentValid = true
+		}
+	}
+	if !isComponentValid {
+		return &ExecCommandInvalidContainerError{commandId: command.GetID()}
+	}
+
+	return
+}
+
+// validateCompositeCommand checks that the specified composite command is valid
+func validateCompositeCommand(compositeCommand *common.DevfileCommand, parentCommands map[string]string, devfileCommands map[string]common.DevfileCommand, components []common.DevfileComponent) error {
+	if compositeCommand.Composite.Group != nil && compositeCommand.Composite.Group.Kind == common.RunCommandGroupType {
+		return &CompositeRunKindError{}
+	}
+
+	// Store the command ID in a map of parent commands
+	parentCommands[compositeCommand.Id] = compositeCommand.Id
+
+	// Loop over the commands and validate that each command points to a command that's in the devfile
+	for _, command := range compositeCommand.Composite.Commands {
+		if strings.ToLower(command) == compositeCommand.Id {
+			return &CompositeDirectReferenceError{commandId: compositeCommand.Id}
+		}
+
+		// Don't allow commands to indirectly reference themselves, so check if the command equals any of the parent commands in the command tree
+		_, ok := parentCommands[strings.ToLower(command)]
+		if ok {
+			return &CompositeIndirectReferenceError{commandId: compositeCommand.Id}
+		}
+
+		subCommand, ok := devfileCommands[strings.ToLower(command)]
+		if !ok {
+			return &CompositeMissingSubCommandError{commandId: compositeCommand.Id, subCommand: command}
+		}
+
+		if subCommand.Composite != nil {
+			// Recursively validate the composite subcommand
+			err := validateCompositeCommand(&subCommand, parentCommands, devfileCommands, components)
+			if err != nil {
+				// Don't wrap the error message here to make the error message more readable to the user
+				return err
+			}
+		} else {
+			err := validateCommand(subCommand, devfileCommands, components)
+			if err != nil {
+				return &CompositeInvalidSubCommandError{commandId: compositeCommand.Id, subCommandId: subCommand.GetID(), errorMsg: err.Error()}
+			}
+		}
+	}
+	return nil
+}
diff --git a/pkg/devfile/validate/errors.go b/pkg/devfile/validate/errors.go
index bb2dfa163..61b5fc40a 100644
--- a/pkg/devfile/validate/errors.go
+++ b/pkg/devfile/validate/errors.go
@@ -59,3 +59,86 @@ type InvalidEventError struct {
 func (e *InvalidEventError) Error() string {
 	return fmt.Sprintf("%s type events is invalid: %s", e.eventType, e.errorMsg)
 }
+
+// UnsupportedOdoCommandError returns an error if the command is neither exec nor composite
+type UnsupportedOdoCommandError struct {
+	commandId string
+}
+
+func (e *UnsupportedOdoCommandError) Error() string {
+	return fmt.Sprintf("command %q must be of type \"exec\" or \"composite\"", e.commandId)
+}
+
+// ExecCommandMissingComponentError returns an error if the exec command does not have a component
+type ExecCommandMissingComponentError struct {
+	commandId string
+}
+
+func (e *ExecCommandMissingComponentError) Error() string {
+	return fmt.Sprintf("exec command %q must reference a component", e.commandId)
+}
+
+// ExecCommandMissingCommandLineError returns an error if the exec command does not have a command line
+type ExecCommandMissingCommandLineError struct {
+	commandId string
+}
+
+func (e *ExecCommandMissingCommandLineError) Error() string {
+	return fmt.Sprintf("exec command %q must have a command", e.commandId)
+}
+
+// ExecCommandInvalidContainerError returns an error if the exec command references an invalid container component
+type ExecCommandInvalidContainerError struct {
+	commandId string
+}
+
+func (e *ExecCommandInvalidContainerError) Error() string {
+	return fmt.Sprintf("the command %q does not map to a container component", e.commandId)
+}
+
+// CompositeRunKindError returns an error if the composite command is of kind run
+type CompositeRunKindError struct {
+}
+
+func (e *CompositeRunKindError) Error() string {
+	return "composite commands of run Kind are not supported currently"
+}
+
+// CompositeDirectReferenceError returns an error if the composite command directly references itself
+type CompositeDirectReferenceError struct {
+	commandId string
+}
+
+func (e *CompositeDirectReferenceError) Error() string {
+	return fmt.Sprintf("the composite command %q cannot reference itself", e.commandId)
+}
+
+// CompositeIndirectReferenceError returns an error if the composite command indirectly references itself
+type CompositeIndirectReferenceError struct {
+	commandId string
+}
+
+func (e *CompositeIndirectReferenceError) Error() string {
+	return fmt.Sprintf("the composite command %q cannot indirectly reference itself", e.commandId)
+}
+
+// CompositeMissingSubCommandError returns an error if the composite command has a missing sub command
+type CompositeMissingSubCommandError struct {
+	commandId  string
+	subCommand string
+}
+
+func (e *CompositeMissingSubCommandError) Error() string {
+	return fmt.Sprintf("the command %q mentioned in the composite command %q does not exist in the devfile", e.subCommand, e.commandId)
+}
+
+// CompositeInvalidSubCommandError returns an error if the composite command references an invalid sub command
+type CompositeInvalidSubCommandError struct {
+	commandId    string
+	subCommandId string
+	errorMsg     string
+}
+
+func (e *CompositeInvalidSubCommandError) Error() string {
+	return fmt.Sprintf("the composite command %q references an invalid command %q: %s", e.commandId, e.subCommandId, e.errorMsg)
+}
diff --git a/pkg/devfile/validate/events.go b/pkg/devfile/validate/events.go
index bd53c97e6..e002182f8 100644
--- a/pkg/devfile/validate/events.go
+++ b/pkg/devfile/validate/events.go
@@ -4,39 +4,37 @@ import (
 	"fmt"
 	"strings"
 
-	adapterCommon "github.com/openshift/odo/pkg/devfile/adapters/common"
-	"github.com/openshift/odo/pkg/devfile/parser/data"
+	"github.com/openshift/odo/pkg/devfile/parser/data/common"
 	"k8s.io/klog"
 )
 
 // validateEvents validates all the devfile events
-func validateEvents(data data.DevfileData) error {
+func validateEvents(events common.DevfileEvents, commands map[string]common.DevfileCommand, components []common.DevfileComponent) error {
 
 	eventErrors := ""
-	events := data.GetEvents()
 
 	switch {
 	case len(events.PreStart) > 0:
 		klog.V(2).Info("Validating preStart events")
-		if preStartErr := isEventValid(data, events.PreStart, "preStart"); preStartErr != nil {
+		if preStartErr := isEventValid(events.PreStart, "preStart", commands, components); preStartErr != nil {
 			eventErrors += fmt.Sprintf("\n%s", preStartErr.Error())
 		}
 		fallthrough
 	case len(events.PostStart) > 0:
 		klog.V(2).Info("Validating postStart events")
-		if postStartErr := isEventValid(data, events.PostStart, "postStart"); postStartErr != nil {
+		if postStartErr := isEventValid(events.PostStart, "postStart", commands, components); postStartErr != nil {
 			eventErrors += fmt.Sprintf("\n%s", postStartErr.Error())
 		}
 		fallthrough
 	case len(events.PreStop) > 0:
 		klog.V(2).Info("Validating preStop events")
-		if preStopErr := isEventValid(data, events.PreStop, "preStop"); preStopErr != nil {
+		if preStopErr := isEventValid(events.PreStop, "preStop", commands, components); preStopErr != nil {
 			eventErrors += fmt.Sprintf("\n%s", preStopErr.Error())
 		}
 		fallthrough
 	case len(events.PostStop) > 0:
 		klog.V(2).Info("Validating postStop events")
-		if postStopErr := isEventValid(data, events.PostStop, "postStop"); postStopErr != nil {
+		if postStopErr := isEventValid(events.PostStop, "postStop", commands, components); postStopErr != nil {
 			eventErrors += fmt.Sprintf("\n%s", postStopErr.Error())
 		}
 	}
@@ -52,10 +50,9 @@ func validateEvents(data data.DevfileData) error {
 // isEventValid checks if events belonging to a specific event type are valid:
 // 1. Event should map to a valid devfile command
 // 2. Event commands should be valid
-func isEventValid(data data.DevfileData, eventNames []string, eventType string) error {
+func isEventValid(eventNames []string, eventType string, commands map[string]common.DevfileCommand, components []common.DevfileComponent) error {
 	eventErrorMsg := make(map[string][]string)
 	eventErrors := ""
-	commands := data.GetCommands()
 
 	for _, eventName := range eventNames {
 		isEventPresent := false
@@ -65,7 +62,7 @@ func isEventValid(data data.DevfileData, eventNames []string, eventType string)
 				isEventPresent = true
 
 				// Check if the devfile command is valid
-				err := adapterCommon.ValidateCommand(data, command)
+				err := validateCommand(command, commands, components)
 				if err != nil {
 					klog.V(2).Infof("command %s is not valid: %s", command.GetID(), err.Error())
 					eventErrorMsg[strings.ToLower(eventName)] = append(eventErrorMsg[strings.ToLower(eventName)], err.Error())
diff --git a/pkg/devfile/validate/validate.go b/pkg/devfile/validate/validate.go
index 970fd2866..b523ec93c 100644
--- a/pkg/devfile/validate/validate.go
+++ b/pkg/devfile/validate/validate.go
@@ -12,24 +12,33 @@ import (
 // ValidateDevfileData validates whether sections of devfile are odo compatible
 func ValidateDevfileData(data interface{}) error {
 	var components []common.DevfileComponent
+	var commands map[string]common.DevfileCommand
+	var events common.DevfileEvents
 
 	switch d := data.(type) {
 	case *v200.Devfile200:
 		components = d.GetComponents()
+		commands = d.GetCommands()
+		events = d.GetEvents()
 
-		// Validate Events
-		if err := validateEvents(d); err != nil {
+		// Validate all the devfile components before validating commands
+		if err := validateComponents(components); err != nil {
+			return err
+		}
+
+		// Validate all the devfile commands before validating events
+		if err := validateCommands(commands, components); err != nil {
+			return err
+		}
+
+		// Validate all the events
+		if err := validateEvents(events, commands, components); err != nil {
 			return err
 		}
 	default:
 		return fmt.Errorf("unknown devfile type %T", d)
 	}
 
-	// Validate Components
-	if err := validateComponents(components); err != nil {
-		return err
-	}
-
 	// Successful
 	klog.V(2).Info("Successfully validated devfile sections")
 	return nil
diff --git a/pkg/envinfo/envinfo.go b/pkg/envinfo/envinfo.go
index 102d3ac02..979ff5cad 100644
--- a/pkg/envinfo/envinfo.go
+++ b/pkg/envinfo/envinfo.go
@@ -19,7 +19,7 @@ import (
 type ComponentSettings struct {
 	Name string `yaml:"Name,omitempty"`
 
-	Namespace   string              `yaml:"Namespace,omitempty"`
+	Project     string              `yaml:"Project,omitempty"`
 	URL         *[]EnvInfoURL       `yaml:"Url,omitempty"`
 	PushCommand *EnvInfoPushCommand `yaml:"PushCommand,omitempty"`
 	// AppName is the application name. Application is a virtual concept present in odo used
@@ -208,9 +208,9 @@ func (esi *EnvSpecificInfo) SetConfiguration(parameter string, value interface{}
 		case "name":
 			val := value.(string)
 			esi.componentSettings.Name = val
-		case "namespace":
+		case "project":
 			val := value.(string)
-			esi.componentSettings.Namespace = val
+			esi.componentSettings.Project = val
 		case "debugport":
 			val, err := strconv.Atoi(value.(string))
 			if err != nil {
@@ -289,7 +289,7 @@ var (
 	// Mandatory parameters in the environment file (env.yaml)
 	manParams = []string{
 		"name",
-		"namespace",
+		"project",
 	}
 )
 
@@ -413,7 +413,7 @@ func (esi *EnvSpecificInfo) SetRunMode(runMode RUNMode) error {
 
 // GetNamespace returns component namespace
 func (ei *EnvInfo) GetNamespace() string {
-	return ei.componentSettings.Namespace
+	return ei.componentSettings.Project
 }
 
 // GetApplication returns the application name
@@ -434,10 +434,10 @@ const (
 	Name = "Name"
 	// NameDescription is the human-readable description for name setting
 	NameDescription = "Set this value to user-defined component name to specify the component name"
-	// Namespace is the name of the setting controlling the component namespace
-	Namespace = "Namespace"
-	// NamespaceDescription is the human-readable description for namespace setting
-	NamespaceDescription = "Set this value to user-defined namespace to let the component create under the namespace"
+	// Project is the name of the setting controlling the component project
+	Project = "Project"
+	// ProjectDescription is the human-readable description for project setting
+	ProjectDescription = "Set this value to user-defined project to let the component create under the project"
 	// DebugPort is the name of the setting controlling the component debug port
 	DebugPort = "DebugPort"
 	// DebugPortDescription s the human-readable description for debug port setting
@@ -459,7 +459,7 @@ const (
 var (
 	supportedLocalParameterDescriptions = map[string]string{
 		Name:      NameDescription,
-		Namespace: NamespaceDescription,
+		Project:   ProjectDescription,
 		DebugPort: DebugPortDescription,
 		URL:       URLDescription,
 		Push:      PushDescription,
diff --git a/pkg/kclient/pods.go b/pkg/kclient/pods.go
index 156f18ff2..654675c89 100644
--- a/pkg/kclient/pods.go
+++ b/pkg/kclient/pods.go
@@ -190,7 +190,7 @@ func (c *Client) GetOnePodFromSelector(selector string) (*corev1.Pod, error) {
 func (c *Client) GetPodLogs(podName, containerName string, followLog bool) (io.ReadCloser, error) {
 
 	// Set standard log options
-	podLogOptions := corev1.PodLogOptions{Follow: false}
+	podLogOptions := corev1.PodLogOptions{Follow: false, Container: containerName}
 
 	// If the log is being followed, set it to follow / don't wait
 	if followLog {
diff --git a/pkg/occlient/occlient.go b/pkg/occlient/occlient.go
index e533e1606..6bf4bcd48 100644
--- a/pkg/occlient/occlient.go
+++ b/pkg/occlient/occlient.go
@@ -601,7 +601,21 @@ func getExposedPortsFromISI(image *imagev1.ImageStreamImage) ([]corev1.Container
 
 	var ports []corev1.ContainerPort
 
-	for exposedPort := range image.Image.DockerImageMetadata.Object.(*dockerapiv10.DockerImage).ContainerConfig.ExposedPorts {
+	var exposedPorts = image.Image.DockerImageMetadata.Object.(*dockerapiv10.DockerImage).ContainerConfig.ExposedPorts
+
+	if image.Image.DockerImageMetadata.Object.(*dockerapiv10.DockerImage).Config != nil {
+		if exposedPorts == nil {
+			exposedPorts = make(map[string]struct{})
+		}
+
+		// add ports from Config
+		for exposedPort := range image.Image.DockerImageMetadata.Object.(*dockerapiv10.DockerImage).Config.ExposedPorts {
+			var emptyStruct struct{}
+			exposedPorts[exposedPort] = emptyStruct
+		}
+	}
+
+	for exposedPort := range exposedPorts {
 		splits := strings.Split(exposedPort, "/")
 		if len(splits) != 2 {
 			return nil, fmt.Errorf("invalid port %s", exposedPort)
diff --git a/pkg/odo/cli/component/common_push.go b/pkg/odo/cli/component/common_push.go
index bfdd34e27..a15416850 100644
--- a/pkg/odo/cli/component/common_push.go
+++ b/pkg/odo/cli/component/common_push.go
@@ -358,7 +358,7 @@ func retrieveKubernetesDefaultNamespace() (string, error) {
 	return client.Namespace, nil
 }
 
-// retrieveCmdNamespace retrieves the namespace from project or namespace, if neither of those are available
+// retrieveCmdNamespace retrieves the namespace from project flag, if unset
 // we revert to the default namespace available from Kubernetes
 func retrieveCmdNamespace(cmd *cobra.Command) (string, error) {
 	var componentNamespace string
@@ -370,12 +370,6 @@ func retrieveCmdNamespace(cmd *cobra.Command) (string, error) {
 		if err != nil {
 			return "", err
 		}
-	} else if cmd.Flags().Changed("namespace") {
-		// For "odo push" check to see if project has been passed
-		componentNamespace, err = cmd.Flags().GetString("namespace")
-		if err != nil {
-			return "", err
-		}
 	} else {
 		componentNamespace, err = retrieveKubernetesDefaultNamespace()
 		if err != nil {
diff --git a/pkg/odo/cli/component/create.go b/pkg/odo/cli/component/create.go
index 0cccd4229..457250424 100644
--- a/pkg/odo/cli/component/create.go
+++ b/pkg/odo/cli/component/create.go
@@ -1077,9 +1077,9 @@ func (co *CreateOptions) devfileRun() (err error) {
 
 	// Generate env file
 	err = co.EnvSpecificInfo.SetComponentSettings(envinfo.ComponentSettings{
-		Name:      co.devfileMetadata.componentName,
-		Namespace: co.devfileMetadata.componentNamespace,
-		AppName:   co.appName,
+		Name:    co.devfileMetadata.componentName,
+		Project: co.devfileMetadata.componentNamespace,
+		AppName: co.appName,
 	})
 	if err != nil {
 		return errors.Wrap(err, "failed to create env file for devfile component")
diff --git a/pkg/odo/cli/component/push.go b/pkg/odo/cli/component/push.go
index 5ed4d43e8..97a79e322 100644
--- a/pkg/odo/cli/component/push.go
+++ b/pkg/odo/cli/component/push.go
@@ -125,7 +125,7 @@ func (po *PushOptions) Complete(name string, cmd *cobra.Command, args []string)
 			}
 
 			// Create the environment file. This will actually *create* the env.yaml file in your context directory.
-			err = envFileInfo.SetComponentSettings(envinfo.ComponentSettings{Name: name, Namespace: namespace})
+			err = envFileInfo.SetComponentSettings(envinfo.ComponentSettings{Name: name, Project: namespace})
 			if err != nil {
 				return errors.Wrap(err, "failed to create env.yaml for devfile component")
 			}
@@ -243,9 +243,8 @@ func NewCmdPush(name, fullName string) *cobra.Command {
 	pushCmd.Flags().StringSliceVar(&po.ignores, "ignore", []string{}, "Files or folders to be ignored via glob expressions.")
 	pushCmd.Flags().BoolVar(&po.pushConfig, "config", false, "Use config flag to only apply config on to cluster")
 	pushCmd.Flags().BoolVar(&po.pushSource, "source", false, "Use source flag to only push latest source on to cluster")
-	pushCmd.Flags().BoolVarP(&po.forceBuild, "force-build", "f", false, "Use force-build flag to force building the component")
+	pushCmd.Flags().BoolVarP(&po.forceBuild, "force-build", "f", false, "Use force-build flag to re-sync the entire source code and re-build the component")
 
-	pushCmd.Flags().StringVar(&po.namespace, "namespace", "", "Namespace to push the component to")
 	pushCmd.Flags().StringVar(&po.devfileInitCommand, "init-command", "", "Devfile Init Command to execute")
 	pushCmd.Flags().StringVar(&po.devfileBuildCommand, "build-command", "", "Devfile Build Command to execute")
 	pushCmd.Flags().StringVar(&po.devfileRunCommand, "run-command", "", "Devfile Run Command to execute")
diff --git a/pkg/odo/cli/debug/debug.go b/pkg/odo/cli/debug/debug.go
index b945192de..08d0fc8a5 100644
--- a/pkg/odo/cli/debug/debug.go
+++ b/pkg/odo/cli/debug/debug.go
@@ -1,8 +1,11 @@
 package debug
 
 import (
+	"fmt"
+
 	"github.com/openshift/odo/pkg/odo/util"
 	"github.com/spf13/cobra"
+	ktemplates "k8s.io/kubectl/pkg/util/templates"
 )
 
 const (
@@ -12,9 +15,7 @@ const (
 	devfile = "devfile.yaml"
 )
 
-var DebugLongDesc = `Warning - Debug is currently in tech preview and hence is subject to change in future.
-
-Debug allows you to remotely debug your application`
+var debugLongDesc = ktemplates.LongDesc(`Debug allows you to remotely debug your application.`)
 
 func NewCmdDebug(name, fullName string) *cobra.Command {
 
@@ -22,9 +23,12 @@ func NewCmdDebug(name, fullName string) *cobra.Command {
 	infoCmd := NewCmdInfo(infoCommandName, util.GetFullName(fullName, infoCommandName))
 
 	debugCmd := &cobra.Command{
-		Use:     name,
-		Short:   "Debug commands",
-		Long:    DebugLongDesc,
+		Use:   name,
+		Short: "Debug commands",
+		Example: fmt.Sprintf("%s\n\n%s",
+			portforwardCmd.Example,
+			infoCmd.Example),
+		Long:    debugLongDesc,
 		Aliases: []string{"d"},
 	}
 
diff --git a/pkg/odo/cli/debug/portforward.go b/pkg/odo/cli/debug/portforward.go
index 28a33d868..14a2f409c 100644
--- a/pkg/odo/cli/debug/portforward.go
+++ b/pkg/odo/cli/debug/portforward.go
@@ -45,10 +45,7 @@ type PortForwardOptions struct {
 }
 
 var (
-	portforwardLong = templates.LongDesc(`
-			Forward a local port to a remote port on the pod where the application is listening for a debugger.
-
-			By default the local port and the remote port will be same. To change the local port you can use --local-port argument and to change the remote port use "odo config set DebugPort <port>"   		  
+	portforwardLong = templates.LongDesc(`Forward a local port to a remote port on the pod where the application is listening for a debugger. By default the local port and the remote port will be same. To change the local port you can use --local-port argument and to change the remote port use "odo env set DebugPort <port>"   		  
 	`)
 
 	portforwardExample = templates.Examples(`
diff --git a/pkg/odo/cli/env/env.go b/pkg/odo/cli/env/env.go
index 2d31d7ea7..fdbad02d2 100644
--- a/pkg/odo/cli/env/env.go
+++ b/pkg/odo/cli/env/env.go
@@ -17,8 +17,8 @@ const RecommendedCommandName = "env"
 const (
 	nameParameter                 = "Name"
 	nameParameterDescription      = "Use this value to set component name"
-	namespaceParameter            = "Namespace"
-	namespaceParameterDescription = "Use this value to set component namespace"
+	projectParameter              = "Project"
+	projectParameterDescription   = "Use this value to set component project"
 	debugportParameter            = "DebugPort"
 	debugportParameterDescription = "Use this value to set component debug port"
 )
diff --git a/pkg/odo/cli/env/set.go b/pkg/odo/cli/env/set.go
index 39edad82f..e84df934e 100644
--- a/pkg/odo/cli/env/set.go
+++ b/pkg/odo/cli/env/set.go
@@ -33,7 +33,7 @@ var (
 var (
 	supportedSetParameters = map[string]string{
 		nameParameter:      nameParameterDescription,
-		namespaceParameter: namespaceParameterDescription,
+		projectParameter:   projectParameterDescription,
 		debugportParameter: debugportParameterDescription,
 	}
 )
@@ -95,7 +95,7 @@ func (o *SetOptions) Run() (err error) {
 	}
 
 	log.Info("Environment was successfully updated")
-	if strings.ToLower(o.paramName) == "name" || strings.ToLower(o.paramName) == "namespace" {
+	if strings.ToLower(o.paramName) == "name" || strings.ToLower(o.paramName) == "project" {
 		log.Warningf("Updated %q would create a new component", o.paramName)
 	}
 
@@ -110,7 +110,7 @@ func NewCmdSet(name, fullName string) *cobra.Command {
 		Short: "Set a value in odo environment file",
 		Long:  setLongDesc + printSupportedParameters(supportedSetParameters),
 		Example: fmt.Sprintf(fmt.Sprint(setExample), fullName,
-			envinfo.Name, envinfo.Namespace, envinfo.DebugPort),
+			envinfo.Name, envinfo.Project, envinfo.DebugPort),
 		Args: func(cmd *cobra.Command, args []string) error {
 			if len(args) < 2 {
 				return fmt.Errorf("please provide a parameter name and value")
diff --git a/pkg/odo/cli/env/view.go b/pkg/odo/cli/env/view.go
index f063b1be8..e8cd30281 100644
--- a/pkg/odo/cli/env/view.go
+++ b/pkg/odo/cli/env/view.go
@@ -62,7 +62,7 @@ func (o *ViewOptions) Run() (err error) {
 	w := tabwriter.NewWriter(os.Stdout, 5, 2, 2, ' ', tabwriter.TabIndent)
 	fmt.Fprintln(w, "PARAMETER NAME", "\t", "PARAMETER VALUE")
 	fmt.Fprintln(w, "Name", "\t", cs.Name)
-	fmt.Fprintln(w, "Namespace", "\t", cs.Namespace)
+	fmt.Fprintln(w, "Project", "\t", cs.Project)
 	fmt.Fprintln(w, "DebugPort", "\t", showBlankIfNil(cs.DebugPort))
 	w.Flush()
 
diff --git a/pkg/odo/cli/url/describe.go b/pkg/odo/cli/url/describe.go
deleted file mode 100644
index fa9f13ae7..000000000
--- a/pkg/odo/cli/url/describe.go
+++ /dev/null
@@ -1,205 +0,0 @@
-package url
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"strconv"
-	"text/tabwriter"
-
-	routev1 "github.com/openshift/api/route/v1"
-	"github.com/openshift/odo/pkg/config"
-	"github.com/openshift/odo/pkg/devfile"
-	adaptersCommon "github.com/openshift/odo/pkg/devfile/adapters/common"
-	"github.com/openshift/odo/pkg/envinfo"
-	"github.com/openshift/odo/pkg/lclient"
-	"github.com/openshift/odo/pkg/log"
-	"github.com/openshift/odo/pkg/machineoutput"
-	"github.com/openshift/odo/pkg/occlient"
-	"github.com/openshift/odo/pkg/odo/cli/component"
-	"github.com/openshift/odo/pkg/odo/genericclioptions"
-	odoutil "github.com/openshift/odo/pkg/odo/util"
-	"github.com/openshift/odo/pkg/odo/util/completion"
-	"github.com/openshift/odo/pkg/odo/util/pushtarget"
-	"github.com/openshift/odo/pkg/url"
-	"github.com/openshift/odo/pkg/util"
-	"github.com/pkg/errors"
-	"github.com/spf13/cobra"
-	ktemplates "k8s.io/kubectl/pkg/util/templates"
-)
-
-// DescribeRecommendedCommandName is the recommended describe command name
-const describeRecommendedCommandName = "describe"
-
-var describeExample = ktemplates.Examples(`  # Describe a URL
-%[1]s myurl
-`)
-
-// URLDescribeOptions encapsulates the options for the odo url describe command
-type URLDescribeOptions struct {
-	localConfigInfo  *config.LocalConfigInfo
-	componentContext string
-	url              string
-	*genericclioptions.Context
-	devfilePath string
-	isDevFile   bool
-}
-
-// NewURLDescribeOptions creates a new NewURLDescribeOptions instance
-func NewURLDescribeOptions() *URLDescribeOptions {
-	return &URLDescribeOptions{&config.LocalConfigInfo{}, "", "", &genericclioptions.Context{}, "", false}
-}
-
-// Complete completes URLDescribeOptions after they've been Listed
-func (o *URLDescribeOptions) Complete(name string, cmd *cobra.Command, args []string) (err error) {
-	o.devfilePath = filepath.Join(o.componentContext, component.DevfilePath)
-
-	if util.CheckPathExists(o.devfilePath) {
-		o.Context = genericclioptions.NewDevfileContext(cmd)
-		o.EnvSpecificInfo, err = envinfo.NewEnvSpecificInfo(o.componentContext)
-	} else {
-		o.Context = genericclioptions.NewContext(cmd)
-		o.localConfigInfo, err = config.NewLocalConfigInfo(o.componentContext)
-	}
-	if err != nil {
-		return errors.Wrap(err, "failed intiating local config")
-	}
-	o.url = args[0]
-	return
-}
-
-// Validate validates the URLDescribeOptions based on completed values
-func (o *URLDescribeOptions) Validate() (err error) {
-	return odoutil.CheckOutputFlag(o.OutputFlag)
-}
-
-// Run contains the logic for the odo url describe command
-func (o *URLDescribeOptions) Run() (err error) {
-	if util.CheckPathExists(o.devfilePath) {
-		if pushtarget.IsPushTargetDocker() {
-			client, err := lclient.New()
-			if err != nil {
-				return err
-			}
-			u, err := url.GetContainerURL(client, o.EnvSpecificInfo, o.url, o.EnvSpecificInfo.GetName())
-			if err != nil {
-				return err
-			}
-
-			if log.IsJSON() {
-				machineoutput.OutputSuccess(u)
-			} else {
-				tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent)
-				fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT")
-				var urlString string
-				if u.Status.State == url.StateTypeNotPushed {
-					// to be consistent with URL for ingress and routes
-					// if not pushed, display URl as ://
-					urlString = "://"
-				} else {
-					urlString = fmt.Sprintf("%s:%s", u.Spec.Host, strconv.Itoa(u.Spec.ExternalPort))
-				}
-				// are there changes between local and cluster states?
-				outOfSync := false
-				fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", urlString, "\t", u.Spec.Port)
-				if u.Status.State != url.StateTypePushed {
-					outOfSync = true
-				}
-				tabWriterURL.Flush()
-				if outOfSync {
-					log.Info("There are local changes. Please run 'odo push'.")
-				}
-			}
-		} else {
-			componentName := o.EnvSpecificInfo.GetName()
-			oclient, err := occlient.New()
-			if err != nil {
-				return err
-			}
-			oclient.Namespace = o.KClient.Namespace
-			routeSupported, err := oclient.IsRouteSupported()
-			if err != nil {
-				return err
-			}
-
-			devObj, err := devfile.ParseAndValidate(o.devfilePath)
-			if err != nil {
-				return errors.Wrap(err, "fail to parse the devfile")
-			}
-			containerComponents := adaptersCommon.GetDevfileContainerComponents(devObj.Data)
-			u, err := url.GetIngressOrRoute(oclient, o.KClient, o.EnvSpecificInfo, o.url, containerComponents, componentName, routeSupported)
-			if err != nil {
-				return err
-			}
-			if log.IsJSON() {
-				machineoutput.OutputSuccess(u)
-			} else {
-				tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent)
-				fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT", "\t", "SECURE", "\t", "KIND")
-
-				// are there changes between local and cluster states?
-				outOfSync := false
-				if u.Spec.Kind == envinfo.ROUTE {
-					fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, "", false), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind)
-				} else {
-					fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(url.GetProtocol(routev1.Route{}, url.ConvertIngressURLToIngress(u, componentName)), "", u.Spec.Host, false), "\t", u.Spec.Port, "\t", u.Spec.Secure, "\t", u.Spec.Kind)
-				}
-				if u.Status.State != url.StateTypePushed {
-					outOfSync = true
-				}
-				tabWriterURL.Flush()
-				if outOfSync {
-					log.Info("There are local changes. Please run 'odo push'.")
-				}
-			}
-		}
-	} else {
-		u, err := url.Get(o.Client, o.localConfigInfo, o.url, o.Application)
-		if err != nil {
-			return err
-		}
-
-		if log.IsJSON() {
-			machineoutput.OutputSuccess(u)
-		} else {
-
-			tabWriterURL := tabwriter.NewWriter(os.Stdout, 5, 2, 3, ' ', tabwriter.TabIndent)
-			fmt.Fprintln(tabWriterURL, "NAME", "\t", "STATE", "\t", "URL", "\t", "PORT")
-
-			// are there changes between local and cluster states?
-			outOfSync := false
-			fmt.Fprintln(tabWriterURL, u.Name, "\t", u.Status.State, "\t", url.GetURLString(u.Spec.Protocol, u.Spec.Host, "", false), "\t", u.Spec.Port)
-			if u.Status.State != url.StateTypePushed {
-				outOfSync = true
-			}
-			tabWriterURL.Flush()
-			if outOfSync {
-				log.Info("There are local changes. Please run 'odo push'.")
-			}
-		}
-	}
-
-	return
-}
-
-// NewCmdURLDescribe implements the odo url describe command.
-func NewCmdURLDescribe(name, fullName string) *cobra.Command {
-	o := NewURLDescribeOptions()
-	urlDescribeCmd := &cobra.Command{
-		Use:         name + " [url name]",
-		Short:       "Describe a URL",
-		Long:        `Describe a URL`,
-		Example:     fmt.Sprintf(describeExample, fullName),
-		Args:        cobra.ExactArgs(1),
-		Annotations: map[string]string{"machineoutput": "json", "command": "url"},
-		Run: func(cmd *cobra.Command, args []string) {
-			genericclioptions.GenericRun(o, cmd, args)
-		},
-	}
-	urlDescribeCmd.SetUsageTemplate(odoutil.CmdUsageTemplate)
-	genericclioptions.AddContextFlag(urlDescribeCmd, &o.componentContext)
-	completion.RegisterCommandHandler(urlDescribeCmd, completion.URLCompletionHandler)
-	completion.RegisterCommandFlagHandler(urlDescribeCmd, "context", completion.FileCompletionHandler)
-
-	return urlDescribeCmd
-}
diff --git a/pkg/odo/cli/url/url.go b/pkg/odo/cli/url/url.go
index 19babb234..f8fed463e 100644
--- a/pkg/odo/cli/url/url.go
+++ b/pkg/odo/cli/url/url.go
@@ -24,22 +24,21 @@ func NewCmdURL(name, fullName string) *cobra.Command {
 	urlCreateCmd := NewCmdURLCreate(createRecommendedCommandName, odoutil.GetFullName(fullName, createRecommendedCommandName))
 	urlDeleteCmd := NewCmdURLDelete(deleteRecommendedCommandName, odoutil.GetFullName(fullName, deleteRecommendedCommandName))
 	urlListCmd := NewCmdURLList(listRecommendedCommandName, odoutil.GetFullName(fullName, listRecommendedCommandName))
-	urlDescribeCmd := NewCmdURLDescribe(describeRecommendedCommandName, odoutil.GetFullName(fullName, describeRecommendedCommandName))
 	urlCmd := &cobra.Command{
 		Use:   name,
 		Short: urlShortDesc,
 		Long:  urlLongDesc,
-		Example: fmt.Sprintf("%s\n\n%s\n\n%s\n\n%s",
+		Example: fmt.Sprintf("%s\n\n%s\n\n%s",
 			urlCreateCmd.Example,
 			urlDeleteCmd.Example,
 			urlListCmd.Example,
-			urlDescribeCmd.Example),
+		),
 	}
 
 	// Add a defined annotation in order to appear in the help menu
 	urlCmd.Annotations = map[string]string{"command": "main"}
 	urlCmd.SetUsageTemplate(odoutil.CmdUsageTemplate)
-	urlCmd.AddCommand(urlCreateCmd, urlDeleteCmd, urlListCmd, urlDescribeCmd)
+	urlCmd.AddCommand(urlCreateCmd, urlDeleteCmd, urlListCmd)
 
 	return urlCmd
 }
diff --git a/pkg/odo/cli/utils/convert.go b/pkg/odo/cli/utils/convert.go
index f0d2875c4..fc9f286cc 100644
--- a/pkg/odo/cli/utils/convert.go
+++ b/pkg/odo/cli/utils/convert.go
@@ -3,8 +3,6 @@ package utils
 import (
 	"fmt"
 	"path/filepath"
-	"strconv"
-	"strings"
 
 	"github.com/fatih/color"
 	imagev1 "github.com/openshift/api/image/v1"
@@ -221,8 +219,6 @@ func generateDevfileYaml(co *ConvertOptions) error {
 func generateEnvYaml(co *ConvertOptions) (err error) {
 	klog.V(2).Info("Generating env.yaml")
 
-	// list of urls having name, ports, secure
-	urls := co.context.LocalConfigInfo.GetURL()
 	debugPort := co.context.LocalConfigInfo.GetDebugPort()
 
 	application := co.context.LocalConfigInfo.GetApplication()
@@ -233,26 +229,10 @@ func generateEnvYaml(co *ConvertOptions) (err error) {
 		return err
 	}
 
-	var urlList []envinfo.EnvInfoURL
-
-	for _, url := range urls {
-		urlEnv := envinfo.EnvInfoURL{
-			Name:   url.Name,
-			Port:   url.Port,
-			Secure: url.Secure,
-			// s2i components are only run on openshift cluster
-			Kind: envinfo.ROUTE,
-		}
-
-		urlList = append(urlList, urlEnv)
-
-	}
-
 	componentSettings := envinfo.ComponentSettings{
-		Name:      co.componentName,
-		Namespace: co.context.Project,
-		URL:       &urlList,
-		AppName:   application,
+		Name:    co.componentName,
+		Project: co.context.Project,
+		AppName: application,
 	}
 
 	if debugPort != 0 || debugPort == config.DefaultDebugPort {
@@ -330,8 +310,7 @@ func setDevfileComponentsForS2I(d data.DevfileData, s2iImage string, localConfig
 
 	maxMemory := localConfig.GetMaxMemory()
 	volumes := localConfig.GetStorage()
-	// list of ports taken from builder image and set into local config
-	ports := localConfig.GetPorts()
+	urls := localConfig.GetURL()
 
 	var endpoints []common.Endpoint
 	var envs []common.Env
@@ -368,19 +347,12 @@ func setDevfileComponentsForS2I(d data.DevfileData, s2iImage string, localConfig
 	envs = append(envs, env)
 
 	// convert s2i ports to devfile endpoints
-	for _, port := range ports {
-
-		port := strings.Split(port, "/")
-		// from s2i config.yaml port is of the form 8080/TCP
-		// Ignoring TCP and Udp values here
-		portInt, err := strconv.ParseInt(port[0], 10, 32)
-		if err != nil {
-			return errors.Wrapf(err, "Unable to convert port %s from config.yaml to devfile.yaml", port)
-		}
+	for _, url := range urls {
 
 		endpoint := common.Endpoint{
-			Name:       fmt.Sprintf("port-%s", port[0]),
-			TargetPort: int32(portInt),
+			Name:       url.Name,
+			TargetPort: int32(url.Port),
+			Secure:     url.Secure,
 		}
 
 		endpoints = append(endpoints, endpoint)
diff --git a/pkg/odo/genericclioptions/context.go b/pkg/odo/genericclioptions/context.go
index 5c2218405..19f592cf1 100644
--- a/pkg/odo/genericclioptions/context.go
+++ b/pkg/odo/genericclioptions/context.go
@@ -19,8 +19,13 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
-// DefaultAppName is the default name of the application when an application name is not provided
-const DefaultAppName = "app"
+const (
+	// DefaultAppName is the default name of the application when an application name is not provided
+	DefaultAppName = "app"
+
+	// gitDirName is the git dir name in a project
+	gitDirName = ".git"
+)
 
 // NewContext creates a new Context struct populated with the current state based on flags specified for the provided command
 func NewContext(command *cobra.Command, ignoreMissingConfiguration ...bool) *Context {
@@ -502,8 +507,8 @@ func (o *Context) checkComponentExistsOrFail(cmp string) {
 	}
 }
 
-// ApplyIgnore will take the current ignores []string and either ignore it (if .odoignore is used)
-// or find the .gitignore file in the directory and use that instead.
+// ApplyIgnore will take the current ignores []string and append the mandatory odo-file-index.json and
+// .git ignores; or find the .odoignore/.gitignore file in the directory and use that instead.
 func ApplyIgnore(ignores *[]string, sourcePath string) (err error) {
 	if len(*ignores) == 0 {
 		rules, err := pkgUtil.GetIgnoreRulesFromDirectory(sourcePath)
@@ -512,6 +517,18 @@ func ApplyIgnore(ignores *[]string, sourcePath string) (err error) {
 		}
 		*ignores = append(*ignores, rules...)
 	}
+
+	indexFile := pkgUtil.GetIndexFileRelativeToContext()
+	// check if the ignores flag has the index file
+	if !pkgUtil.In(*ignores, indexFile) {
+		*ignores = append(*ignores, indexFile)
+	}
+
+	// check if the ignores flag has the git dir
+	if !pkgUtil.In(*ignores, gitDirName) {
+		*ignores = append(*ignores, gitDirName)
+	}
+
 	return nil
 }
 
diff --git a/pkg/url/url.go b/pkg/url/url.go
index ae2535464..6466c7976 100644
--- a/pkg/url/url.go
+++ b/pkg/url/url.go
@@ -49,47 +49,6 @@ func (urls URLList) Get(urlName string) URL {
 
 }
 
-// Get returns URL definition for given URL name
-func Get(client *occlient.Client, localConfig *config.LocalConfigInfo, urlName string, applicationName string) (URL, error) {
-	remoteUrlName, err := util.NamespaceOpenShiftObject(urlName, applicationName)
-	if err != nil {
-		return URL{}, errors.Wrapf(err, "unable to create namespaced name")
-	}
-
-	// Check whether remote already created the route
-	remoteExist := true
-	route, err := client.GetRoute(remoteUrlName)
-	if err != nil {
-		remoteExist = false
-	}
-
-	localConfigURLs := localConfig.GetURL()
-	for _, configURL := range localConfigURLs {
-		localURL := ConvertConfigURL(configURL)
-		// search local URL, if it exist in local, update state with remote status
-		if localURL.Name == urlName {
-			if remoteExist {
-				clusterURL := getMachineReadableFormat(*route)
-				clusterURL.Status.State = StateTypePushed
-				return clusterURL, nil
-			} else {
-				localURL.Status.State = StateTypeNotPushed
-				return localURL, nil
-			}
-		}
-	}
-
-	if err == nil && remoteExist {
-		// Remote exist, but not in local, so it's deleted status
-		clusterURL := getMachineReadableFormat(*route)
-		clusterURL.Status.State = StateTypeLocallyDeleted
-		return clusterURL, nil
-	}
-
-	// can't find the URL in local and remote
-	return URL{}, errors.New(fmt.Sprintf("the url %v does not exist", urlName))
-}
-
 // GetIngressOrRoute returns ingress/route spec for given URL name
 func GetIngressOrRoute(client *occlient.Client, kClient *kclient.Client, envSpecificInfo *envinfo.EnvSpecificInfo, urlName string, containerComponents []common.DevfileComponent, componentName string, routeSupported bool) (URL, error) {
 	remoteExist := true
@@ -190,62 +149,6 @@ func GetIngressOrRoute(client *occlient.Client, kClient *kclient.Client, envSpec
 	return URL{}, errors.New(fmt.Sprintf("the url %v does not exist", urlName))
 }
 
-// GetContainer returns Docker URL definition for given URL name
-func GetContainerURL(client *lclient.Client, envSpecificInfo *envinfo.EnvSpecificInfo, urlName string, componentName string) (URL, error) {
-	localURLs := envSpecificInfo.GetURL()
-	containers, err := dockerutils.GetComponentContainers(*client, componentName)
-	if err != nil {
-		return URL{}, errors.Wrap(err, "unable to get component containers")
-	}
-	var remoteExist = false
-	var dockerURL URL
-	// iterating through each container's HostConfig, generate and cache the dockerURL if found a match urlName
-	for _, c := range containers {
-		containerJSON, err := client.Client.ContainerInspect(client.Context, c.ID)
-		if err != nil {
-			return URL{}, err
-		}
-		for internalPort, portbinding := range containerJSON.HostConfig.PortBindings {
-			remoteURLName := containerJSON.Config.Labels[internalPort.Port()]
-			if remoteURLName != urlName {
-				continue
-			}
-			// found urlName in Docker container's config
-			remoteExist = true
-			externalport, err := strconv.Atoi(portbinding[0].HostPort)
-			if err != nil {
-				return URL{}, err
-			}
-			dockerURL = getMachineReadableFormatDocker(internalPort.Int(), externalport, portbinding[0].HostIP, remoteURLName)
-		}
-	}
-
-	// iterating through URLs in local env.yaml
-	for _, localurl := range localURLs {
-		if localurl.Kind != envinfo.DOCKER || localurl.Name != urlName {
-			continue
-		}
-		localURL := getMachineReadableFormatDocker(localurl.Port, localurl.ExposedPort, dockercomponent.LocalhostIP, localurl.Name)
-		// found urlName in local env file
-		if remoteExist {
-			// URL is in both env file and Docker HostConfig
-			localURL.Status.State = StateTypePushed
-			return localURL, nil
-		} else {
-			// URL only exists in local env file
-			localURL.Status.State = StateTypeNotPushed
-			return localURL, nil
-		}
-	}
-	// URL only exists in pushed Docker container
-	if remoteExist {
-		dockerURL.Status.State = StateTypeLocallyDeleted
-		return dockerURL, nil
-	}
-	// can't find the URL in local env.yaml or Docker containers
-	return URL{}, errors.New(fmt.Sprintf("the url %v does not exist", urlName))
-}
-
 // Delete deletes a URL
 func Delete(client *occlient.Client, kClient *kclient.Client, urlName string, applicationName string, urlType envinfo.URLKind) error {
 	if urlType == envinfo.INGRESS {
diff --git a/pkg/util/file_indexer.go b/pkg/util/file_indexer.go
index e5f25f493..c25d13882 100644
--- a/pkg/util/file_indexer.go
+++ b/pkg/util/file_indexer.go
@@ -85,6 +85,11 @@ func ResolveIndexFilePath(directory string) (string, error) {
 	return directory, nil
 }
 
+// GetIndexFileRelativeToContext returns the index file relative to context i.e.; .odo/odo-file-index.json
+func GetIndexFileRelativeToContext() string {
+	return filepath.Join(fileIndexDirectory, fileIndexName)
+}
+
 // AddOdoFileIndex adds odo-file-index.json to .gitignore
 func AddOdoFileIndex(gitIgnoreFile string) error {
 	return addOdoFileIndex(gitIgnoreFile, filesystem.DefaultFs{})


Test patch:
diff --git a/pkg/devfile/adapters/common/command_test.go b/pkg/devfile/adapters/common/command_test.go
index 8bd15b4de..912ca21b4 100644
--- a/pkg/devfile/adapters/common/command_test.go
+++ b/pkg/devfile/adapters/common/command_test.go
@@ -5,12 +5,10 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/openshift/odo/pkg/util"
-
 	devfileParser "github.com/openshift/odo/pkg/devfile/parser"
 	"github.com/openshift/odo/pkg/devfile/parser/data/common"
-	versionsCommon "github.com/openshift/odo/pkg/devfile/parser/data/common"
 	"github.com/openshift/odo/pkg/testingutil"
+	"github.com/openshift/odo/pkg/util"
 )
 
 var buildGroup = common.BuildCommandGroupType
@@ -22,10 +20,6 @@ func TestGetCommand(t *testing.T) {
 
 	commands := [...]string{"ls -la", "pwd"}
 	components := [...]string{"alias1", "alias2"}
-	invalidComponent := "garbagealias"
-	workDir := [...]string{"/", "/root"}
-
-	emptyString := ""
 
 	tests := []struct {
 		name           string
@@ -38,7 +32,7 @@ func TestGetCommand(t *testing.T) {
 	}{
 		{
 			name: "Case 1: Valid devfile",
-			execCommands: []versionsCommon.DevfileCommand{
+			execCommands: []common.DevfileCommand{
 				getExecCommand("build", buildGroup),
 				getExecCommand("run", runGroup),
 			},
@@ -47,7 +41,7 @@ func TestGetCommand(t *testing.T) {
 		},
 		{
 			name: "Case 2: Valid devfile with devrun and devbuild",
-			execCommands: []versionsCommon.DevfileCommand{
+			execCommands: []common.DevfileCommand{
 				getExecCommand("build", buildGroup),
 				getExecCommand("run", runGroup),
 			},
@@ -55,43 +49,13 @@ func TestGetCommand(t *testing.T) {
 			wantErr:       false,
 		},
 		{
-			name: "Case 4: Invalid devfile with empty component",
-			execCommands: []versionsCommon.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: commands[0],
-						Component:   emptyString,
-						WorkingDir:  workDir[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			requestedType: []common.DevfileCommandGroupType{buildGroup},
-			wantErr:       true,
-		},
-		{
-			name: "Case 5: Invalid devfile with empty devbuild command",
-			execCommands: []versionsCommon.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: emptyString,
-						Component:   components[0],
-						WorkingDir:  workDir[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			requestedType: []common.DevfileCommandGroupType{buildGroup},
-			wantErr:       true,
-		},
-		{
-			name: "Case 6: Valid devfile with empty workdir",
+			name: "Case 3: Valid devfile with empty workdir",
 			execCommands: []common.DevfileCommand{
 				{
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -99,28 +63,14 @@ func TestGetCommand(t *testing.T) {
 			wantErr:       false,
 		},
 		{
-			name: "Case 7: Invalid command referencing an absent component",
-			execCommands: []common.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: commands[0],
-						Component:   invalidComponent,
-						Group:       &versionsCommon.Group{Kind: runGroup},
-					},
-				},
-			},
-			requestedType: []common.DevfileCommandGroupType{runGroup},
-			wantErr:       true,
-		},
-		{
-			name: "Case 8: Mismatched command type",
+			name: "Case 4: Mismatched command type",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -129,22 +79,22 @@ func TestGetCommand(t *testing.T) {
 			wantErr:        true,
 		},
 		{
-			name: "Case 9: Default command is returned",
+			name: "Case 5: Default command is returned",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "defaultRunCommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup, IsDefault: true},
+						Group:       &common.Group{Kind: runGroup, IsDefault: true},
 					},
 				},
 				{
 					Id: "runCommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -153,31 +103,31 @@ func TestGetCommand(t *testing.T) {
 			wantErr:        false,
 		},
 		{
-			name: "Case 10: Composite command is returned",
+			name: "Case 6: Composite command is returned",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup, IsDefault: false},
+						Group:       &common.Group{Kind: buildGroup, IsDefault: false},
 					},
 				},
 				{
 					Id: "run",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
 			compCommands: []common.DevfileCommand{
 				{
 					Id: "myComposite",
-					Composite: &versionsCommon.Composite{
+					Composite: &common.Composite{
 						Commands: []string{"build", "run"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: true},
 					},
 				},
 			},
@@ -189,9 +139,6 @@ func TestGetCommand(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			components := []common.DevfileComponent{testingutil.GetFakeContainerComponent(tt.execCommands[0].Exec.Component)}
-			if tt.execCommands[0].Exec.Component == invalidComponent {
-				components = []common.DevfileComponent{testingutil.GetFakeContainerComponent("randomComponent")}
-			}
 			devObj := devfileParser.DevfileObj{
 				Data: &testingutil.TestDevfileData{
 					Commands:   append(tt.execCommands, tt.compCommands...),
@@ -221,10 +168,6 @@ func TestGetCommandFromDevfile(t *testing.T) {
 
 	commands := [...]string{"ls -la", "pwd"}
 	components := [...]string{"alias1", "alias2"}
-	invalidComponent := "garbagealias"
-	workDir := [...]string{"/", "/root"}
-
-	emptyString := ""
 
 	tests := []struct {
 		name           string
@@ -236,7 +179,7 @@ func TestGetCommandFromDevfile(t *testing.T) {
 	}{
 		{
 			name: "Case 1: Valid devfile",
-			execCommands: []versionsCommon.DevfileCommand{
+			execCommands: []common.DevfileCommand{
 				getExecCommand("", buildGroup),
 				getExecCommand("", runGroup),
 			},
@@ -245,7 +188,7 @@ func TestGetCommandFromDevfile(t *testing.T) {
 		},
 		{
 			name: "Case 2: Valid devfile with devrun and devbuild",
-			execCommands: []versionsCommon.DevfileCommand{
+			execCommands: []common.DevfileCommand{
 				getExecCommand("", buildGroup),
 				getExecCommand("", runGroup),
 			},
@@ -253,43 +196,13 @@ func TestGetCommandFromDevfile(t *testing.T) {
 			wantErr:       false,
 		},
 		{
-			name: "Case 3: Invalid devfile with empty component",
-			execCommands: []versionsCommon.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: commands[0],
-						Component:   emptyString,
-						WorkingDir:  workDir[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			requestedType: []common.DevfileCommandGroupType{buildGroup},
-			wantErr:       true,
-		},
-		{
-			name: "Case 4: Invalid devfile with empty devbuild command",
-			execCommands: []versionsCommon.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: emptyString,
-						Component:   components[0],
-						WorkingDir:  workDir[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			requestedType: []common.DevfileCommandGroupType{buildGroup},
-			wantErr:       true,
-		},
-		{
-			name: "Case 5: Valid devfile with empty workdir",
+			name: "Case 3: Valid devfile with empty workdir",
 			execCommands: []common.DevfileCommand{
 				{
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -297,36 +210,22 @@ func TestGetCommandFromDevfile(t *testing.T) {
 			wantErr:       false,
 		},
 		{
-			name: "Case 6: Invalid command referencing an absent component",
-			execCommands: []common.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: commands[0],
-						Component:   invalidComponent,
-						Group:       &versionsCommon.Group{Kind: runGroup},
-					},
-				},
-			},
-			requestedType: []common.DevfileCommandGroupType{runGroup},
-			wantErr:       true,
-		},
-		{
-			name: "Case 7: Default command is returned",
+			name: "Case 4: Default command is returned",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "defaultruncommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup, IsDefault: true},
+						Group:       &common.Group{Kind: runGroup, IsDefault: true},
 					},
 				},
 				{
 					Id: "runcommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -335,39 +234,39 @@ func TestGetCommandFromDevfile(t *testing.T) {
 			wantErr:        false,
 		},
 		{
-			name: "Case 8: Valid devfile, has composite command",
+			name: "Case 5: Valid devfile, has composite command",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build1",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 				{
 					Id: "build2",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 				{
 					Id: "run",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
 			compCommands: []common.DevfileCommand{
 				{
 					Id: "mycomp",
-					Composite: &versionsCommon.Composite{
+					Composite: &common.Composite{
 						Commands: []string{"build1", "run"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: true},
 					},
 				},
 			},
@@ -376,38 +275,38 @@ func TestGetCommandFromDevfile(t *testing.T) {
 			wantErr:        false,
 		},
 		{
-			name: "Case 9: Default composite command",
+			name: "Case 6: Default composite command",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup, IsDefault: false},
+						Group:       &common.Group{Kind: buildGroup, IsDefault: false},
 					},
 				},
 				{
 					Id: "run",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
 			compCommands: []common.DevfileCommand{
 				{
 					Id: "mycomp",
-					Composite: &versionsCommon.Composite{
+					Composite: &common.Composite{
 						Commands: []string{"build", "run"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: true},
 					},
 				},
 				{
 					Id: "mycomp2",
-					Composite: &versionsCommon.Composite{
+					Composite: &common.Composite{
 						Commands: []string{"build", "run"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: false},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: false},
 					},
 				},
 			},
@@ -415,46 +314,10 @@ func TestGetCommandFromDevfile(t *testing.T) {
 			requestedType:  []common.DevfileCommandGroupType{buildGroup},
 			wantErr:        false,
 		},
-		{
-			name: "Case 10: Invalid composite command",
-			execCommands: []common.DevfileCommand{
-				{
-					Id: "build",
-					Exec: &versionsCommon.Exec{
-						CommandLine: commands[0],
-						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup, IsDefault: false},
-					},
-				},
-				{
-					Id: "run",
-					Exec: &versionsCommon.Exec{
-						CommandLine: commands[0],
-						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
-					},
-				},
-			},
-			compCommands: []common.DevfileCommand{
-				{
-					Id: "myComp",
-					Composite: &versionsCommon.Composite{
-						Commands: []string{"fake"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
-					},
-				},
-			},
-			retCommandName: "myComp",
-			requestedType:  []common.DevfileCommandGroupType{buildGroup},
-			wantErr:        true,
-		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			components := []common.DevfileComponent{testingutil.GetFakeContainerComponent(tt.execCommands[0].Exec.Component)}
-			if tt.execCommands[0].Exec.Component == invalidComponent {
-				components = []common.DevfileComponent{testingutil.GetFakeContainerComponent("randomComponent")}
-			}
 			devObj := devfileParser.DevfileObj{
 				Data: &testingutil.TestDevfileData{
 					Commands:   append(tt.execCommands, tt.compCommands...),
@@ -485,9 +348,6 @@ func TestGetCommandFromFlag(t *testing.T) {
 	commands := [...]string{"ls -la", "pwd"}
 	components := [...]string{"alias1", "alias2"}
 	invalidComponent := "garbagealias"
-	workDir := [...]string{"/", "/root"}
-
-	emptyString := ""
 
 	tests := []struct {
 		name           string
@@ -500,7 +360,7 @@ func TestGetCommandFromFlag(t *testing.T) {
 	}{
 		{
 			name: "Case 1: Valid devfile",
-			execCommands: []versionsCommon.DevfileCommand{
+			execCommands: []common.DevfileCommand{
 				getExecCommand("a", buildGroup),
 				getExecCommand("b", runGroup),
 			},
@@ -510,31 +370,14 @@ func TestGetCommandFromFlag(t *testing.T) {
 			wantErr:        false,
 		},
 		{
-			name: "Case 2: Invalid devfile with empty component",
-			execCommands: []versionsCommon.DevfileCommand{
-				{
-					Id: "build command",
-					Exec: &versionsCommon.Exec{
-						CommandLine: commands[0],
-						Component:   emptyString,
-						WorkingDir:  workDir[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			reqCommandName: "build command",
-			requestedType:  buildGroup,
-			wantErr:        true,
-		},
-		{
-			name: "Case 3: Valid devfile with empty workdir",
+			name: "Case 2: Valid devfile with empty workdir",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -544,14 +387,14 @@ func TestGetCommandFromFlag(t *testing.T) {
 			wantErr:        false,
 		},
 		{
-			name: "Case 4: Invalid command",
+			name: "Case 3: Invalid command",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   invalidComponent,
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -560,14 +403,14 @@ func TestGetCommandFromFlag(t *testing.T) {
 			wantErr:        true,
 		},
 		{
-			name: "Case 5: Mismatched command type",
+			name: "Case 4: Mismatched command type",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -576,22 +419,22 @@ func TestGetCommandFromFlag(t *testing.T) {
 			wantErr:        true,
 		},
 		{
-			name: "Case 6: Multiple default commands but should be with the flag",
+			name: "Case 5: Multiple default commands but should be with the flag",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "defaultruncommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup, IsDefault: true},
+						Group:       &common.Group{Kind: runGroup, IsDefault: true},
 					},
 				},
 				{
 					Id: "runcommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup, IsDefault: true},
+						Group:       &common.Group{Kind: runGroup, IsDefault: true},
 					},
 				},
 			},
@@ -601,22 +444,22 @@ func TestGetCommandFromFlag(t *testing.T) {
 			wantErr:        false,
 		},
 		{
-			name: "Case 7: No default command but should be with the flag",
+			name: "Case 6: No default command but should be with the flag",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "defaultruncommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 				{
 					Id: "runcommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -626,11 +469,11 @@ func TestGetCommandFromFlag(t *testing.T) {
 			wantErr:        false,
 		},
 		{
-			name: "Case 8: No Command Group",
+			name: "Case 7: No Command Group",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "defaultruncommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
 					},
@@ -642,38 +485,38 @@ func TestGetCommandFromFlag(t *testing.T) {
 			wantErr:        false,
 		},
 		{
-			name: "Case 9: Valid devfile with composite commands",
+			name: "Case 8: Valid devfile with composite commands",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup, IsDefault: false},
+						Group:       &common.Group{Kind: buildGroup, IsDefault: false},
 					},
 				},
 				{
 					Id: "run",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
 			compCommands: []common.DevfileCommand{
 				{
 					Id: "mycomp",
-					Composite: &versionsCommon.Composite{
+					Composite: &common.Composite{
 						Commands: []string{"build", "run"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: true},
 					},
 				},
 				{
 					Id: "mycomp2",
-					Composite: &versionsCommon.Composite{
+					Composite: &common.Composite{
 						Commands: []string{"build", "run"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: false},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: false},
 					},
 				},
 			},
@@ -683,31 +526,31 @@ func TestGetCommandFromFlag(t *testing.T) {
 			wantErr:        false,
 		},
 		{
-			name: "Case 10: Valid devfile with invalid composite commands",
+			name: "Case 9: Valid devfile with invalid composite commands",
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: buildGroup, IsDefault: false},
+						Group:       &common.Group{Kind: buildGroup, IsDefault: false},
 					},
 				},
 				{
 					Id: "run",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: commands[0],
 						Component:   components[0],
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
 			compCommands: []common.DevfileCommand{
 				{
 					Id: "myComp",
-					Composite: &versionsCommon.Composite{
+					Composite: &common.Composite{
 						Commands: []string{"fake"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: true},
 					},
 				},
 			},
@@ -766,11 +609,11 @@ func TestValidateCommandsForGroup(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "run command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   componentName,
 						WorkingDir:  workDir,
-						Group: &versionsCommon.Group{
+						Group: &common.Group{
 							Kind:      runGroup,
 							IsDefault: true,
 						},
@@ -778,11 +621,11 @@ func TestValidateCommandsForGroup(t *testing.T) {
 				},
 				{
 					Id: "customcommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   componentName,
 						WorkingDir:  workDir,
-						Group: &versionsCommon.Group{
+						Group: &common.Group{
 							Kind:      runGroup,
 							IsDefault: true,
 						},
@@ -797,20 +640,20 @@ func TestValidateCommandsForGroup(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   componentName,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 				{
 					Id: "build command 2",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   componentName,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 			},
@@ -822,11 +665,11 @@ func TestValidateCommandsForGroup(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "test command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   componentName,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: testGroup},
+						Group:       &common.Group{Kind: testGroup},
 					},
 				},
 			},
@@ -838,11 +681,11 @@ func TestValidateCommandsForGroup(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "debug command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   componentName,
 						WorkingDir:  workDir,
-						Group: &versionsCommon.Group{
+						Group: &common.Group{
 							Kind:      debugGroup,
 							IsDefault: true,
 						},
@@ -857,29 +700,29 @@ func TestValidateCommandsForGroup(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   componentName,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 				{
 					Id: "build command 2",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   componentName,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 			},
 			compCommands: []common.DevfileCommand{
 				{
 					Id: "composite1",
-					Composite: &versionsCommon.Composite{
+					Composite: &common.Composite{
 						Commands: []string{"build command", "build command 2"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: true},
 					},
 				},
 			},
@@ -891,7 +734,7 @@ func TestValidateCommandsForGroup(t *testing.T) {
 		t.Run(tt.name, func(t *testing.T) {
 			devObj := devfileParser.DevfileObj{
 				Data: &testingutil.TestDevfileData{
-					Components: []versionsCommon.DevfileComponent{
+					Components: []common.DevfileComponent{
 						testingutil.GetFakeContainerComponent("alias1"),
 					},
 					Commands: append(tt.compCommands, tt.execCommands...),
@@ -907,161 +750,6 @@ func TestValidateCommandsForGroup(t *testing.T) {
 
 }
 
-func TestValidateCommand(t *testing.T) {
-
-	command := "ls -la"
-	component := "alias1"
-	workDir := "/"
-
-	emptyString := ""
-
-	tests := []struct {
-		name    string
-		exec    []common.DevfileCommand
-		comp    []common.DevfileCommand
-		wantErr bool
-	}{
-		{
-			name: "Case: Valid Exec Command",
-			exec: []common.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: command,
-						Component:   component,
-						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: runGroup},
-					},
-				},
-			},
-			wantErr: false,
-		},
-		{
-			name: "Case: Invalid Exec Command with empty command",
-			exec: []common.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: emptyString,
-						Component:   component,
-						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: runGroup},
-					},
-				},
-			},
-			wantErr: true,
-		},
-		{
-			name: "Case: Invalid Exec Command with missing component",
-			exec: []common.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: command,
-						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: runGroup},
-					},
-				},
-			},
-			wantErr: true,
-		},
-		{
-			name: "Case: valid Exec Command with Group nil",
-			exec: []common.DevfileCommand{
-				{
-					Exec: &versionsCommon.Exec{
-						CommandLine: command,
-						Component:   component,
-						WorkingDir:  workDir,
-					},
-				},
-			},
-			wantErr: false,
-		},
-		{
-			name: "Case: valid Composite Command",
-			exec: []common.DevfileCommand{
-				{
-					Id: "somecommand1",
-					Exec: &versionsCommon.Exec{
-						CommandLine: command,
-						Component:   component,
-						WorkingDir:  workDir,
-					},
-				},
-				{
-					Id: "somecommand2",
-					Exec: &versionsCommon.Exec{
-						CommandLine: command,
-						Component:   component,
-						WorkingDir:  workDir,
-					},
-				},
-			},
-			comp: []common.DevfileCommand{
-				{
-					Id: "composite1",
-					Composite: &versionsCommon.Composite{
-						Commands: []string{"somecommand1", "somecommand2"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
-					},
-				},
-			},
-			wantErr: false,
-		},
-		{
-			name: "Case: Invalid Composite Command",
-			exec: []common.DevfileCommand{
-				{
-					Id: "somecommand1",
-					Exec: &versionsCommon.Exec{
-						CommandLine: command,
-						Component:   component,
-						WorkingDir:  workDir,
-					},
-				},
-				{
-					Id: "somecommand2",
-					Exec: &versionsCommon.Exec{
-						CommandLine: command,
-						Component:   component,
-						WorkingDir:  workDir,
-					},
-				},
-			},
-			comp: []common.DevfileCommand{
-				{
-					Id: "composite1",
-					Composite: &versionsCommon.Composite{
-						Commands: []string{"fakecommand"},
-						Group:    &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
-					},
-				},
-			},
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		devObj := devfileParser.DevfileObj{
-			Data: &testingutil.TestDevfileData{
-				Commands:   append(tt.comp, tt.exec...),
-				Components: []common.DevfileComponent{testingutil.GetFakeContainerComponent(component)},
-			},
-		}
-		t.Run(tt.name, func(t *testing.T) {
-			var cmd common.DevfileCommand
-			if tt.comp != nil {
-				cmd = tt.comp[0]
-			} else {
-				cmd = tt.exec[0]
-			}
-			err := ValidateCommand(devObj.Data, cmd)
-			if !tt.wantErr == (err != nil) {
-				t.Errorf("TestValidateAction unexpected error: %v", err)
-				return
-			}
-		})
-	}
-
-}
-
 func TestGetBuildCommand(t *testing.T) {
 
 	command := "ls -la"
@@ -1082,11 +770,11 @@ func TestGetBuildCommand(t *testing.T) {
 			commandName: emptyString,
 			execCommands: []common.DevfileCommand{
 				{
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: buildGroup, IsDefault: true},
+						Group:       &common.Group{Kind: buildGroup, IsDefault: true},
 					},
 				},
 			},
@@ -1098,20 +786,20 @@ func TestGetBuildCommand(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "flagcommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 				{
 					Id: "build command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 			},
@@ -1123,11 +811,11 @@ func TestGetBuildCommand(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "build command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 			},
@@ -1177,13 +865,13 @@ func TestGetDebugCommand(t *testing.T) {
 			commandName: emptyString,
 			execCommands: []common.DevfileCommand{
 				{
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group: &versionsCommon.Group{
+						Group: &common.Group{
 							IsDefault: true,
-							Kind:      versionsCommon.DebugCommandGroupType,
+							Kind:      common.DebugCommandGroupType,
 						},
 					},
 				},
@@ -1196,13 +884,13 @@ func TestGetDebugCommand(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "customdebugcommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group: &versionsCommon.Group{
+						Group: &common.Group{
 							IsDefault: false,
-							Kind:      versionsCommon.DebugCommandGroupType,
+							Kind:      common.DebugCommandGroupType,
 						},
 					},
 				},
@@ -1214,13 +902,13 @@ func TestGetDebugCommand(t *testing.T) {
 			commandName: "customcommand123",
 			execCommands: []common.DevfileCommand{
 				{
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group: &versionsCommon.Group{
+						Group: &common.Group{
 							IsDefault: true,
-							Kind:      versionsCommon.BuildCommandGroupType,
+							Kind:      common.BuildCommandGroupType,
 						},
 					},
 				},
@@ -1273,13 +961,13 @@ func TestGetTestCommand(t *testing.T) {
 			commandName: emptyString,
 			execCommands: []common.DevfileCommand{
 				{
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group: &versionsCommon.Group{
+						Group: &common.Group{
 							IsDefault: true,
-							Kind:      versionsCommon.TestCommandGroupType,
+							Kind:      common.TestCommandGroupType,
 						},
 					},
 				},
@@ -1292,13 +980,13 @@ func TestGetTestCommand(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "customtestcommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group: &versionsCommon.Group{
+						Group: &common.Group{
 							IsDefault: false,
-							Kind:      versionsCommon.TestCommandGroupType,
+							Kind:      common.TestCommandGroupType,
 						},
 					},
 				},
@@ -1310,13 +998,13 @@ func TestGetTestCommand(t *testing.T) {
 			commandName: "customcommand123",
 			execCommands: []common.DevfileCommand{
 				{
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group: &versionsCommon.Group{
+						Group: &common.Group{
 							IsDefault: true,
-							Kind:      versionsCommon.BuildCommandGroupType,
+							Kind:      common.BuildCommandGroupType,
 						},
 					},
 				},
@@ -1369,11 +1057,11 @@ func TestGetRunCommand(t *testing.T) {
 			commandName: emptyString,
 			execCommands: []common.DevfileCommand{
 				{
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: runGroup, IsDefault: true},
+						Group:       &common.Group{Kind: runGroup, IsDefault: true},
 					},
 				},
 			},
@@ -1385,20 +1073,20 @@ func TestGetRunCommand(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "flagcommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 				{
 					Id: "run command",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: runGroup},
+						Group:       &common.Group{Kind: runGroup},
 					},
 				},
 			},
@@ -1409,11 +1097,11 @@ func TestGetRunCommand(t *testing.T) {
 			commandName: "",
 			execCommands: []common.DevfileCommand{
 				{
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						CommandLine: command,
 						Component:   component,
 						WorkingDir:  workDir,
-						Group:       &versionsCommon.Group{Kind: buildGroup},
+						Group:       &common.Group{Kind: buildGroup},
 					},
 				},
 			},
@@ -1451,7 +1139,7 @@ func TestValidateAndGetDebugDevfileCommands(t *testing.T) {
 
 	execCommands := []common.DevfileCommand{
 		{
-			Exec: &versionsCommon.Exec{
+			Exec: &common.Exec{
 				CommandLine: command,
 				Component:   component,
 				WorkingDir:  workDir,
@@ -1463,7 +1151,7 @@ func TestValidateAndGetDebugDevfileCommands(t *testing.T) {
 		},
 		{
 			Id: "customdebugcommand",
-			Exec: &versionsCommon.Exec{
+			Exec: &common.Exec{
 				CommandLine: command,
 				Component:   component,
 				WorkingDir:  workDir,
@@ -1490,13 +1178,13 @@ func TestValidateAndGetDebugDevfileCommands(t *testing.T) {
 		{
 			name:          "Case: provided debug Command",
 			debugCommand:  "customdebugcommand",
-			componentType: versionsCommon.ContainerComponentType,
+			componentType: common.ContainerComponentType,
 			wantErr:       false,
 		},
 		{
 			name:          "Case: invalid debug Command",
 			debugCommand:  "invaliddebugcommand",
-			componentType: versionsCommon.ContainerComponentType,
+			componentType: common.ContainerComponentType,
 			wantErr:       true,
 		},
 	}
@@ -1541,11 +1229,11 @@ func TestValidateAndGetPushDevfileCommands(t *testing.T) {
 	execCommands := []common.DevfileCommand{
 		{
 			Id: "run command",
-			Exec: &versionsCommon.Exec{
+			Exec: &common.Exec{
 				CommandLine: command,
 				Component:   component,
 				WorkingDir:  workDir,
-				Group: &versionsCommon.Group{
+				Group: &common.Group{
 					Kind:      runGroup,
 					IsDefault: true,
 				},
@@ -1554,21 +1242,21 @@ func TestValidateAndGetPushDevfileCommands(t *testing.T) {
 
 		{
 			Id: "build command",
-			Exec: &versionsCommon.Exec{
+			Exec: &common.Exec{
 				CommandLine: command,
 				Component:   component,
 				WorkingDir:  workDir,
-				Group:       &versionsCommon.Group{Kind: buildGroup},
+				Group:       &common.Group{Kind: buildGroup},
 			},
 		},
 
 		{
 			Id: "customcommand",
-			Exec: &versionsCommon.Exec{
+			Exec: &common.Exec{
 				CommandLine: command,
 				Component:   component,
 				WorkingDir:  workDir,
-				Group:       &versionsCommon.Group{Kind: runGroup},
+				Group:       &common.Group{Kind: runGroup},
 			},
 		},
 	}
@@ -1576,11 +1264,11 @@ func TestValidateAndGetPushDevfileCommands(t *testing.T) {
 	wrongCompTypeCmd := common.DevfileCommand{
 
 		Id: "wrong",
-		Exec: &versionsCommon.Exec{
+		Exec: &common.Exec{
 			CommandLine: command,
 			Component:   "",
 			WorkingDir:  workDir,
-			Group:       &versionsCommon.Group{Kind: runGroup},
+			Group:       &common.Group{Kind: runGroup},
 		},
 	}
 
@@ -1632,7 +1320,7 @@ func TestValidateAndGetPushDevfileCommands(t *testing.T) {
 			execCommands: []common.DevfileCommand{
 				{
 					Id: "customcommand",
-					Exec: &versionsCommon.Exec{
+					Exec: &common.Exec{
 						Group:       &common.Group{Kind: runGroup},
 						Component:   component,
 						CommandLine: command,
@@ -1668,291 +1356,6 @@ func TestValidateAndGetPushDevfileCommands(t *testing.T) {
 
 }
 
-func TestValidateCompositeCommand(t *testing.T) {
-
-	command := []string{"ls -la", "ps", "ls /"}
-	component := "alias1"
-	workDir := []string{"/", "/dev", "/etc"}
-	id := []string{"command1", "command2", "command3", "command4", "command5"}
-
-	tests := []struct {
-		name              string
-		compositeCommands []common.DevfileCommand
-		execCommands      []common.DevfileCommand
-		wantErr           bool
-	}{
-		{
-			name: "Case 1: Valid Composite Command",
-			compositeCommands: []common.DevfileCommand{
-				{
-					Id: id[3],
-					Composite: &versionsCommon.Composite{
-						Commands: []string{id[0], id[1], id[2]},
-						Group:    &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			execCommands: []common.DevfileCommand{
-				{
-					Id: id[0],
-					Exec: &versionsCommon.Exec{
-						CommandLine: command[0],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[0],
-					},
-				},
-				{
-					Id: id[1],
-					Exec: &versionsCommon.Exec{
-						CommandLine: command[1],
-						Component:   component,
-						Group:       &common.Group{Kind: buildGroup},
-						WorkingDir:  workDir[1],
-					},
-				},
-				{
-					Id: id[2],
-					Exec: &versionsCommon.Exec{
-						CommandLine: command[2],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[2],
-					},
-				},
-			},
-			wantErr: false,
-		},
-		{
-			name: "Case 2: Invalid composite command, references non-existent command",
-			compositeCommands: []common.DevfileCommand{
-				{
-					Id: id[3],
-					Composite: &versionsCommon.Composite{
-						Commands: []string{id[0], "fakecommand", id[2]},
-						Group:    &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			execCommands: []common.DevfileCommand{
-				{
-					Id: id[0],
-					Exec: &versionsCommon.Exec{
-						CommandLine: command[0],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[0],
-					},
-				},
-				{
-					Id: id[1],
-					Exec: &versionsCommon.Exec{
-						CommandLine: command[1],
-						Component:   component,
-						Group:       &common.Group{Kind: buildGroup},
-						WorkingDir:  workDir[1],
-					},
-				},
-				{
-					Id: id[2],
-					Exec: &versionsCommon.Exec{
-						CommandLine: command[2],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[2],
-					},
-				},
-			},
-			wantErr: true,
-		},
-		{
-			name: "Case 3: Invalid composite command, references itself",
-			compositeCommands: []common.DevfileCommand{
-				{
-					Id: id[3],
-					Composite: &common.Composite{
-						Commands: []string{id[0], id[3], id[2]},
-						Group:    &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			execCommands: []common.DevfileCommand{
-				{
-					Id: id[0],
-					Exec: &common.Exec{
-						CommandLine: command[0],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[0],
-					},
-				},
-				{
-					Id: id[1],
-					Exec: &common.Exec{
-						CommandLine: command[1],
-						Component:   component,
-						Group:       &common.Group{Kind: buildGroup},
-						WorkingDir:  workDir[1],
-					},
-				},
-				{
-					Id: id[2],
-					Exec: &common.Exec{
-						CommandLine: command[2],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[2],
-					},
-				},
-			},
-			wantErr: true,
-		},
-		{
-			name: "Case 4: Invalid composite run command",
-			compositeCommands: []common.DevfileCommand{
-				{
-					Id: id[3],
-					Composite: &common.Composite{
-						Commands: []string{id[0], id[3], id[2]},
-						Group:    &versionsCommon.Group{Kind: runGroup},
-					},
-				},
-			},
-			execCommands: []common.DevfileCommand{
-				{
-					Id: id[0],
-					Exec: &common.Exec{
-						CommandLine: command[0],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[0],
-					},
-				},
-				{
-					Id: id[1],
-					Exec: &common.Exec{
-						CommandLine: command[1],
-						Component:   component,
-						Group:       &common.Group{Kind: buildGroup},
-						WorkingDir:  workDir[1],
-					},
-				},
-				{
-					Id: id[2],
-					Exec: &common.Exec{
-						CommandLine: command[2],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[2],
-					},
-				},
-			},
-			wantErr: true,
-		},
-		{
-			name: "Case 5: Invalid composite command, indirectly references itself",
-			compositeCommands: []common.DevfileCommand{
-				{
-					Id: id[3],
-					Composite: &common.Composite{
-						Commands: []string{id[4], id[3], id[2]},
-						Group:    &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-				{
-					Id: id[4],
-					Composite: &common.Composite{
-						Commands: []string{id[0], id[3], id[2]},
-						Group:    &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			execCommands: []common.DevfileCommand{
-				{
-					Id: id[0],
-					Exec: &common.Exec{
-						CommandLine: command[0],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[0],
-					},
-				},
-				{
-					Id: id[1],
-					Exec: &common.Exec{
-						CommandLine: command[1],
-						Component:   component,
-						Group:       &common.Group{Kind: buildGroup},
-						WorkingDir:  workDir[1],
-					},
-				},
-				{
-					Id: id[2],
-					Exec: &common.Exec{
-						CommandLine: command[2],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[2],
-					},
-				},
-			},
-			wantErr: true,
-		},
-		{
-			name: "Case 6: Invalid composite command, points to invalid exec command",
-			compositeCommands: []common.DevfileCommand{
-				{
-					Id: id[3],
-					Composite: &common.Composite{
-						Commands: []string{id[0], id[1]},
-						Group:    &versionsCommon.Group{Kind: buildGroup},
-					},
-				},
-			},
-			execCommands: []common.DevfileCommand{
-				{
-					Id: id[0],
-					Exec: &common.Exec{
-						CommandLine: command[0],
-						Component:   component,
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[0],
-					},
-				},
-				{
-					Id: id[1],
-					Exec: &common.Exec{
-						CommandLine: command[1],
-						Component:   "some-fake-component",
-						Group:       &common.Group{Kind: runGroup},
-						WorkingDir:  workDir[1],
-					},
-				},
-			},
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		devObj := devfileParser.DevfileObj{
-			Data: &testingutil.TestDevfileData{
-				Commands:   append(tt.execCommands, tt.compositeCommands...),
-				Components: []common.DevfileComponent{testingutil.GetFakeContainerComponent(component)},
-			},
-		}
-		t.Run(tt.name, func(t *testing.T) {
-			cmd := tt.compositeCommands[0]
-			commandsMap := devObj.Data.GetCommands()
-			parentCommands := make(map[string]string)
-
-			err := validateCompositeCommand(devObj.Data, &cmd, parentCommands, commandsMap)
-			if !tt.wantErr == (err != nil) {
-				t.Errorf("TestValidateAction unexpected error: %v", err)
-				return
-			}
-		})
-	}
-}
-
 func TestValidateAndGetTestDevfileCommands(t *testing.T) {
 
 	command := "ls -la"
@@ -1962,7 +1365,7 @@ func TestValidateAndGetTestDevfileCommands(t *testing.T) {
 
 	execCommands := []common.DevfileCommand{
 		{
-			Exec: &versionsCommon.Exec{
+			Exec: &common.Exec{
 				CommandLine: command,
 				Component:   component,
 				WorkingDir:  workDir,
@@ -1974,7 +1377,7 @@ func TestValidateAndGetTestDevfileCommands(t *testing.T) {
 		},
 		{
 			Id: "customtestcommand",
-			Exec: &versionsCommon.Exec{
+			Exec: &common.Exec{
 				CommandLine: command,
 				Component:   component,
 				WorkingDir:  workDir,
@@ -2001,13 +1404,13 @@ func TestValidateAndGetTestDevfileCommands(t *testing.T) {
 		{
 			name:          "Case: provided test Command",
 			testCommand:   "customtestcommand",
-			componentType: versionsCommon.ContainerComponentType,
+			componentType: common.ContainerComponentType,
 			wantErr:       false,
 		},
 		{
 			name:          "Case: invalid test Command",
 			testCommand:   "invalidtestcommand",
-			componentType: versionsCommon.ContainerComponentType,
+			componentType: common.ContainerComponentType,
 			wantErr:       true,
 		},
 	}
@@ -2042,7 +1445,7 @@ func TestValidateAndGetTestDevfileCommands(t *testing.T) {
 	}
 }
 
-func getExecCommand(id string, group common.DevfileCommandGroupType) versionsCommon.DevfileCommand {
+func getExecCommand(id string, group common.DevfileCommandGroupType) common.DevfileCommand {
 	if len(id) == 0 {
 		id = fmt.Sprintf("%s-%s", "cmd", util.GenerateRandomString(10))
 	}
@@ -2050,9 +1453,9 @@ func getExecCommand(id string, group common.DevfileCommandGroupType) versionsCom
 	components := [...]string{"alias1", "alias2"}
 	workDir := [...]string{"/", "/root"}
 
-	return versionsCommon.DevfileCommand{
+	return common.DevfileCommand{
 		Id: id,
-		Exec: &versionsCommon.Exec{
+		Exec: &common.Exec{
 			CommandLine: commands[0],
 			Component:   components[0],
 			WorkingDir:  workDir[0],
diff --git a/pkg/devfile/adapters/common/utils_test.go b/pkg/devfile/adapters/common/utils_test.go
index 44b9fab17..0fe7c045e 100644
--- a/pkg/devfile/adapters/common/utils_test.go
+++ b/pkg/devfile/adapters/common/utils_test.go
@@ -337,68 +337,6 @@ func TestGetBootstrapperImage(t *testing.T) {
 
 }
 
-func TestIsContainer(t *testing.T) {
-
-	tests := []struct {
-		name            string
-		component       common.DevfileComponent
-		wantIsSupported bool
-	}{
-		{
-			name:            "Case 1: Container component",
-			component:       testingutil.GetFakeContainerComponent("comp1"),
-			wantIsSupported: true,
-		},
-		{
-			name: "Case 2: Not a container component",
-			component: common.DevfileComponent{
-				Openshift: &versionsCommon.Openshift{},
-			},
-			wantIsSupported: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			isSupported := isContainer(tt.component)
-			if isSupported != tt.wantIsSupported {
-				t.Errorf("TestIsContainer error: component support mismatch, expected: %v got: %v", tt.wantIsSupported, isSupported)
-			}
-		})
-	}
-
-}
-
-func TestIsVolume(t *testing.T) {
-
-	tests := []struct {
-		name            string
-		component       common.DevfileComponent
-		wantIsSupported bool
-	}{
-		{
-			name:            "Case 1: Volume component",
-			component:       testingutil.GetFakeVolumeComponent("myvol", "4Gi"),
-			wantIsSupported: true,
-		},
-		{
-			name: "Case 2: Not a volume component",
-			component: common.DevfileComponent{
-				Openshift: &versionsCommon.Openshift{},
-			},
-			wantIsSupported: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			isSupported := isVolume(tt.component)
-			if isSupported != tt.wantIsSupported {
-				t.Errorf("TestIsVolume error: component support mismatch, expected: %v got: %v", tt.wantIsSupported, isSupported)
-			}
-		})
-	}
-
-}
-
 func TestGetCommandsForGroup(t *testing.T) {
 
 	component := []versionsCommon.DevfileComponent{
diff --git a/pkg/devfile/parser/data/common/component_helper_test.go b/pkg/devfile/parser/data/common/component_helper_test.go
new file mode 100644
index 000000000..d8c9b8077
--- /dev/null
+++ b/pkg/devfile/parser/data/common/component_helper_test.go
@@ -0,0 +1,73 @@
+package common
+
+import (
+	"testing"
+)
+
+func TestIsContainer(t *testing.T) {
+
+	tests := []struct {
+		name            string
+		component       DevfileComponent
+		wantIsSupported bool
+	}{
+		{
+			name: "Case 1: Container component",
+			component: DevfileComponent{
+				Name:      "name",
+				Container: &Container{}},
+			wantIsSupported: true,
+		},
+		{
+			name: "Case 2: Not a container component",
+			component: DevfileComponent{
+				Openshift: &Openshift{},
+			},
+			wantIsSupported: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			isSupported := tt.component.IsContainer()
+			if isSupported != tt.wantIsSupported {
+				t.Errorf("TestIsContainer error: component support mismatch, expected: %v got: %v", tt.wantIsSupported, isSupported)
+			}
+		})
+	}
+
+}
+
+func TestIsVolume(t *testing.T) {
+
+	tests := []struct {
+		name            string
+		component       DevfileComponent
+		wantIsSupported bool
+	}{
+		{
+			name: "Case 1: Volume component",
+			component: DevfileComponent{
+				Name: "name",
+				Volume: &Volume{
+					Size: "size",
+				}},
+			wantIsSupported: true,
+		},
+		{
+			name: "Case 2: Not a volume component",
+			component: DevfileComponent{
+				Openshift: &Openshift{},
+			},
+			wantIsSupported: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			isSupported := tt.component.IsVolume()
+			if isSupported != tt.wantIsSupported {
+				t.Errorf("TestIsVolume error: component support mismatch, expected: %v got: %v", tt.wantIsSupported, isSupported)
+			}
+		})
+	}
+
+}
diff --git a/pkg/devfile/validate/commands_test.go b/pkg/devfile/validate/commands_test.go
new file mode 100644
index 000000000..0b95fa434
--- /dev/null
+++ b/pkg/devfile/validate/commands_test.go
@@ -0,0 +1,472 @@
+package validate
+
+import (
+	"testing"
+
+	devfileParser "github.com/openshift/odo/pkg/devfile/parser"
+	"github.com/openshift/odo/pkg/devfile/parser/data/common"
+	"github.com/openshift/odo/pkg/testingutil"
+)
+
+var buildGroup = common.BuildCommandGroupType
+var runGroup = common.RunCommandGroupType
+
+func TestValidateCommands(t *testing.T) {
+
+	command := "ls -la"
+	component := "alias1"
+	workDir := "/"
+	invalidComponent := "garbagealias"
+	emptyString := ""
+
+	tests := []struct {
+		name    string
+		exec    []common.DevfileCommand
+		comp    []common.DevfileCommand
+		wantErr bool
+	}{
+		{
+			name: "Case 1: Valid Exec Command",
+			exec: []common.DevfileCommand{
+				{
+					Id: "somecommand",
+					Exec: &common.Exec{
+						CommandLine: command,
+						Component:   component,
+						WorkingDir:  workDir,
+						Group:       &common.Group{Kind: runGroup},
+					},
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "Case 2: Invalid Exec Command with empty command",
+			exec: []common.DevfileCommand{
+				{
+					Id: "somecommand",
+					Exec: &common.Exec{
+						CommandLine: emptyString,
+						Component:   component,
+						WorkingDir:  workDir,
+						Group:       &common.Group{Kind: runGroup},
+					},
+				},
+			},
+			wantErr: true,
+		},
+		{
+			name: "Case 3: Invalid Exec Command with missing component",
+			exec: []common.DevfileCommand{
+				{
+					Id: "somecommand",
+					Exec: &common.Exec{
+						CommandLine: command,
+						WorkingDir:  workDir,
+						Group:       &common.Group{Kind: runGroup},
+					},
+				},
+			},
+			wantErr: true,
+		},
+		{
+			name: "Case 4: Valid Exec Command with invalid component",
+			exec: []common.DevfileCommand{
+				{
+					Id: "somecommand",
+					Exec: &common.Exec{
+						CommandLine: command,
+						Component:   invalidComponent,
+						WorkingDir:  workDir,
+						Group:       &common.Group{Kind: runGroup},
+					},
+				},
+			},
+			wantErr: true,
+		},
+		{
+			name: "Case 5: valid Exec Command with Group nil",
+			exec: []common.DevfileCommand{
+				{
+					Id: "somecommand",
+					Exec: &common.Exec{
+						CommandLine: command,
+						Component:   component,
+						WorkingDir:  workDir,
+					},
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "Case 6: valid Composite Command",
+			exec: []common.DevfileCommand{
+				{
+					Id: "somecommand1",
+					Exec: &common.Exec{
+						CommandLine: command,
+						Component:   component,
+						WorkingDir:  workDir,
+					},
+				},
+				{
+					Id: "somecommand2",
+					Exec: &common.Exec{
+						CommandLine: command,
+						Component:   component,
+						WorkingDir:  workDir,
+					},
+				},
+			},
+			comp: []common.DevfileCommand{
+				{
+					Id: "composite1",
+					Composite: &common.Composite{
+						Commands: []string{"somecommand1", "somecommand2"},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: true},
+					},
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "Case 7: Invalid Composite Command",
+			exec: []common.DevfileCommand{
+				{
+					Id: "somecommand1",
+					Exec: &common.Exec{
+						CommandLine: command,
+						Component:   component,
+						WorkingDir:  workDir,
+					},
+				},
+				{
+					Id: "somecommand2",
+					Exec: &common.Exec{
+						CommandLine: command,
+						Component:   component,
+						WorkingDir:  workDir,
+					},
+				},
+			},
+			comp: []common.DevfileCommand{
+				{
+					Id: "composite1",
+					Composite: &common.Composite{
+						Commands: []string{"fakecommand"},
+						Group:    &common.Group{Kind: buildGroup, IsDefault: true},
+					},
+				},
+			},
+			wantErr: true,
+		},
+	}
+	for _, tt := range tests {
+		devObj := devfileParser.DevfileObj{
+			Data: &testingutil.TestDevfileData{
+				Commands:   append(tt.comp, tt.exec...),
+				Components: []common.DevfileComponent{testingutil.GetFakeContainerComponent(component)},
+			},
+		}
+
+		commands := devObj.Data.GetCommands()
+		components := devObj.Data.GetComponents()
+
+		t.Run(tt.name, func(t *testing.T) {
+			err := validateCommands(commands, components)
+			if !tt.wantErr == (err != nil) {
+				t.Errorf("TestValidateAction unexpected error: %v", err)
+				return
+			}
+		})
+	}
+
+}
+
+func TestValidateCompositeCommand(t *testing.T) {
+
+	command := []string{"ls -la", "ps", "ls /"}
+	component := "alias1"
+	workDir := []string{"/", "/dev", "/etc"}
+	id := []string{"command1", "command2", "command3", "command4", "command5"}
+
+	tests := []struct {
+		name              string
+		compositeCommands []common.DevfileCommand
+		execCommands      []common.DevfileCommand
+		wantErr           bool
+	}{
+		{
+			name: "Case 1: Valid Composite Command",
+			compositeCommands: []common.DevfileCommand{
+				{
+					Id: id[3],
+					Composite: &common.Composite{
+						Commands: []string{id[0], id[1], id[2]},
+						Group:    &common.Group{Kind: buildGroup},
+					},
+				},
+			},
+			execCommands: []common.DevfileCommand{
+				{
+					Id: id[0],
+					Exec: &common.Exec{
+						CommandLine: command[0],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[0],
+					},
+				},
+				{
+					Id: id[1],
+					Exec: &common.Exec{
+						CommandLine: command[1],
+						Component:   component,
+						Group:       &common.Group{Kind: buildGroup},
+						WorkingDir:  workDir[1],
+					},
+				},
+				{
+					Id: id[2],
+					Exec: &common.Exec{
+						CommandLine: command[2],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[2],
+					},
+				},
+			},
+			wantErr: false,
+		},
+		{
+			name: "Case 2: Invalid composite command, references non-existent command",
+			compositeCommands: []common.DevfileCommand{
+				{
+					Id: id[3],
+					Composite: &common.Composite{
+						Commands: []string{id[0], "fakecommand", id[2]},
+						Group:    &common.Group{Kind: buildGroup},
+					},
+				},
+			},
+			execCommands: []common.DevfileCommand{
+				{
+					Id: id[0],
+					Exec: &common.Exec{
+						CommandLine: command[0],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[0],
+					},
+				},
+				{
+					Id: id[1],
+					Exec: &common.Exec{
+						CommandLine: command[1],
+						Component:   component,
+						Group:       &common.Group{Kind: buildGroup},
+						WorkingDir:  workDir[1],
+					},
+				},
+				{
+					Id: id[2],
+					Exec: &common.Exec{
+						CommandLine: command[2],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[2],
+					},
+				},
+			},
+			wantErr: true,
+		},
+		{
+			name: "Case 3: Invalid composite command, references itself",
+			compositeCommands: []common.DevfileCommand{
+				{
+					Id: id[3],
+					Composite: &common.Composite{
+						Commands: []string{id[0], id[3], id[2]},
+						Group:    &common.Group{Kind: buildGroup},
+					},
+				},
+			},
+			execCommands: []common.DevfileCommand{
+				{
+					Id: id[0],
+					Exec: &common.Exec{
+						CommandLine: command[0],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[0],
+					},
+				},
+				{
+					Id: id[1],
+					Exec: &common.Exec{
+						CommandLine: command[1],
+						Component:   component,
+						Group:       &common.Group{Kind: buildGroup},
+						WorkingDir:  workDir[1],
+					},
+				},
+				{
+					Id: id[2],
+					Exec: &common.Exec{
+						CommandLine: command[2],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[2],
+					},
+				},
+			},
+			wantErr: true,
+		},
+		{
+			name: "Case 4: Invalid composite run command",
+			compositeCommands: []common.DevfileCommand{
+				{
+					Id: id[3],
+					Composite: &common.Composite{
+						Commands: []string{id[0], id[3], id[2]},
+						Group:    &common.Group{Kind: runGroup},
+					},
+				},
+			},
+			execCommands: []common.DevfileCommand{
+				{
+					Id: id[0],
+					Exec: &common.Exec{
+						CommandLine: command[0],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[0],
+					},
+				},
+				{
+					Id: id[1],
+					Exec: &common.Exec{
+						CommandLine: command[1],
+						Component:   component,
+						Group:       &common.Group{Kind: buildGroup},
+						WorkingDir:  workDir[1],
+					},
+				},
+				{
+					Id: id[2],
+					Exec: &common.Exec{
+						CommandLine: command[2],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[2],
+					},
+				},
+			},
+			wantErr: true,
+		},
+		{
+			name: "Case 5: Invalid composite command, indirectly references itself",
+			compositeCommands: []common.DevfileCommand{
+				{
+					Id: id[3],
+					Composite: &common.Composite{
+						Commands: []string{id[4], id[3], id[2]},
+						Group:    &common.Group{Kind: buildGroup},
+					},
+				},
+				{
+					Id: id[4],
+					Composite: &common.Composite{
+						Commands: []string{id[0], id[3], id[2]},
+						Group:    &common.Group{Kind: buildGroup},
+					},
+				},
+			},
+			execCommands: []common.DevfileCommand{
+				{
+					Id: id[0],
+					Exec: &common.Exec{
+						CommandLine: command[0],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[0],
+					},
+				},
+				{
+					Id: id[1],
+					Exec: &common.Exec{
+						CommandLine: command[1],
+						Component:   component,
+						Group:       &common.Group{Kind: buildGroup},
+						WorkingDir:  workDir[1],
+					},
+				},
+				{
+					Id: id[2],
+					Exec: &common.Exec{
+						CommandLine: command[2],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[2],
+					},
+				},
+			},
+			wantErr: true,
+		},
+		{
+			name: "Case 6: Invalid composite command, points to invalid exec command",
+			compositeCommands: []common.DevfileCommand{
+				{
+					Id: id[3],
+					Composite: &common.Composite{
+						Commands: []string{id[0], id[1]},
+						Group:    &common.Group{Kind: buildGroup},
+					},
+				},
+			},
+			execCommands: []common.DevfileCommand{
+				{
+					Id: id[0],
+					Exec: &common.Exec{
+						CommandLine: command[0],
+						Component:   component,
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[0],
+					},
+				},
+				{
+					Id: id[1],
+					Exec: &common.Exec{
+						CommandLine: command[1],
+						Component:   "some-fake-component",
+						Group:       &common.Group{Kind: runGroup},
+						WorkingDir:  workDir[1],
+					},
+				},
+			},
+			wantErr: true,
+		},
+	}
+	for _, tt := range tests {
+		devObj := devfileParser.DevfileObj{
+			Data: &testingutil.TestDevfileData{
+				Commands:   append(tt.execCommands, tt.compositeCommands...),
+				Components: []common.DevfileComponent{testingutil.GetFakeContainerComponent(component)},
+			},
+		}
+
+		commands := devObj.Data.GetCommands()
+		components := devObj.Data.GetComponents()
+
+		t.Run(tt.name, func(t *testing.T) {
+			cmd := tt.compositeCommands[0]
+			parentCommands := make(map[string]string)
+
+			err := validateCompositeCommand(&cmd, parentCommands, commands, components)
+			if !tt.wantErr == (err != nil) {
+				t.Errorf("TestValidateAction unexpected error: %v", err)
+				return
+			}
+		})
+	}
+}
diff --git a/pkg/devfile/validate/events_test.go b/pkg/devfile/validate/events_test.go
index d1bef6ccf..a0b0e6c7d 100644
--- a/pkg/devfile/validate/events_test.go
+++ b/pkg/devfile/validate/events_test.go
@@ -201,7 +201,12 @@ func TestValidateEvents(t *testing.T) {
 					Events:     tt.events,
 				},
 			}
-			err := validateEvents(devObj.Data)
+
+			events := devObj.Data.GetEvents()
+			commands := devObj.Data.GetCommands()
+			components := devObj.Data.GetComponents()
+
+			err := validateEvents(events, commands, components)
 			if err != nil && !tt.wantErr {
 				t.Errorf("TestValidateEvents error - %v", err)
 			}
@@ -346,7 +351,7 @@ func TestIsEventValid(t *testing.T) {
 				"composite1",
 			},
 			wantErr:    true,
-			wantErrMsg: "does not map to a supported component",
+			wantErrMsg: "does not map to a container component",
 		},
 		{
 			name:       "Case 4: Invalid events with wrong child command in composite command",
@@ -395,7 +400,10 @@ func TestIsEventValid(t *testing.T) {
 				},
 			}
 
-			err := isEventValid(devObj.Data, tt.eventNames, tt.eventType)
+			commands := devObj.Data.GetCommands()
+			components := devObj.Data.GetComponents()
+
+			err := isEventValid(tt.eventNames, tt.eventType, commands, components)
 			if err != nil && !tt.wantErr {
 				t.Errorf("TestIsEventValid error: %v", err)
 			} else if err != nil && tt.wantErr {
diff --git a/pkg/occlient/occlient_test.go b/pkg/occlient/occlient_test.go
index 13ffd5534..4ffe26a5a 100644
--- a/pkg/occlient/occlient_test.go
+++ b/pkg/occlient/occlient_test.go
@@ -1412,17 +1412,112 @@ func TestGetExposedPorts(t *testing.T) {
 		want             []corev1.ContainerPort
 	}{
 		{
-			name:             "Case: Valid image ports",
-			imageTag:         "3.5",
-			imageStreamImage: fakeImageStreamImage("python", []string{"8080/tcp"}, ""),
+			name:     "Case: Valid image ports in ContainerConfig",
+			imageTag: "3.5",
+			imageStreamImage: &imagev1.ImageStreamImage{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "name/imagename@@sha256:9579a93ee",
+				},
+				Image: imagev1.Image{
+					ObjectMeta: metav1.ObjectMeta{
+						Name: "@sha256:9579a93ee",
+					},
+					DockerImageMetadata: runtime.RawExtension{
+						Object: &dockerapiv10.DockerImage{
+							ContainerConfig: dockerapiv10.DockerConfig{
+								ExposedPorts: map[string]struct{}{
+									"8080/tcp": {},
+								},
+							},
+						},
+					},
+				},
+			},
+			want: []corev1.ContainerPort{
+				{
+					Name:          "8080-tcp",
+					ContainerPort: 8080,
+					Protocol:      "TCP",
+				},
+			},
+		},
+		{
+			name:     "Case: Valid image ports in Config",
+			imageTag: "3.5",
+			imageStreamImage: &imagev1.ImageStreamImage{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "name/imagename@@sha256:9579a93ee",
+				},
+				Image: imagev1.Image{
+					ObjectMeta: metav1.ObjectMeta{
+						Name: "@sha256:9579a93ee",
+					},
+					DockerImageMetadata: runtime.RawExtension{
+						Object: &dockerapiv10.DockerImage{
+							Config: &dockerapiv10.DockerConfig{
+								ExposedPorts: map[string]struct{}{
+									"8080/tcp": {},
+								},
+							},
+						},
+					},
+				},
+			},
 			want: []corev1.ContainerPort{
 				{
-					Name:          fmt.Sprintf("%d-%s", 8080, strings.ToLower(string("tcp"))),
+					Name:          "8080-tcp",
 					ContainerPort: 8080,
 					Protocol:      "TCP",
 				},
 			},
 		},
+		{
+			name:     "Case: Valid image ports in both Config and ContainerConfig",
+			imageTag: "3.5",
+			imageStreamImage: &imagev1.ImageStreamImage{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "name/imagename@@sha256:9579a93ee",
+				},
+				Image: imagev1.Image{
+					ObjectMeta: metav1.ObjectMeta{
+						Name: "@sha256:9579a93ee",
+					},
+					DockerImageMetadata: runtime.RawExtension{
+						Object: &dockerapiv10.DockerImage{
+							ContainerConfig: dockerapiv10.DockerConfig{
+								ExposedPorts: map[string]struct{}{
+									"8080/tcp": {},
+									"9090/tcp": {},
+								},
+							},
+							Config: &dockerapiv10.DockerConfig{
+								ExposedPorts: map[string]struct{}{
+									"9090/tcp": {},
+									"9191/tcp": {},
+								},
+							},
+						},
+					},
+				},
+			},
+			want: []corev1.ContainerPort{
+				{
+					Name:          "8080-tcp",
+					ContainerPort: 8080,
+					Protocol:      "TCP",
+				},
+				{
+					Name:          "9090-tcp",
+					ContainerPort: 9090,
+					Protocol:      "TCP",
+				},
+				{
+					Name:          "9191-tcp",
+					ContainerPort: 9191,
+					Protocol:      "TCP",
+				},
+			},
+		},
 		{
 			name:             "Case: Invalid image tag",
 			imageTag:         "0.1",
@@ -1436,6 +1531,11 @@ func TestGetExposedPorts(t *testing.T) {
 			fkclient.Namespace = "testing"
 			got, err := fkclient.GetExposedPorts(tt.imageStreamImage)
 
+			// sort result, map is used behind the scene so the ordering might be different
+			sort.Slice(got, func(i, j int) bool {
+				return got[i].ContainerPort < got[j].ContainerPort
+			})
+
 			if !tt.wantErr == (err != nil) {
 				t.Errorf("client.GetExposedPorts(imagestream imageTag) unexpected error %v, wantErr %v", err, tt.wantErr)
 			}
diff --git a/pkg/odo/cli/env/env_test.go b/pkg/odo/cli/env/env_test.go
index 878a5a47c..d7919bfc4 100644
--- a/pkg/odo/cli/env/env_test.go
+++ b/pkg/odo/cli/env/env_test.go
@@ -10,14 +10,14 @@ import (
 func TestPrintSupportedParameters(t *testing.T) {
 	supportedSetParameters := map[string]string{
 		nameParameter:      nameParameterDescription,
-		namespaceParameter: namespaceParameterDescription,
+		projectParameter:   projectParameterDescription,
 		debugportParameter: debugportParameterDescription,
 	}
 
 	wantSetParameters := `Available parameters:
   DebugPort: Use this value to set component debug port
   Name: Use this value to set component name
-  Namespace: Use this value to set component namespace`
+  Project: Use this value to set component project`
 
 	supportedUnsetParameters := map[string]string{
 		debugportParameter: debugportParameterDescription,
diff --git a/pkg/url/url_test.go b/pkg/url/url_test.go
index b5d85d265..95a841dd2 100644
--- a/pkg/url/url_test.go
+++ b/pkg/url/url_test.go
@@ -1977,98 +1977,6 @@ func TestListDockerURL(t *testing.T) {
 	}
 }
 
-func TestGetContainerURL(t *testing.T) {
-	fakeClient := lclient.FakeNew()
-	fakeErrorClient := lclient.FakeErrorNew()
-	testURL1 := envinfo.EnvInfoURL{Name: "testurl1", Port: 8080, ExposedPort: 56789, Kind: "docker"}
-	testURL2 := envinfo.EnvInfoURL{Name: "testurl2", Port: 8080, ExposedPort: 54321, Kind: "docker"}
-	testURL3 := envinfo.EnvInfoURL{Name: "testurl3", Port: 8080, ExposedPort: 65432, Kind: "docker"}
-	esi := &envinfo.EnvSpecificInfo{}
-	err := esi.SetConfiguration("url", testURL1)
-	if err != nil {
-		// discard the error, since no physical file to write
-		t.Log("Expected error since no physical env file to write")
-	}
-	err = esi.SetConfiguration("url", testURL2)
-	if err != nil {
-		// discard the error, since no physical file to write
-		t.Log("Expected error since no physical env file to write")
-	}
-	tests := []struct {
-		name      string
-		client    *lclient.Client
-		component string
-		urlName   string
-		wantURL   URL
-		wantErr   bool
-	}{
-		{
-			name:      "Case 1: Successfully retrieve the not pushed URL object",
-			client:    fakeClient,
-			component: "golang",
-			urlName:   testURL1.Name,
-			wantURL: URL{
-				TypeMeta:   metav1.TypeMeta{Kind: "url", APIVersion: "odo.dev/v1alpha1"},
-				ObjectMeta: metav1.ObjectMeta{Name: testURL1.Name},
-				Spec:       URLSpec{Host: dockercomponent.LocalhostIP, Port: testURL1.Port, ExternalPort: testURL1.ExposedPort},
-				Status: URLStatus{
-					State: StateTypeNotPushed,
-				},
-			},
-			wantErr: false,
-		},
-		{
-			name:      "Case 2: Successfully retrieve the pushed URL object",
-			client:    fakeClient,
-			component: "golang",
-			urlName:   testURL2.Name,
-			wantURL: URL{
-				TypeMeta:   metav1.TypeMeta{Kind: "url", APIVersion: "odo.dev/v1alpha1"},
-				ObjectMeta: metav1.ObjectMeta{Name: testURL2.Name},
-				Spec:       URLSpec{Host: dockercomponent.LocalhostIP, Port: testURL2.Port, ExternalPort: testURL2.ExposedPort},
-				Status: URLStatus{
-					State: StateTypePushed,
-				},
-			},
-			wantErr: false,
-		},
-		{
-			name:      "Case 3: Successfully retrieve the locally deleted URL object",
-			client:    fakeClient,
-			component: "golang",
-			urlName:   testURL3.Name,
-			wantURL: URL{
-				TypeMeta:   metav1.TypeMeta{Kind: "url", APIVersion: "odo.dev/v1alpha1"},
-				ObjectMeta: metav1.ObjectMeta{Name: testURL3.Name},
-				Spec:       URLSpec{Host: dockercomponent.LocalhostIP, Port: testURL3.Port, ExternalPort: testURL3.ExposedPort},
-				Status: URLStatus{
-					State: StateTypeLocallyDeleted,
-				},
-			},
-			wantErr: false,
-		},
-		{
-			name:      "Case 4: Error retrieving the URL object",
-			client:    fakeErrorClient,
-			component: "golang",
-			urlName:   "",
-			wantURL:   URL{},
-			wantErr:   true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			url, err := GetContainerURL(fakeClient, esi, tt.urlName, tt.component)
-			if !tt.wantErr == (err != nil) {
-				t.Errorf("expected %v, got %v", tt.wantErr, err)
-			}
-			if !reflect.DeepEqual(url, tt.wantURL) {
-				t.Errorf("Expected %v, got %v", tt.wantURL, url)
-			}
-		})
-	}
-}
-
 func TestListIngressAndRoute(t *testing.T) {
 	componentName := "testcomponent"
 	containerName := "testcontainer"
diff --git a/tests/examples/source/devfiles/nodejs/devfile-with-valid-events.yaml b/tests/examples/source/devfiles/nodejs/devfile-with-valid-events.yaml
index 16bedaed5..70906d349 100644
--- a/tests/examples/source/devfiles/nodejs/devfile-with-valid-events.yaml
+++ b/tests/examples/source/devfiles/nodejs/devfile-with-valid-events.yaml
@@ -50,7 +50,7 @@ commands:
   - id: wrongPostStart
     exec:
       commandLine: echo I am also a PostStart
-      component: wrongruntime
+      component: runtime #wrongruntime #do not delete comment, tests rely on it for search & replace
       workingDir: /
   - id: myPreStop
     exec:
@@ -78,7 +78,7 @@ commands:
     composite:
       label: Build and Mkdir
       commands:
-        - secondPreStopisWrong
+        - secondPreStop #secondPreStopisWrong #do not delete comment, tests rely on it for search & replace
         - thirdPreStop
       parallel: true
   - id: devbuild
diff --git a/tests/examples/source/devfiles/nodejs/devfileCompositeInvalidComponent.yaml b/tests/examples/source/devfiles/nodejs/devfileCompositeInvalidComponent.yaml
index 8f3c6e552..8ebaa4c5d 100644
--- a/tests/examples/source/devfiles/nodejs/devfileCompositeInvalidComponent.yaml
+++ b/tests/examples/source/devfiles/nodejs/devfileCompositeInvalidComponent.yaml
@@ -17,6 +17,16 @@ components:
         - name: http-3000
           targetPort: 3000
 commands:
+  - id: buildAndMkdir
+    composite:
+         label: Build and Mkdir
+         commands:
+           - mkdir
+           - install
+         parallel: false
+         group: 
+            kind: build
+            isDefault: true
   - id: install
     exec:
       component: runtime
@@ -41,13 +51,3 @@ commands:
       group:
         kind: run
         isDefault: true
-  - id: buildAndMkdir
-    composite:
-         label: Build and Mkdir
-         commands:
-           - mkdir
-           - install
-         parallel: false
-         group: 
-            kind: build
-            isDefault: true
diff --git a/tests/integration/cmd_url_test.go b/tests/integration/cmd_url_test.go
index 3c7bbf4bc..81a1f38d8 100644
--- a/tests/integration/cmd_url_test.go
+++ b/tests/integration/cmd_url_test.go
@@ -95,47 +95,6 @@ var _ = Describe("odo url command tests", func() {
 		})
 	})
 
-	Context("Describing urls", func() {
-		It("should describe appropriate URLs and push message", func() {
-			var stdout string
-			url1 := helper.RandString(5)
-			componentName := helper.RandString(6)
-			helper.CmdShouldPass("odo", "create", "--s2i", "nodejs", "--context", context, "--project", project, componentName, "--ref", "master", "--git", "https://github.com/openshift/nodejs-ex", "--port", "8080,8000")
-
-			helper.CmdShouldPass("odo", "url", "create", url1, "--port", "8080", "--context", context)
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1, "--context", context)
-			helper.MatchAllInOutput(stdout, []string{url1, "Not Pushed", url1, "odo push"})
-
-			helper.CmdShouldPass("odo", "push", "--context", context)
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1, "--context", context)
-			helper.MatchAllInOutput(stdout, []string{url1, "Pushed"})
-			helper.DontMatchAllInOutput(stdout, []string{"Not Pushed", "odo push"})
-
-			helper.CmdShouldPass("odo", "url", "delete", url1, "-f", "--context", context)
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1, "--context", context)
-			helper.MatchAllInOutput(stdout, []string{url1, "Locally Deleted", url1, "odo push"})
-		})
-
-		It("should be able to describe a url in CLI format and machine readable json format for a secure url", func() {
-			helper.CmdShouldPass("odo", "create", "--s2i", "nodejs", "nodejs", "--app", "myapp", "--project", project, "--git", "https://github.com/openshift/nodejs-ex", "--context", context)
-			helper.CmdShouldPass("odo", "url", "create", "myurl", "--secure", "--context", context)
-
-			actualURLDescribeJSON := helper.CmdShouldPass("odo", "url", "describe", "myurl", "-o", "json", "--context", context)
-			desiredURLDescribeJSON := `{"kind":"url","apiVersion":"odo.dev/v1alpha1","metadata":{ "name": "myurl","creationTimestamp": null},"spec":{"port": 8080,"secure": true,"path": "/", "kind": "route"},"status": {"state": "Not Pushed"}}`
-			Expect(desiredURLDescribeJSON).Should(MatchJSON(actualURLDescribeJSON))
-
-			helper.CmdShouldPass("odo", "push", "--context", context)
-
-			// odo url describe -o json
-			actualURLDescribeJSON = helper.CmdShouldPass("odo", "url", "describe", "myurl", "-o", "json", "--context", context)
-			// get the route URL
-			fullURLPath := helper.DetermineRouteURL(context)
-			pathNoHTTP := strings.Split(fullURLPath, "//")[1]
-			desiredURLDescribeJSON = fmt.Sprintf(`{"kind":"url","apiVersion":"odo.dev/v1alpha1","metadata":{ "name": "myurl","creationTimestamp": null},"spec":{"host":"%s","protocol": "https","port": 8080,"secure": true, "path": "/", "kind": "route"},"status": {"state": "Pushed"}}`, pathNoHTTP)
-			Expect(desiredURLDescribeJSON).Should(MatchJSON(actualURLDescribeJSON))
-		})
-	})
-
 	Context("when listing urls using -o json flag", func() {
 		JustBeforeEach(func() {
 			originalDir = helper.Getwd()
diff --git a/tests/integration/component.go b/tests/integration/component.go
index c7f981029..c628032a3 100644
--- a/tests/integration/component.go
+++ b/tests/integration/component.go
@@ -909,9 +909,7 @@ func componentTests(args ...string) {
 			// verify the url
 			stdout = helper.CmdShouldPass("odo", "url", "list", "--context", context)
 
-			// temporary test fix, the url name of the url list output is expected to contain urlName instead
-			// issue to track: https://github.com/openshift/odo/issues/3910
-			helper.MatchAllInOutput(stdout, []string{"port-8080", "Pushed", "false", "route"})
+			helper.MatchAllInOutput(stdout, []string{urlName, "Pushed", "false", "route"})
 			//verify storage
 			stdout = helper.CmdShouldPass("odo", "storage", "list", "--context", context)
 			helper.MatchAllInOutput(stdout, []string{storageName, "Pushed"})
diff --git a/tests/integration/devfile/cmd_devfile_create_test.go b/tests/integration/devfile/cmd_devfile_create_test.go
index bd3fa3c93..542b370fa 100644
--- a/tests/integration/devfile/cmd_devfile_create_test.go
+++ b/tests/integration/devfile/cmd_devfile_create_test.go
@@ -197,6 +197,15 @@ var _ = Describe("odo devfile create command tests", func() {
 			It("should fail to create the devfile component with --devfile points to different devfile", func() {
 				helper.CmdShouldFail("odo", "create", "nodejs", "--devfile", "/path/to/file")
 			})
+
+			It("should fail to create the devfile component for an invalid devfile", func() {
+				// Delete the devfile that was copied in as part of setup
+				helper.DeleteFile("devfile.yaml")
+
+				helper.CmdShouldPass("touch", "devfile.yaml")
+				output := helper.CmdShouldFail("odo", "create", "mycomp", "--devfile", "devfile.yaml")
+				helper.MatchAllInOutput(output, []string{"apiVersion or schemaVersion not present in devfile"})
+			})
 		})
 
 		Context("When devfile exists not in user's working directory and user specify the devfile path via --devfile", func() {
diff --git a/tests/integration/devfile/cmd_devfile_env_test.go b/tests/integration/devfile/cmd_devfile_env_test.go
index 690062590..ddb05e9dd 100644
--- a/tests/integration/devfile/cmd_devfile_env_test.go
+++ b/tests/integration/devfile/cmd_devfile_env_test.go
@@ -13,7 +13,7 @@ import (
 var _ = Describe("odo devfile env command tests", func() {
 	const (
 		testName      = "testname"
-		testNamepace  = "testNamepace"
+		testProject   = "testProject"
 		testDebugPort = "8888"
 		fakeParameter = "fakeParameter"
 	)
@@ -54,7 +54,7 @@ var _ = Describe("odo devfile env command tests", func() {
 				"PARAMETER VALUE",
 				"NAME",
 				"nodejs",
-				"Namespace",
+				"Project",
 				project,
 				"DebugPort",
 			}
@@ -66,7 +66,7 @@ var _ = Describe("odo devfile env command tests", func() {
 		It("Should successfully set and unset the parameters", func() {
 			helper.CmdShouldPass("odo", "create", "nodejs")
 			helper.CmdShouldPass("odo", "env", "set", "Name", testName, "-f")
-			helper.CmdShouldPass("odo", "env", "set", "Namespace", testNamepace, "-f")
+			helper.CmdShouldPass("odo", "env", "set", "Project", testProject, "-f")
 			helper.CmdShouldPass("odo", "env", "set", "DebugPort", testDebugPort, "-f")
 			output := helper.CmdShouldPass("odo", "env", "view")
 			wantOutput := []string{
@@ -74,8 +74,8 @@ var _ = Describe("odo devfile env command tests", func() {
 				"PARAMETER VALUE",
 				"NAME",
 				testName,
-				"Namespace",
-				testNamepace,
+				"Project",
+				testProject,
 				"DebugPort",
 				testDebugPort,
 			}
diff --git a/tests/integration/devfile/cmd_devfile_log_test.go b/tests/integration/devfile/cmd_devfile_log_test.go
index cce392311..f19368d04 100644
--- a/tests/integration/devfile/cmd_devfile_log_test.go
+++ b/tests/integration/devfile/cmd_devfile_log_test.go
@@ -12,8 +12,7 @@ import (
 )
 
 var _ = Describe("odo devfile log command tests", func() {
-	var namespace, context, cmpName, currentWorkingDirectory, originalKubeconfig, projectDirPath string
-	var projectDir = "/projectDir"
+	var namespace, context, cmpName, currentWorkingDirectory, originalKubeconfig string
 	// Using program commmand according to cliRunner in devfile
 	cliRunner := helper.GetCliRunner()
 
@@ -29,7 +28,6 @@ var _ = Describe("odo devfile log command tests", func() {
 		currentWorkingDirectory = helper.Getwd()
 		cmpName = helper.RandString(6)
 		helper.Chdir(context)
-		projectDirPath = context + projectDir
 	})
 
 	// Clean up after the test
@@ -45,16 +43,18 @@ var _ = Describe("odo devfile log command tests", func() {
 
 	Context("Verify odo log for devfile works", func() {
 
-		It("should log run command output", func() {
-			helper.MakeDir(projectDirPath)
-			helper.Chdir(projectDirPath)
+		It("should log run command output and fail for debug command", func() {
 
-			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName)
-			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), projectDirPath)
-			helper.CmdShouldPass("odo", "push", "--project", namespace)
-			output := helper.CmdShouldPass("odo", "log")
+			helper.CmdShouldPass("odo", "create", "java-springboot", "--project", namespace, cmpName, "--context", context)
+			helper.CopyExample(filepath.Join("source", "devfiles", "springboot", "project"), context)
+			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "springboot", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
+			helper.CmdShouldPass("odo", "push", "--context", context)
+			output := helper.CmdShouldPass("odo", "log", "--context", context)
 			Expect(output).To(ContainSubstring("ODO_COMMAND_RUN"))
 
+			// It should fail for debug command as no debug command in devfile
+			helper.CmdShouldFail("odo", "log", "--debug")
+
 			/*
 				Flaky Test odo log -f, see issue https://github.com/openshift/odo/issues/3809
 				match, err := helper.RunCmdWithMatchOutputFromBuffer(30*time.Second, "program=devrun", "odo", "log", "-f")
@@ -65,21 +65,21 @@ var _ = Describe("odo devfile log command tests", func() {
 		})
 
 		It("should error out if component does not exist", func() {
-			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName)
+			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName, "--context", context)
 			helper.CmdShouldFail("odo", "log")
 		})
 
 		It("should log debug command output", func() {
 
-			helper.CmdShouldPass("git", "clone", "https://github.com/che-samples/web-nodejs-sample.git", projectDirPath)
-			helper.Chdir(projectDirPath)
+			projectDir := filepath.Join(context, "projectDir")
 
-			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName)
-			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs"), projectDirPath)
-			helper.RenameFile("devfile-with-debugrun.yaml", "devfile.yaml")
-			helper.CmdShouldPass("odo", "push", "--debug")
+			helper.CmdShouldPass("git", "clone", "https://github.com/che-samples/web-nodejs-sample.git", projectDir)
 
-			output := helper.CmdShouldPass("odo", "log", "--debug")
+			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName, "--context", projectDir)
+			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-debugrun.yaml"), filepath.Join(projectDir, "devfile.yaml"))
+			helper.CmdShouldPass("odo", "push", "--debug", "--context", projectDir)
+
+			output := helper.CmdShouldPass("odo", "log", "--debug", "--context", projectDir)
 			Expect(output).To(ContainSubstring("ODO_COMMAND_DEBUG"))
 
 			/*
@@ -91,16 +91,6 @@ var _ = Describe("odo devfile log command tests", func() {
 
 		})
 
-		// we do not need test for run command as odo push fails
-		// if there is no run command in devfile.
-		It("should give error if no debug command in devfile", func() {
-
-			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
-			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace)
-			helper.CmdShouldPass("odo", "push", "--project", namespace)
-			helper.CmdShouldFail("odo", "log", "--debug")
-		})
-
 	})
 
 })
diff --git a/tests/integration/devfile/cmd_devfile_push_test.go b/tests/integration/devfile/cmd_devfile_push_test.go
index 1f8ed9c1b..bfb59ba96 100644
--- a/tests/integration/devfile/cmd_devfile_push_test.go
+++ b/tests/integration/devfile/cmd_devfile_push_test.go
@@ -58,7 +58,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "springboot", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "springboot", "devfile-with-metadataname-foobar.yaml"), filepath.Join(context, "devfile.yaml"))
 
-			output := helper.CmdShouldPass("odo", "push", "--namespace", namespace)
+			output := helper.CmdShouldPass("odo", "push", "--project", namespace)
 			Expect(output).To(ContainSubstring("Executing devfile commands for component " + name))
 		})
 
@@ -67,12 +67,12 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "springboot", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "springboot", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
 
-			output := helper.CmdShouldPass("odo", "push", "--namespace", namespace, name)
+			output := helper.CmdShouldPass("odo", "push", "--project", namespace, name)
 			Expect(output).To(ContainSubstring("Executing devfile commands for component " + name))
 		})
 
 		It("should error out on devfile flag", func() {
-			helper.CmdShouldFail("odo", "push", "--namespace", namespace, "--devfile", "invalid.yaml")
+			helper.CmdShouldFail("odo", "push", "--project", namespace, "--devfile", "invalid.yaml")
 		})
 
 	})
@@ -254,7 +254,7 @@ var _ = Describe("odo devfile push command tests", func() {
 
 			// Verify odo push failed
 			output := helper.CmdShouldFail("odo", "push", "--context", context)
-			Expect(output).To(ContainSubstring("references an invalid command"))
+			Expect(output).To(ContainSubstring("does not map to a container component"))
 		})
 
 		It("checks that odo push works outside of the context directory", func() {
@@ -386,7 +386,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-valid-events.yaml"), filepath.Join(context, "devfile.yaml"))
 
-			output := helper.CmdShouldPass("odo", "push", "--namespace", namespace)
+			output := helper.CmdShouldPass("odo", "push", "--project", namespace)
 			helper.MatchAllInOutput(output, []string{"PreStart commands have been added to the component"})
 
 			firstPushPodName := cliRunner.GetRunningPodNameByComponent(cmpName, namespace)
@@ -397,7 +397,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.MatchAllInOutput(strings.Join(firstPushInitContainers, ","), expectedInitContainers)
 
 			// Need to force so build and run get triggered again with the component already created.
-			output = helper.CmdShouldPass("odo", "push", "--namespace", namespace, "-f")
+			output = helper.CmdShouldPass("odo", "push", "--project", namespace, "-f")
 			helper.MatchAllInOutput(output, []string{"PreStart commands have been added to the component"})
 
 			secondPushPodName := cliRunner.GetRunningPodNameByComponent(cmpName, namespace)
@@ -442,11 +442,11 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-valid-events.yaml"), filepath.Join(context, "devfile.yaml"))
 
-			output := helper.CmdShouldPass("odo", "push", "--namespace", namespace)
+			output := helper.CmdShouldPass("odo", "push", "--project", namespace)
 			helper.MatchAllInOutput(output, []string{"Executing mypoststart command \"echo I am a PostStart\"", "Executing secondpoststart command \"echo I am also a PostStart\""})
 
 			// Need to force so build and run get triggered again with the component already created.
-			output = helper.CmdShouldPass("odo", "push", "--namespace", namespace, "-f")
+			output = helper.CmdShouldPass("odo", "push", "--project", namespace, "-f")
 			helper.DontMatchAllInOutput(output, []string{"Executing mypoststart command \"echo I am a PostStart\"", "Executing secondpoststart command \"echo I am also a PostStart\""})
 			helper.MatchAllInOutput(output, []string{
 				"Executing devbuild command",
@@ -462,7 +462,7 @@ var _ = Describe("odo devfile push command tests", func() {
 
 			helper.ReplaceString("devfile.yaml", "secondpoststart", "secondpoststart12345")
 
-			output := helper.CmdShouldFail("odo", "push", "--namespace", namespace)
+			output := helper.CmdShouldFail("odo", "push", "--project", namespace)
 			helper.MatchAllInOutput(output, []string{"does not map to a valid devfile command"})
 		})
 
@@ -473,9 +473,10 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-valid-events.yaml"), filepath.Join(context, "devfile.yaml"))
 
 			helper.ReplaceString("devfile.yaml", "secondpoststart", "wrongPostStart")
+			helper.ReplaceString("devfile.yaml", "runtime #wrongruntime", "wrongruntime")
 
-			output := helper.CmdShouldFail("odo", "push", "--namespace", namespace)
-			helper.MatchAllInOutput(output, []string{"the command does not map to a supported component"})
+			output := helper.CmdShouldFail("odo", "push", "--project", namespace)
+			helper.MatchAllInOutput(output, []string{"the command \"wrongpoststart\" does not map to a container component"})
 		})
 
 		It("should err out on an event composite command mentioning an invalid child command", func() {
@@ -485,8 +486,9 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-valid-events.yaml"), filepath.Join(context, "devfile.yaml"))
 
 			helper.ReplaceString("devfile.yaml", "secondpoststart", "myWrongCompCmd")
+			helper.ReplaceString("devfile.yaml", "secondPreStop #secondPreStopisWrong", "secondPreStopisWrong")
 
-			output := helper.CmdShouldFail("odo", "push", "--namespace", namespace)
+			output := helper.CmdShouldFail("odo", "push", "--project", namespace)
 			helper.MatchAllInOutput(output, []string{"does not exist in the devfile"})
 		})
 
@@ -536,9 +538,9 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-hotReload.yaml"), filepath.Join(context, "devfile.yaml"))
 
-			helper.CmdShouldPass("odo", "push", "--namespace", namespace)
+			helper.CmdShouldPass("odo", "push", "--project", namespace)
 
-			helper.CmdShouldPass("odo", "push", "--debug", "--namespace", namespace)
+			helper.CmdShouldPass("odo", "push", "--debug", "--project", namespace)
 
 			logs := helper.CmdShouldPass("odo", "log")
 
@@ -555,13 +557,13 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-debugrun.yaml"), filepath.Join(context, "devfile.yaml"))
 
-			output := helper.CmdShouldPass("odo", "push", "--debug", "--namespace", namespace)
+			output := helper.CmdShouldPass("odo", "push", "--debug", "--project", namespace)
 			helper.MatchAllInOutput(output, []string{
 				"Executing devbuild command",
 				"Executing debugrun command",
 			})
 
-			output = helper.CmdShouldPass("odo", "push", "--namespace", namespace)
+			output = helper.CmdShouldPass("odo", "push", "--project", namespace)
 			helper.MatchAllInOutput(output, []string{
 				"Executing devbuild command",
 				"Executing devrun command",
@@ -575,7 +577,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-volumes.yaml"), filepath.Join(context, "devfile.yaml"))
 
-			output := helper.CmdShouldPass("odo", "push", "--namespace", namespace)
+			output := helper.CmdShouldPass("odo", "push", "--project", namespace)
 			helper.MatchAllInOutput(output, []string{
 				"Executing devbuild command",
 				"Executing devrun command",
@@ -635,7 +637,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "springboot", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "springboot", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
 
-			output := helper.CmdShouldPass("odo", "push", "--namespace", namespace)
+			output := helper.CmdShouldPass("odo", "push", "--project", namespace)
 			Expect(output).To(ContainSubstring("Changes successfully pushed to component"))
 
 			// 2) Rename the pom.xml, which should cause the build to fail if sync is working as expected
@@ -644,7 +646,7 @@ var _ = Describe("odo devfile push command tests", func() {
 
 			// 3) Ensure that the build fails due to missing 'pom.xml', which ensures that the sync operation
 			// correctly renamed pom.xml to pom.xml.renamed.
-			output = helper.CmdShouldFail("odo", "push", "-f", "--namespace", namespace)
+			output = helper.CmdShouldFail("odo", "push", "-f", "--project", namespace)
 			helper.MatchAllInOutput(output, []string{"no POM in this directory"})
 		})
 
@@ -660,12 +662,12 @@ var _ = Describe("odo devfile push command tests", func() {
 			fmt.Fprintf(GinkgoWriter, "Testing with force push %v", shouldForcePush)
 
 			// 1) Push a standard spring boot project
-			output := helper.CmdShouldPass("odo", "push", "--namespace", namespace)
+			output := helper.CmdShouldPass("odo", "push", "--project", namespace)
 			Expect(output).To(ContainSubstring("Changes successfully pushed to component"))
 
 			// 2) Update the devfile.yaml, causing push to redeploy the component
 			helper.ReplaceString("devfile.yaml", "memoryLimit: 768Mi", "memoryLimit: 769Mi")
-			commands := []string{"push", "-v", "4", "--namespace", namespace}
+			commands := []string{"push", "-v", "4", "--project", namespace}
 			if shouldForcePush {
 				// Test both w/ and w/o '-f'
 				commands = append(commands, "-f")
@@ -820,7 +822,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName)
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-multiple-defaults.yaml"), filepath.Join(context, "devfile.yaml"))
-			output := helper.CmdShouldPass("odo", "push", "--build-command", "firstbuild", "--run-command", "singleenv", "--namespace", namespace, "--context", context)
+			output := helper.CmdShouldPass("odo", "push", "--build-command", "firstbuild", "--run-command", "singleenv", "--context", context)
 			Expect(output).To(ContainSubstring("mkdir $ENV1"))
 
 			podName := cliRunner.GetRunningPodNameByComponent(cmpName, namespace)
@@ -833,7 +835,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName)
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-multiple-defaults.yaml"), filepath.Join(context, "devfile.yaml"))
-			output := helper.CmdShouldPass("odo", "push", "--build-command", "firstbuild", "--run-command", "multipleenv", "--namespace", namespace, "--context", context)
+			output := helper.CmdShouldPass("odo", "push", "--build-command", "firstbuild", "--run-command", "multipleenv", "--context", context)
 			Expect(output).To(ContainSubstring("mkdir $ENV1 $ENV2"))
 
 			podName := cliRunner.GetRunningPodNameByComponent(cmpName, namespace)
@@ -846,7 +848,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName)
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-multiple-defaults.yaml"), filepath.Join(context, "devfile.yaml"))
-			output := helper.CmdShouldPass("odo", "push", "--build-command", "firstbuild", "--run-command", "envwithspace", "--namespace", namespace, "--context", context)
+			output := helper.CmdShouldPass("odo", "push", "--build-command", "firstbuild", "--run-command", "envwithspace", "--context", context)
 			Expect(output).To(ContainSubstring("mkdir \\\"$ENV1\\\""))
 
 			podName := cliRunner.GetRunningPodNameByComponent(cmpName, namespace)
@@ -864,7 +866,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			// devfile with clonePath set in project field
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-projects.yaml"), filepath.Join(context, "devfile.yaml"))
 
-			helper.CmdShouldPass("odo", "push", "--namespace", namespace, "--context", context, "--v", "5")
+			helper.CmdShouldPass("odo", "push", "--context", context, "--v", "5")
 			podName := cliRunner.GetRunningPodNameByComponent(cmpName, namespace)
 			// source code is synced to $PROJECTS_ROOT/clonePath
 			// $PROJECTS_ROOT is /projects by default, if sourceMapping is set it is same as sourceMapping
@@ -883,7 +885,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.ReplaceString(filepath.Join(context, "devfile.yaml"), "clonePath: webapp/", "# clonePath: webapp/")
 			helper.ReplaceString(filepath.Join(context, "devfile.yaml"), "workingDir: ${PROJECTS_ROOT}/webapp", "workingDir: ${PROJECTS_ROOT}/nodeshift")
 
-			helper.CmdShouldPass("odo", "push", "--namespace", namespace, "--context", context)
+			helper.CmdShouldPass("odo", "push", "--context", context)
 
 			podName := cliRunner.GetRunningPodNameByComponent(cmpName, namespace)
 			output := cliRunner.ExecListDir(podName, namespace, "/apps/nodeshift")
@@ -895,7 +897,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-with-multiple-projects.yaml"), filepath.Join(context, "devfile.yaml"))
-			helper.CmdShouldPass("odo", "push", "--namespace", namespace, "--context", context)
+			helper.CmdShouldPass("odo", "push", "--context", context)
 			podName := cliRunner.GetRunningPodNameByComponent(cmpName, namespace)
 			// for devfile-with-multiple-projects.yaml source mapping is not set so $PROJECTS_ROOT is /projects
 			// multiple projects, so source code would sync to /projects
@@ -908,7 +910,7 @@ var _ = Describe("odo devfile push command tests", func() {
 			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
 
 			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
-			helper.CmdShouldPass("odo", "push", "--namespace", namespace, "--context", context)
+			helper.CmdShouldPass("odo", "push", "--context", context)
 			podName := cliRunner.GetRunningPodNameByComponent(cmpName, namespace)
 			output := cliRunner.ExecListDir(podName, namespace, "/projects")
 			helper.MatchAllInOutput(output, []string{"package.json"})
diff --git a/tests/integration/devfile/cmd_devfile_url_test.go b/tests/integration/devfile/cmd_devfile_url_test.go
index fe96cc13c..688de087b 100644
--- a/tests/integration/devfile/cmd_devfile_url_test.go
+++ b/tests/integration/devfile/cmd_devfile_url_test.go
@@ -264,55 +264,6 @@ var _ = Describe("odo devfile url command tests", func() {
 
 	})
 
-	Context("Describing urls", func() {
-		It("should describe appropriate Ingress URLs", func() {
-			url1 := helper.RandString(5)
-			host := helper.RandString(5) + ".com"
-
-			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, componentName)
-
-			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
-			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
-
-			helper.CmdShouldPass("odo", "url", "create", url1, "--port", "8080", "--host", host, "--ingress")
-
-			stdout := helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1 + "." + host, "Not Pushed", "false", "ingress", "odo push"})
-
-			helper.CmdShouldPass("odo", "push", "--project", namespace)
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1 + "." + host, "Pushed", "false", "ingress"})
-			helper.CmdShouldPass("odo", "url", "delete", url1, "-f")
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1 + "." + host, "Locally Deleted", "false", "ingress"})
-
-			helper.CmdShouldPass("odo", "url", "create", url1, "--port", "9090", "--host", host, "--secure", "--ingress")
-			helper.CmdShouldPass("odo", "push", "--project", namespace)
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1 + "." + host, "Pushed", "true", "ingress"})
-		})
-
-		It("should describe Ingress URL in json format", func() {
-			url1 := helper.RandString(5)
-			host := helper.RandString(5) + ".com"
-
-			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, componentName)
-
-			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
-			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
-			// remove the endpoint came with the devfile
-			// need to create an ingress to be more general for openshift/non-openshift cluster to run
-			helper.CmdShouldPass("odo", "url", "delete", "3000/tcp", "-f")
-			helper.CmdShouldPass("odo", "url", "create", url1, "--port", "3000", "--host", host, "--ingress")
-			helper.CmdShouldPass("odo", "push", "--project", namespace)
-
-			// odo url describe url1 -o json
-			stdout := helper.CmdShouldPass("odo", "url", "describe", url1, "-o", "json")
-			desiredURLListJSON := fmt.Sprintf(`{"kind":"url","apiVersion":"odo.dev/v1alpha1","metadata":{"name":"%s","creationTimestamp":null},"spec":{"host":"%s","port":3000,"secure": false,"path": "/", "kind":"ingress"},"status":{"state":"Pushed"}}`, url1, url1+"."+host)
-			Expect(desiredURLListJSON).Should(MatchJSON(stdout))
-		})
-	})
-
 	Context("Testing URLs for OpenShift specific scenarios", func() {
 		JustBeforeEach(func() {
 			if os.Getenv("KUBERNETES") == "true" {
@@ -401,32 +352,6 @@ var _ = Describe("odo devfile url command tests", func() {
 			Expect(output).Should(ContainSubstring("3000-tcp"))
 		})
 
-		It("should describe appropriate Route URLs", func() {
-			url1 := helper.RandString(5)
-
-			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, componentName)
-
-			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
-			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
-
-			helper.CmdShouldPass("odo", "url", "create", url1, "--port", "8080")
-
-			stdout := helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1, "Not Pushed", "false", "route", "odo push"})
-
-			helper.CmdShouldPass("odo", "push", "--project", namespace)
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1, "Pushed", "false", "route"})
-			helper.CmdShouldPass("odo", "url", "delete", url1, "-f")
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1, "Locally Deleted", "false", "route"})
-
-			helper.CmdShouldPass("odo", "url", "create", url1, "--port", "9090", "--secure")
-			helper.CmdShouldPass("odo", "push", "--project", namespace)
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1, "Pushed", "true", "route"})
-		})
-
 		It("should create a url for a unsupported devfile component", func() {
 			url1 := helper.RandString(5)
 
diff --git a/tests/integration/devfile/cmd_devfile_watch_test.go b/tests/integration/devfile/cmd_devfile_watch_test.go
index 5f6a18157..8edf496c6 100644
--- a/tests/integration/devfile/cmd_devfile_watch_test.go
+++ b/tests/integration/devfile/cmd_devfile_watch_test.go
@@ -219,6 +219,27 @@ var _ = Describe("odo devfile watch command tests", func() {
 		})
 	})
 
+	Context("when executing odo watch after odo push with ignores flag", func() {
+		It("should be able to ignore the specified file, .git and odo-file-index.json ", func() {
+			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName)
+
+			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
+			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
+
+			output := helper.CmdShouldPass("odo", "push", "--build-command", "build", "--run-command", "run", "--project", namespace)
+			Expect(output).To(ContainSubstring("Changes successfully pushed to component"))
+
+			watchFlag := "--ignore doignoreme.txt"
+			odoV2Watch := utils.OdoV2Watch{
+				CmpName:               cmpName,
+				StringsToBeMatched:    []string{"donotignoreme.txt changed", "Executing devbuild command", "Executing devrun command"},
+				StringsNotToBeMatched: []string{"doignoreme.txt changed", "odo-file-index.json changed", ".git/index changed"},
+			}
+			// odo watch and validate
+			utils.OdoWatchWithIgnore(odoV2Watch, context, watchFlag)
+		})
+	})
+
 	Context("when executing odo watch", func() {
 		It("ensure that index information is updated by watch", func() {
 			helper.CmdShouldPass("odo", "create", "nodejs", "--project", namespace, cmpName)
diff --git a/tests/integration/devfile/docker/cmd_docker_devfile_url_test.go b/tests/integration/devfile/docker/cmd_docker_devfile_url_test.go
index df6015d7d..897ab8872 100644
--- a/tests/integration/devfile/docker/cmd_docker_devfile_url_test.go
+++ b/tests/integration/devfile/docker/cmd_docker_devfile_url_test.go
@@ -155,51 +155,4 @@ var _ = Describe("odo docker devfile url command tests", func() {
 		})
 	})
 
-	Context("Describing urls", func() {
-		It("should describe URL with appropriate state", func() {
-			var stdout string
-			url1 := helper.RandString(5)
-			helper.CmdShouldPass("odo", "create", "nodejs", cmpName)
-
-			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
-			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
-
-			helper.CmdShouldPass("odo", "url", "create", url1)
-
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1, "Not Pushed"})
-
-			helper.CmdShouldPass("odo", "push")
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1, "Pushed"})
-
-			helper.CmdShouldPass("odo", "url", "delete", url1, "-f")
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1, "Locally Deleted"})
-		})
-
-		It("should be able to describe url in machine readable json format", func() {
-			var stdout string
-			url1 := helper.RandString(5)
-
-			helper.CmdShouldPass("odo", "create", "nodejs", cmpName)
-
-			helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), context)
-			helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), filepath.Join(context, "devfile.yaml"))
-
-			stdout = helper.CmdShouldFail("odo", "url", "describe", url1)
-			Expect(stdout).To(ContainSubstring("the url " + url1 + " does not exist"))
-
-			httpPort, err := util.HTTPGetFreePort()
-			Expect(err).NotTo(HaveOccurred())
-			freePort := strconv.Itoa(httpPort)
-			helper.CmdShouldPass("odo", "url", "create", url1, "--exposed-port", freePort, "--now")
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1)
-			helper.MatchAllInOutput(stdout, []string{url1, "Pushed"})
-
-			desiredURLListJSON := fmt.Sprintf(`{"kind":"url","apiVersion":"odo.dev/v1alpha1","metadata":{"name":"%s","creationTimestamp":null},"spec":{"host":"127.0.0.1","port": 3000,"secure":false,"externalport":%s},"status":{"state":"Pushed"}}`, url1, freePort)
-			stdout = helper.CmdShouldPass("odo", "url", "describe", url1, "-o", "json")
-			Expect(desiredURLListJSON).Should(MatchJSON(stdout))
-		})
-	})
 })
diff --git a/tests/integration/devfile/utils/utils.go b/tests/integration/devfile/utils/utils.go
index beb2a7be6..179b2a630 100644
--- a/tests/integration/devfile/utils/utils.go
+++ b/tests/integration/devfile/utils/utils.go
@@ -349,8 +349,9 @@ type OdoV1Watch struct {
 }
 
 type OdoV2Watch struct {
-	CmpName            string
-	StringsToBeMatched []string
+	CmpName               string
+	StringsToBeMatched    []string
+	StringsNotToBeMatched []string
 }
 
 // OdoWatch creates files, dir in the context and watches for the changes to be pushed
@@ -507,6 +508,56 @@ func OdoWatchWithDebug(odoV2Watch OdoV2Watch, context, flag string) {
 	Expect(err).To(BeNil())
 }
 
+// OdoWatchWithIgnore checks if odo watch ignores the specified files and
+// it also checks if odo-file-index.json and .git are ignored
+// when --ignores is used
+func OdoWatchWithIgnore(odoV2Watch OdoV2Watch, context, flag string) {
+
+	startSimulationCh := make(chan bool)
+	go func() {
+		startMsg := <-startSimulationCh
+		if startMsg {
+			_, err := os.Create(filepath.Join(context, "doignoreme.txt"))
+			Expect(err).To(BeNil())
+
+			_, err = os.Create(filepath.Join(context, "donotignoreme.txt"))
+			Expect(err).To(BeNil())
+		}
+	}()
+
+	success, err := helper.WatchNonRetCmdStdOut(
+		("odo watch " + flag + " --context " + context),
+		time.Duration(5)*time.Minute,
+		func(output string) bool {
+			stringsMatched := true
+			for _, stringToBeMatched := range odoV2Watch.StringsToBeMatched {
+				if !strings.Contains(output, stringToBeMatched) {
+					stringsMatched = false
+				}
+			}
+
+			stringsNotMatched := true
+			for _, stringNotToBeMatched := range odoV2Watch.StringsNotToBeMatched {
+				if strings.Contains(output, stringNotToBeMatched) {
+					stringsNotMatched = false
+				}
+			}
+
+			if stringsMatched && stringsNotMatched {
+				return true
+			}
+
+			return false
+		},
+		startSimulationCh,
+		func(output string) bool {
+			return strings.Contains(output, "Waiting for something to change")
+		})
+
+	Expect(success).To(Equal(true))
+	Expect(err).To(BeNil())
+}
+
 func validateContainerExecListDir(odoV1Watch OdoV1Watch, odoV2Watch OdoV2Watch, runner interface{}, platform, project string, isDevfileTest bool) error {
 	var stdOut string