Repository: iterative/dvc

Issue:
`exp show --show -json`: `outs` does not return full path for keys
# Bug Report

<!--
## Issue name

Issue names must follow the pattern `command: description` where the command is the dvc command that you are trying to run. The description should describe the consequence of the bug. 

Example: `repro: doesn't detect input changes`
-->

## Description

`exp show` output returns incomplete paths for `outs` (and maybe `deps`).

<!--
A clear and concise description of what the bug is.
-->

### Reproduce

<!--
Step list of how to reproduce the bug
-->

Demo project structure is as follow:

```yaml
stages:
  train:
    cmd: python train.py
    deps:
    - data/MNIST
    - train.py
    params:
    - params.yaml:
    outs:
    - model.pt:
        checkpoint: true
    metrics:
      - training_metrics.json:
          persist: true
          cache: false
    plots:
    - training_metrics
    - misclassified.jpg
    - predictions.json:
        template: confusion
        x: actual
        y: predicted
```

```
.
├── data
│   └── MNIST
│       ├── raw
│       │   ├── t10k-images-idx3-ubyte
│       │   ├── t10k-images-idx3-ubyte.gz
│       │   ├── t10k-labels-idx1-ubyte
│       │   ├── t10k-labels-idx1-ubyte.gz
│       │   ├── train-images-idx3-ubyte
│       │   ├── train-images-idx3-ubyte.gz
│       │   ├── train-labels-idx1-ubyte
│       │   └── train-labels-idx1-ubyte.gz
│       └── raw.dvc
├── dvc.lock
├── dvc.yaml
├── misclassified.jpg
├── model.pt
├── params.yaml
├── predictions.json
├── requirements.txt
├── train.py
├── training_metrics
│   └── scalars
│       ├── acc.tsv
│       └── loss.tsv
└── training_metrics.json
```

`exp show --show-json` returns

```json
{
  "workspace": {
    "baseline": {
      "data": {
        "timestamp": null,
        "params": {
          "params.yaml": {
            "data": {
              "lr": 0.003,
              "weight_decay": 0,
              "epochs": 15
            }
          }
        },
        "deps": {
          "data/MNIST": {
            "hash": "0aed307494600d178fbdc0d000d6db38.dir",
            "size": 66544866,
            "nfiles": 10
          },
          "train.py": {
            "hash": "90f29a92c178927514c7f4d61a984a8a",
            "size": 4865,
            "nfiles": null
          }
        },
        "outs": {
          "model.pt": {
            "hash": "38126781764ca9fb04496ca2c2173056",
            "size": 439383,
            "nfiles": null
          },
          "raw": {
            "hash": "8c257df187855c681f88bde92d721ccd.dir",
            "size": 66544770,
            "nfiles": 8
          }
        },
        "queued": false,
        "running": false,
        "executor": null,
        "metrics": {
          "training_metrics.json": {
            "data": {
              "step": 14,
              "loss": 0.9596208930015564,
              "acc": 0.7735
            }
          }
        }
      }
    }
  },
  "024aa30e3e0b226f101b8323eeaea7ebb6537316": {
    "baseline": {
      "data": {
        "timestamp": "2022-05-20T08:34:01",
        "params": {
          "params.yaml": {
            "data": {
              "lr": 0.003,
              "weight_decay": 0,
              "epochs": 15
            }
          }
        },
        "deps": {
          "data/MNIST": {
            "hash": "0aed307494600d178fbdc0d000d6db38.dir",
            "size": 66544866,
            "nfiles": 10
          },
          "train.py": {
            "hash": "90f29a92c178927514c7f4d61a984a8a",
            "size": 4865,
            "nfiles": null
          }
        },
        "outs": {
          "model.pt": {
            "hash": "38126781764ca9fb04496ca2c2173056",
            "size": 439383,
            "nfiles": null
          },
          "raw": {
            "hash": "8c257df187855c681f88bde92d721ccd.dir",
            "size": 66544770,
            "nfiles": 8
          }
        },
        "queued": false,
        "running": false,
        "executor": null,
        "metrics": {
          "training_metrics.json": {
            "data": {
              "step": 14,
              "loss": 0.9596208930015564,
              "acc": 0.7735
            }
          }
        },
        "name": "main"
      }
    }
  }
}
```

Notice the `"raw":` key in the outs output. I believe this should be `data/MNIST/raw`.

<!--
Example:

1. dvc init
3. Copy dataset.zip to the directory
4. dvc add dataset.zip
5. dvc run -d dataset.zip -o model ./train.sh
6. modify dataset.zip
7. dvc repro
-->

### Expected

<!--
A clear and concise description of what you expect to happen.
-->

Full paths are returns for all `deps`/`outs`.

### Environment information

<!--
This is required to ensure that we can reproduce the bug.
-->

**Output of `dvc doctor`:**

```console
$ dvc doctor
DVC version: 2.10.2 (pip)
---------------------------------
Platform: Python 3.9.9 on macOS-12.4-x86_64-i386-64bit
Supports:
        webhdfs (fsspec = 2022.3.0),
        http (aiohttp = 3.8.1, aiohttp-retry = 2.4.6),
        https (aiohttp = 3.8.1, aiohttp-retry = 2.4.6),
        s3 (s3fs = 2022.3.0, boto3 = 1.21.21)
Cache types: reflink, hardlink, symlink
Cache directory: apfs on /dev/disk1s5s1
Caches: local
Remotes: s3
Workspace directory: apfs on /dev/disk1s5s1
Repo: dvc (subdir), git
```

**Additional Information (if any):**

Please LMK if I have misunderstood something and this is expected. Thank you.

<!--
Please check https://github.com/iterative/dvc/wiki/Debugging-DVC on ways to gather more information regarding the issue.

If applicable, please also provide a `--verbose` output of the command, eg: `dvc add --verbose`.
If the issue is regarding the performance, please attach the profiling information and the benchmark comparisons.
-->



Discussion:

Resolving patch:
diff --git a/dvc/repo/experiments/show.py b/dvc/repo/experiments/show.py
--- a/dvc/repo/experiments/show.py
+++ b/dvc/repo/experiments/show.py
@@ -7,7 +7,7 @@
 from dvc.repo.metrics.show import _gather_metrics
 from dvc.repo.params.show import _gather_params
 from dvc.scm import iter_revs
-from dvc.utils import error_handler, onerror_collect
+from dvc.utils import error_handler, onerror_collect, relpath
 
 if TYPE_CHECKING:
     from dvc.repo import Repo
@@ -45,7 +45,7 @@ def _collect_experiment_commit(
             res["params"] = params
 
         res["deps"] = {
-            dep.def_path: {
+            relpath(dep.fs_path, repo.root_dir): {
                 "hash": dep.hash_info.value,
                 "size": dep.meta.size,
                 "nfiles": dep.meta.nfiles,
@@ -53,12 +53,13 @@ def _collect_experiment_commit(
             for dep in repo.index.deps
             if not isinstance(dep, (ParamsDependency, RepoDependency))
         }
-
         res["outs"] = {
-            out.def_path: {
+            relpath(out.fs_path, repo.root_dir): {
                 "hash": out.hash_info.value,
                 "size": out.meta.size,
                 "nfiles": out.meta.nfiles,
+                "use_cache": out.use_cache,
+                "is_data_source": out.stage.is_data_source,
             }
             for out in repo.index.outs
             if not (out.is_metric or out.is_plot)


Test patch:
diff --git a/tests/func/experiments/test_show.py b/tests/func/experiments/test_show.py
--- a/tests/func/experiments/test_show.py
+++ b/tests/func/experiments/test_show.py
@@ -34,6 +34,7 @@ def make_executor_info(**kwargs):
     return ExecutorInfo(**kwargs)
 
 
+@pytest.mark.vscode
 def test_show_simple(tmp_dir, scm, dvc, exp_stage):
     assert dvc.experiments.show()["workspace"] == {
         "baseline": {
@@ -57,6 +58,7 @@ def test_show_simple(tmp_dir, scm, dvc, exp_stage):
     }
 
 
+@pytest.mark.vscode
 @pytest.mark.parametrize("workspace", [True, False])
 def test_show_experiment(tmp_dir, scm, dvc, exp_stage, workspace):
     baseline_rev = scm.get_rev()
@@ -101,6 +103,7 @@ def test_show_experiment(tmp_dir, scm, dvc, exp_stage, workspace):
             assert exp["data"]["params"]["params.yaml"] == expected_params
 
 
+@pytest.mark.vscode
 def test_show_queued(tmp_dir, scm, dvc, exp_stage):
     baseline_rev = scm.get_rev()
 
@@ -132,6 +135,7 @@ def test_show_queued(tmp_dir, scm, dvc, exp_stage):
     assert exp["params"]["params.yaml"] == {"data": {"foo": 3}}
 
 
+@pytest.mark.vscode
 @pytest.mark.parametrize("workspace", [True, False])
 def test_show_checkpoint(
     tmp_dir, scm, dvc, checkpoint_stage, capsys, workspace
@@ -169,6 +173,7 @@ def test_show_checkpoint(
         assert f"{fs} {name}" in cap.out
 
 
+@pytest.mark.vscode
 @pytest.mark.parametrize("workspace", [True, False])
 def test_show_checkpoint_branch(
     tmp_dir, scm, dvc, checkpoint_stage, capsys, workspace
@@ -281,6 +286,7 @@ def test_show_filter(
     assert "Experiment" not in cap.out
 
 
+@pytest.mark.vscode
 def test_show_multiple_commits(tmp_dir, scm, dvc, exp_stage):
     init_rev = scm.get_rev()
     tmp_dir.scm_gen("file", "file", "commit")
@@ -318,6 +324,7 @@ def test_show_sort(tmp_dir, scm, dvc, exp_stage, caplog):
     )
 
 
+@pytest.mark.vscode
 def test_show_running_workspace(tmp_dir, scm, dvc, exp_stage, capsys):
     pid_dir = os.path.join(dvc.tmp_dir, EXEC_TMP_DIR, EXEC_PID_DIR)
     info = make_executor_info(location=BaseExecutor.DEFAULT_LOCATION)
@@ -626,7 +633,8 @@ def test_show_parallel_coordinates(tmp_dir, dvc, scm, mocker, capsys):
     assert '"label": "Experiment"' not in html_text
 
 
-def test_show_outs(tmp_dir, dvc, scm):
+@pytest.mark.vscode
+def test_show_outs(tmp_dir, dvc, scm, erepo_dir):
     tmp_dir.gen("copy.py", COPY_SCRIPT)
     params_file = tmp_dir / "params.yaml"
     params_data = {
@@ -652,9 +660,61 @@ def test_show_outs(tmp_dir, dvc, scm):
             "hash": ANY,
             "size": ANY,
             "nfiles": None,
+            "use_cache": True,
+            "is_data_source": False,
         }
     }
 
+    tmp_dir.dvc_gen("out_add", "foo", commit="dvc add output")
+
+    outs = dvc.experiments.show()["workspace"]["baseline"]["data"]["outs"]
+    assert outs == {
+        "out": {
+            "hash": ANY,
+            "size": ANY,
+            "nfiles": None,
+            "use_cache": True,
+            "is_data_source": False,
+        },
+        "out_add": {
+            "hash": ANY,
+            "size": ANY,
+            "nfiles": None,
+            "use_cache": True,
+            "is_data_source": True,
+        },
+    }
+
+    with erepo_dir.chdir():
+        erepo_dir.dvc_gen("out", "out content", commit="create out")
+
+    dvc.imp(os.fspath(erepo_dir), "out", "out_imported")
+
+    outs = dvc.experiments.show()["workspace"]["baseline"]["data"]["outs"]
+    assert outs == {
+        "out": {
+            "hash": ANY,
+            "size": ANY,
+            "nfiles": None,
+            "use_cache": True,
+            "is_data_source": False,
+        },
+        "out_add": {
+            "hash": ANY,
+            "size": ANY,
+            "nfiles": None,
+            "use_cache": True,
+            "is_data_source": True,
+        },
+        "out_imported": {
+            "hash": ANY,
+            "size": ANY,
+            "nfiles": None,
+            "use_cache": True,
+            "is_data_source": True,
+        },
+    }
+
 
 def test_metrics_renaming(tmp_dir, dvc, scm, capsys):
     tmp_dir.gen("copy.py", COPY_SCRIPT)