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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions dvc/cli/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
import argparse


class DictAction(argparse.Action):
def __call__(self, parser, args, values, option_string=None): # noqa: ARG002
d = getattr(args, self.dest) or {}

if isinstance(values, list):
kvs = values
else:
kvs = [values]

for kv in kvs:
key, value = kv.split("=")
if not value:
raise argparse.ArgumentError(
self,
f'Could not parse argument "{values}" as k1=v1 k2=v2 ... format',
)
d[key] = value

setattr(args, self.dest, d)


def fix_subparsers(subparsers):
"""Workaround for bug in Python 3. See more info at:
https://bugs.python.org/issue16308
Expand Down
19 changes: 18 additions & 1 deletion dvc/commands/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from dvc.cli import completion
from dvc.cli.command import CmdBaseNoRepo
from dvc.cli.utils import append_doc_link
from dvc.cli.utils import DictAction, append_doc_link
from dvc.exceptions import DvcException

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -38,6 +38,8 @@ def _get_file_from_repo(self):
jobs=self.args.jobs,
force=self.args.force,
config=self.args.config,
remote=self.args.remote,
remote_config=self.args.remote_config,
)
return 0
except CloneError:
Expand Down Expand Up @@ -111,4 +113,19 @@ def add_parser(subparsers, parent_parser):
"in the target repository."
),
)
get_parser.add_argument(
"--remote",
type=str,
help="Remote name to set as a default in the target repository.",
)
get_parser.add_argument(
"--remote-config",
type=str,
nargs="*",
action=DictAction,
help=(
"Remote config options to merge with a remote's config (default or one "
"specified by '--remote') in the target repository."
),
)
get_parser.set_defaults(func=CmdGet)
19 changes: 18 additions & 1 deletion dvc/commands/imp.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from dvc.cli import completion
from dvc.cli.command import CmdBase
from dvc.cli.utils import append_doc_link
from dvc.cli.utils import DictAction, append_doc_link
from dvc.exceptions import DvcException

logger = logging.getLogger(__name__)
Expand All @@ -23,6 +23,8 @@ def run(self):
no_download=self.args.no_download,
jobs=self.args.jobs,
config=self.args.config,
remote=self.args.remote,
remote_config=self.args.remote_config,
)
except CloneError:
logger.exception("failed to import '%s'", self.args.path)
Expand Down Expand Up @@ -103,4 +105,19 @@ def add_parser(subparsers, parent_parser):
"in the target repository."
),
)
import_parser.add_argument(
"--remote",
type=str,
help="Remote name to set as a default in the target repository.",
)
import_parser.add_argument(
"--remote-config",
type=str,
nargs="*",
action=DictAction,
help=(
"Remote config options to merge with a remote's config (default or one "
"specified by '--remote') in the target repository."
),
)
import_parser.set_defaults(func=CmdImport)
19 changes: 18 additions & 1 deletion dvc/commands/ls/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from dvc.cli import completion
from dvc.cli.command import CmdBaseNoRepo
from dvc.cli.utils import append_doc_link
from dvc.cli.utils import DictAction, append_doc_link
from dvc.commands.ls.ls_colors import LsColors
from dvc.exceptions import DvcException
from dvc.ui import ui
Expand Down Expand Up @@ -35,6 +35,8 @@ def run(self):
recursive=self.args.recursive,
dvc_only=self.args.dvc_only,
config=self.args.config,
remote=self.args.remote,
remote_config=self.args.remote_config,
)
if self.args.json:
ui.write_json(entries)
Expand Down Expand Up @@ -89,6 +91,21 @@ def add_parser(subparsers, parent_parser):
"in the target repository."
),
)
list_parser.add_argument(
"--remote",
type=str,
help="Remote name to set as a default in the target repository.",
)
list_parser.add_argument(
"--remote-config",
type=str,
nargs="*",
action=DictAction,
help=(
"Remote config options to merge with a remote's config (default or one "
"specified by '--remote') in the target repository."
),
)
list_parser.add_argument(
"path",
nargs="?",
Expand Down
18 changes: 17 additions & 1 deletion dvc/dependency/repo.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import TYPE_CHECKING, Dict, Optional, Union

from voluptuous import Required
from voluptuous import Any, Required

from dvc.utils import as_posix

Expand All @@ -17,13 +17,15 @@ class RepoDependency(Dependency):
PARAM_REV = "rev"
PARAM_REV_LOCK = "rev_lock"
PARAM_CONFIG = "config"
PARAM_REMOTE = "remote"

REPO_SCHEMA = {
PARAM_REPO: {
Required(PARAM_URL): str,
PARAM_REV: str,
PARAM_REV_LOCK: str,
PARAM_CONFIG: str,
PARAM_REMOTE: Any(str, dict),
}
}

Expand Down Expand Up @@ -76,6 +78,10 @@ def dumpd(self, **kwargs) -> Dict[str, Union[str, Dict[str, str]]]:
if config:
repo[self.PARAM_CONFIG] = config

remote = self.def_repo.get(self.PARAM_REMOTE)
if remote:
repo[self.PARAM_REMOTE] = remote

return {
self.PARAM_PATH: self.def_path,
self.PARAM_REPO: repo,
Expand All @@ -99,6 +105,14 @@ def _make_fs(
from dvc.config import Config
from dvc.fs import DVCFileSystem

rem = self.def_repo.get("remote")
if isinstance(rem, dict):
remote = None # type: ignore[unreachable]
remote_config = rem
else:
remote = rem
remote_config = None

conf = self.def_repo.get("config")
if conf:
config = Config.load_file(conf)
Expand All @@ -113,6 +127,8 @@ def _make_fs(
rev=rev or self._get_rev(locked=locked),
subrepos=True,
config=config,
remote=remote,
remote_config=remote_config,
)

def _get_rev(self, locked: bool = True):
Expand Down
14 changes: 13 additions & 1 deletion dvc/repo/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@ def __init__(self):
)


def get(url, path, out=None, rev=None, jobs=None, force=False, config=None):
def get(
url,
path,
out=None,
rev=None,
jobs=None,
force=False,
config=None,
remote=None,
remote_config=None,
):
from dvc.config import Config
from dvc.dvcfile import is_valid_filename
from dvc.repo import Repo
Expand All @@ -38,6 +48,8 @@ def get(url, path, out=None, rev=None, jobs=None, force=False, config=None):
subrepos=True,
uninitialized=True,
config=config,
remote=remote,
remote_config=remote_config,
) as repo:
from dvc.fs import download
from dvc.fs.data import DataFileSystem
Expand Down
25 changes: 24 additions & 1 deletion dvc/repo/imp.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,32 @@
def imp(self, url, path, out=None, rev=None, config=None, **kwargs):
def imp(
self,
url,
path,
out=None,
rev=None,
config=None,
remote=None,
remote_config=None,
**kwargs,
):
erepo = {"url": url}
if rev is not None:
erepo["rev"] = rev

if config is not None:
erepo["config"] = config

if remote is not None and remote_config is not None:
conf = erepo.get("config") or {}
remotes = conf.get("remote") or {}
remote_conf = remotes.get(remote) or {}
remote_conf.update(remote_config)
remotes[remote] = remote_conf
conf["remote"] = remotes
erepo["config"] = conf
elif remote is not None:
erepo["remote"] = remote
elif remote_config is not None:
erepo["remote"] = remote_config

return self.imp_url(path, out=out, erepo=erepo, frozen=True, **kwargs)
14 changes: 12 additions & 2 deletions dvc/repo/ls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def ls(
recursive: Optional[bool] = None,
dvc_only: bool = False,
config: Optional[str] = None,
remote: Optional[str] = None,
remote_config: Optional[dict] = None,
):
"""Methods for getting files and outputs for the repo.

Expand All @@ -23,7 +25,9 @@ def ls(
rev (str, optional): SHA commit, branch or tag name
recursive (bool, optional): recursively walk the repo
dvc_only (bool, optional): show only DVC-artifacts
config (bool, optional): path to config file
config (str, optional): path to config file
remote (str, optional): remote name to set as a default remote in the repo
remote_config (str, dict): remote config to merge with a remote in the repo

Returns:
list of `entry`
Expand All @@ -47,7 +51,13 @@ def ls(
config_dict = None

with Repo.open(
url, rev=rev, subrepos=True, uninitialized=True, config=config_dict
url,
rev=rev,
subrepos=True,
uninitialized=True,
config=config_dict,
remote=remote,
remote_config=remote_config,
) as repo:
path = path or ""

Expand Down
Loading