diff mbox

[dim] dim: allow a space separated list of URLs for each repo in drm_tip_repos

Message ID 20170928145147.19196-1-jani.nikula@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jani Nikula Sept. 28, 2017, 2:51 p.m. UTC
This lets us configure a space separated list of URLs for each repo in
drm_tip_repos, with all accepted protocols and sources, and the first
one found gets picked. This way we don't have to have a complicated set
of rules for converting between ssh, git and https protocol URLs.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>

---

!!! UNTESTED !!!
---
 dim | 97 +++++++++++++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 63 insertions(+), 34 deletions(-)

Comments

Jani Nikula Oct. 3, 2017, 6:15 a.m. UTC | #1
On Thu, 28 Sep 2017, Jani Nikula <jani.nikula@intel.com> wrote:
> This lets us configure a space separated list of URLs for each repo in
> drm_tip_repos, with all accepted protocols and sources, and the first
> one found gets picked. This way we don't have to have a complicated set
> of rules for converting between ssh, git and https protocol URLs.

I merged this last week with Daniel's IRC ack. We'll need to give people
a little bit of time before updating nightly.conf. Sorry for the
inconvenience in the mean time.

We should probably think about adding some real versioning to dim to be
able to handle this kind of stuff more systematically.

BR,
Jani.



>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>
> ---
>
> !!! UNTESTED !!!
> ---
>  dim | 97 +++++++++++++++++++++++++++++++++++++++++++++------------------------
>  1 file changed, 63 insertions(+), 34 deletions(-)
>
> diff --git a/dim b/dim
> index c6c746cdb154..d2f165893161 100755
> --- a/dim
> +++ b/dim
> @@ -255,44 +255,73 @@ fi
>  # The below functions map between these.
>  #
>  
> -function url_to_remote # url
> +function url_to_remote # url [url ...]
>  {
>  	local url remote
>  
> -	url="$1"
> -
> -	if [[ -z "$url" ]]; then
> -		echoerr "$0 without url"
> +	if [[ "$#" = "0" ]]; then
> +		echoerr "url_to_remote without URLs"
>  		return 1
>  	fi
>  
> -	remote=$(git remote -v | grep -m 1 "$url" | cut -f 1)
> -
> -	if [[ -z "$remote" ]]; then
> -		git_url=$(echo $url | sed -e 's/git\./anongit./' -e 's/ssh:/git:/')
> -		remote=$(git remote -v | grep -m 1 "$git_url" | cut -f 1)
> +	for url; do
> +		remote=$(git remote -v | grep -m 1 "$url" | cut -f 1)
> +		if [[ -n "$remote" ]]; then
> +			echo "$remote"
> +			return 0
> +		fi
> +	done
>  
> -		if [[ -z "$remote" ]]; then
> -			echoerr "No git remote for url $url or $git_url found in $(pwd)"
> -			remote=${url%.git}
> -			remote=${remote##*/}
> -			read -r -i "$remote" -e -p "Enter a name to auto-add this remote, leave blank to abort: " || true
> -			if [[ "$REPLY" == "" ]] ; then
> -				echoerr "Please set it up yourself using:"
> -				echoerr "    $ git remote add <name> $url"
> -				echoerr "with a name of your choice."
> -				exit 1
> -			fi
> +	echoerr "No git remote for any of the URLs $* found in $(pwd)"
>  
> -			git remote add $remote $url
> -		fi
> +	url=$1
> +	remote=${url%.git}
> +	remote=${remote##*/}
> +	read -r -i "$remote" -e -p "Enter a name to auto-add this remote, leave blank to abort: " || true
> +	if [[ "$REPLY" == "" ]] ; then
> +		echoerr "Please set it up yourself using:"
> +		echoerr "    $ git remote add <name> $url"
> +		echoerr "with a name of your choice."
> +		exit 1
>  	fi
>  
> +	git remote add $remote $url
> +
>  	echo $remote
>  
>  	return 0
>  }
>  
> +function url_to_git_url # url [url ...]
> +{
> +	local url git_url
> +
> +	if [[ "$#" = "0" ]]; then
> +		echoerr "url_to_git_url without URLs"
> +		return 1
> +	fi
> +
> +	# Find the git:// URL, converting from ssh:// URL as fallback
> +	for url; do
> +		case $url in
> +			git://*)
> +				git_url=$url
> +				break
> +				;;
> +			ssh://*)
> +				git_url=$(echo $url | sed -e 's/git\./anongit./' -e 's/ssh:/git:/')
> +				;;
> +		esac
> +	done
> +
> +	if [[ -z "$git_url" ]]; then
> +		echoerr "No git or ssh URL in any of the URLs $*"
> +		return 1
> +	fi
> +
> +	echo $git_url
> +}
> +
>  function branch_to_remote # branch
>  {
>  	local branch remote
> @@ -595,7 +624,7 @@ function commit_rerere_cache
>  
>  function dim_rebuild_tip
>  {
> -	local integration_branch specfile time first rerere repo url remote
> +	local integration_branch specfile time first rerere repo url_list remote
>  
>  	integration_branch=drm-tip
>  	specfile=$(mktemp)
> @@ -627,8 +656,8 @@ function dim_rebuild_tip
>  	echo "Done."
>  
>  	for repo in "${!drm_tip_repos[@]}"; do
> -		url=${drm_tip_repos[$repo]}
> -		remote=$(url_to_remote $url)
> +		url_list=${drm_tip_repos[$repo]}
> +		remote=$(url_to_remote $url_list)
>  		echo -n "Fetching $repo (local remote $remote)... "
>  		git_fetch_helper $remote
>  		echo "Done."
> @@ -639,8 +668,8 @@ function dim_rebuild_tip
>  		local branch override sha1 fixup_file
>  
>  		read -r repo branch override <<< $conf
> -		url=${drm_tip_repos[$repo]}
> -		remote=$(url_to_remote $url)
> +		url_list=${drm_tip_repos[$repo]}
> +		remote=$(url_to_remote $url_list)
>  		sha1=$remote/$branch
>  
>  		echo -n "Merging $repo (local remote $remote) $branch... "
> @@ -1641,7 +1670,7 @@ function prep_pull_tag_summary
>  # dim_pull_request branch upstream
>  function dim_pull_request
>  {
> -	local branch upstream remote repo req_file url git_url suffix tag
> +	local branch upstream remote repo req_file url_list git_url suffix tag
>  
>  	branch=${1:?$usage}
>  	upstream=${2:?$usage}
> @@ -1679,8 +1708,8 @@ function dim_pull_request
>  		repo=$(branch_to_repo $branch)
>  	fi
>  
> -	url=${drm_tip_repos[$repo]}
> -	git_url=$(echo $url | sed -e 's/git\./anongit./' -e 's/ssh:/git:/')
> +	url_list=${drm_tip_repos[$repo]}
> +	git_url=$(url_to_git_url $url_list)
>  
>  	git request-pull $upstream $git_url $tag >> $req_file
>  	$DRY $DIM_MUA -s "[PULL] $branch" \
> @@ -1729,7 +1758,7 @@ function dim_list_branches
>  dim_alias_ub=update-branches
>  function dim_update_branches
>  {
> -	local repo remote
> +	local repo remote url_list
>  
>  	cd $DIM_PREFIX/$DIM_DRM_INTEL
>  
> @@ -1740,8 +1769,8 @@ function dim_update_branches
>  	fi
>  
>  	for repo in "${!drm_tip_repos[@]}"; do
> -		url=${drm_tip_repos[$repo]}
> -		if ! remote=$(url_to_remote $url 2>/dev/null); then
> +		url_list=${drm_tip_repos[$repo]}
> +		if ! remote=$(url_to_remote $url_list 2>/dev/null); then
>  			continue
>  		fi
>  		echo -n "Fetching $repo (local remote $remote)... "
Daniel Vetter Oct. 3, 2017, 8:01 a.m. UTC | #2
On Tue, Oct 03, 2017 at 09:15:46AM +0300, Jani Nikula wrote:
> On Thu, 28 Sep 2017, Jani Nikula <jani.nikula@intel.com> wrote:
> > This lets us configure a space separated list of URLs for each repo in
> > drm_tip_repos, with all accepted protocols and sources, and the first
> > one found gets picked. This way we don't have to have a complicated set
> > of rules for converting between ssh, git and https protocol URLs.
> 
> I merged this last week with Daniel's IRC ack. We'll need to give people
> a little bit of time before updating nightly.conf. Sorry for the
> inconvenience in the mean time.
> 
> We should probably think about adding some real versioning to dim to be
> able to handle this kind of stuff more systematically.

We update dim in dim update-branches, and we complain about old dim. I
think a few days of update time is plenty enough, at least it seems to
have been for adding the drm-amd remote.
-Daniel

> 
> BR,
> Jani.
> 
> 
> 
> >
> > Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >
> > ---
> >
> > !!! UNTESTED !!!
> > ---
> >  dim | 97 +++++++++++++++++++++++++++++++++++++++++++++------------------------
> >  1 file changed, 63 insertions(+), 34 deletions(-)
> >
> > diff --git a/dim b/dim
> > index c6c746cdb154..d2f165893161 100755
> > --- a/dim
> > +++ b/dim
> > @@ -255,44 +255,73 @@ fi
> >  # The below functions map between these.
> >  #
> >  
> > -function url_to_remote # url
> > +function url_to_remote # url [url ...]
> >  {
> >  	local url remote
> >  
> > -	url="$1"
> > -
> > -	if [[ -z "$url" ]]; then
> > -		echoerr "$0 without url"
> > +	if [[ "$#" = "0" ]]; then
> > +		echoerr "url_to_remote without URLs"
> >  		return 1
> >  	fi
> >  
> > -	remote=$(git remote -v | grep -m 1 "$url" | cut -f 1)
> > -
> > -	if [[ -z "$remote" ]]; then
> > -		git_url=$(echo $url | sed -e 's/git\./anongit./' -e 's/ssh:/git:/')
> > -		remote=$(git remote -v | grep -m 1 "$git_url" | cut -f 1)
> > +	for url; do
> > +		remote=$(git remote -v | grep -m 1 "$url" | cut -f 1)
> > +		if [[ -n "$remote" ]]; then
> > +			echo "$remote"
> > +			return 0
> > +		fi
> > +	done
> >  
> > -		if [[ -z "$remote" ]]; then
> > -			echoerr "No git remote for url $url or $git_url found in $(pwd)"
> > -			remote=${url%.git}
> > -			remote=${remote##*/}
> > -			read -r -i "$remote" -e -p "Enter a name to auto-add this remote, leave blank to abort: " || true
> > -			if [[ "$REPLY" == "" ]] ; then
> > -				echoerr "Please set it up yourself using:"
> > -				echoerr "    $ git remote add <name> $url"
> > -				echoerr "with a name of your choice."
> > -				exit 1
> > -			fi
> > +	echoerr "No git remote for any of the URLs $* found in $(pwd)"
> >  
> > -			git remote add $remote $url
> > -		fi
> > +	url=$1
> > +	remote=${url%.git}
> > +	remote=${remote##*/}
> > +	read -r -i "$remote" -e -p "Enter a name to auto-add this remote, leave blank to abort: " || true
> > +	if [[ "$REPLY" == "" ]] ; then
> > +		echoerr "Please set it up yourself using:"
> > +		echoerr "    $ git remote add <name> $url"
> > +		echoerr "with a name of your choice."
> > +		exit 1
> >  	fi
> >  
> > +	git remote add $remote $url
> > +
> >  	echo $remote
> >  
> >  	return 0
> >  }
> >  
> > +function url_to_git_url # url [url ...]
> > +{
> > +	local url git_url
> > +
> > +	if [[ "$#" = "0" ]]; then
> > +		echoerr "url_to_git_url without URLs"
> > +		return 1
> > +	fi
> > +
> > +	# Find the git:// URL, converting from ssh:// URL as fallback
> > +	for url; do
> > +		case $url in
> > +			git://*)
> > +				git_url=$url
> > +				break
> > +				;;
> > +			ssh://*)
> > +				git_url=$(echo $url | sed -e 's/git\./anongit./' -e 's/ssh:/git:/')
> > +				;;
> > +		esac
> > +	done
> > +
> > +	if [[ -z "$git_url" ]]; then
> > +		echoerr "No git or ssh URL in any of the URLs $*"
> > +		return 1
> > +	fi
> > +
> > +	echo $git_url
> > +}
> > +
> >  function branch_to_remote # branch
> >  {
> >  	local branch remote
> > @@ -595,7 +624,7 @@ function commit_rerere_cache
> >  
> >  function dim_rebuild_tip
> >  {
> > -	local integration_branch specfile time first rerere repo url remote
> > +	local integration_branch specfile time first rerere repo url_list remote
> >  
> >  	integration_branch=drm-tip
> >  	specfile=$(mktemp)
> > @@ -627,8 +656,8 @@ function dim_rebuild_tip
> >  	echo "Done."
> >  
> >  	for repo in "${!drm_tip_repos[@]}"; do
> > -		url=${drm_tip_repos[$repo]}
> > -		remote=$(url_to_remote $url)
> > +		url_list=${drm_tip_repos[$repo]}
> > +		remote=$(url_to_remote $url_list)
> >  		echo -n "Fetching $repo (local remote $remote)... "
> >  		git_fetch_helper $remote
> >  		echo "Done."
> > @@ -639,8 +668,8 @@ function dim_rebuild_tip
> >  		local branch override sha1 fixup_file
> >  
> >  		read -r repo branch override <<< $conf
> > -		url=${drm_tip_repos[$repo]}
> > -		remote=$(url_to_remote $url)
> > +		url_list=${drm_tip_repos[$repo]}
> > +		remote=$(url_to_remote $url_list)
> >  		sha1=$remote/$branch
> >  
> >  		echo -n "Merging $repo (local remote $remote) $branch... "
> > @@ -1641,7 +1670,7 @@ function prep_pull_tag_summary
> >  # dim_pull_request branch upstream
> >  function dim_pull_request
> >  {
> > -	local branch upstream remote repo req_file url git_url suffix tag
> > +	local branch upstream remote repo req_file url_list git_url suffix tag
> >  
> >  	branch=${1:?$usage}
> >  	upstream=${2:?$usage}
> > @@ -1679,8 +1708,8 @@ function dim_pull_request
> >  		repo=$(branch_to_repo $branch)
> >  	fi
> >  
> > -	url=${drm_tip_repos[$repo]}
> > -	git_url=$(echo $url | sed -e 's/git\./anongit./' -e 's/ssh:/git:/')
> > +	url_list=${drm_tip_repos[$repo]}
> > +	git_url=$(url_to_git_url $url_list)
> >  
> >  	git request-pull $upstream $git_url $tag >> $req_file
> >  	$DRY $DIM_MUA -s "[PULL] $branch" \
> > @@ -1729,7 +1758,7 @@ function dim_list_branches
> >  dim_alias_ub=update-branches
> >  function dim_update_branches
> >  {
> > -	local repo remote
> > +	local repo remote url_list
> >  
> >  	cd $DIM_PREFIX/$DIM_DRM_INTEL
> >  
> > @@ -1740,8 +1769,8 @@ function dim_update_branches
> >  	fi
> >  
> >  	for repo in "${!drm_tip_repos[@]}"; do
> > -		url=${drm_tip_repos[$repo]}
> > -		if ! remote=$(url_to_remote $url 2>/dev/null); then
> > +		url_list=${drm_tip_repos[$repo]}
> > +		if ! remote=$(url_to_remote $url_list 2>/dev/null); then
> >  			continue
> >  		fi
> >  		echo -n "Fetching $repo (local remote $remote)... "
> 
> -- 
> Jani Nikula, Intel Open Source Technology Center
Jani Nikula Oct. 9, 2017, 10:30 a.m. UTC | #3
On Tue, 03 Oct 2017, Jani Nikula <jani.nikula@intel.com> wrote:
> I merged this last week with Daniel's IRC ack. We'll need to give people
> a little bit of time before updating nightly.conf. Sorry for the
> inconvenience in the mean time.

Andrzej, all the bits and pieces for this have been pushed, so https://
should just work for all repos *except* Dave's drm tree. I don't know
why, but [1] doesn't advertize https for it.

BR,
Jani.


[1] https://cgit.freedesktop.org/~airlied/linux/
Daniel Stone Oct. 9, 2017, 10:37 a.m. UTC | #4
Hey,

On 9 October 2017 at 11:30, Jani Nikula <jani.nikula@intel.com> wrote:
> On Tue, 03 Oct 2017, Jani Nikula <jani.nikula@intel.com> wrote:
>> I merged this last week with Daniel's IRC ack. We'll need to give people
>> a little bit of time before updating nightly.conf. Sorry for the
>> inconvenience in the mean time.
>
> Andrzej, all the bits and pieces for this have been pushed, so https://
> should just work for all repos *except* Dave's drm tree. I don't know
> why, but [1] doesn't advertize https for it.

Probably because it's not linked in from his public_html? He'd need to
do that, and also make sure that git-update-server-info was run in a
hook somewhere too.

Cheers,
Daniel
Andrzej Hajda Oct. 10, 2017, 8:10 a.m. UTC | #5
On 09.10.2017 12:30, Jani Nikula wrote:
> On Tue, 03 Oct 2017, Jani Nikula <jani.nikula@intel.com> wrote:
>> I merged this last week with Daniel's IRC ack. We'll need to give people
>> a little bit of time before updating nightly.conf. Sorry for the
>> inconvenience in the mean time.
> Andrzej, all the bits and pieces for this have been pushed, so https://
> should just work for all repos *except* Dave's drm tree. I don't know
> why, but [1] doesn't advertize https for it.
>
> BR,
> Jani.
>
>
> [1] https://cgit.freedesktop.org/~airlied/linux/
>
Sorry for late response, I have tested the code and it works, thanks.


Regards

Andrzej
Jani Nikula Oct. 11, 2017, 7:22 p.m. UTC | #6
On Mon, 09 Oct 2017, Daniel Stone <daniel@fooishbar.org> wrote:
> Hey,
>
> On 9 October 2017 at 11:30, Jani Nikula <jani.nikula@intel.com> wrote:
>> On Tue, 03 Oct 2017, Jani Nikula <jani.nikula@intel.com> wrote:
>>> I merged this last week with Daniel's IRC ack. We'll need to give people
>>> a little bit of time before updating nightly.conf. Sorry for the
>>> inconvenience in the mean time.
>>
>> Andrzej, all the bits and pieces for this have been pushed, so https://
>> should just work for all repos *except* Dave's drm tree. I don't know
>> why, but [1] doesn't advertize https for it.
>
> Probably because it's not linked in from his public_html? He'd need to
> do that, and also make sure that git-update-server-info was run in a
> hook somewhere too.

Sorry, how do you do these two steps exactly? I tried looking around in
the docs, [1] is the closest I could find but nothing on https.

BR,
Jani.


[1] https://www.freedesktop.org/wiki/Infrastructure/git/RepositoryAdmin/
diff mbox

Patch

diff --git a/dim b/dim
index c6c746cdb154..d2f165893161 100755
--- a/dim
+++ b/dim
@@ -255,44 +255,73 @@  fi
 # The below functions map between these.
 #
 
-function url_to_remote # url
+function url_to_remote # url [url ...]
 {
 	local url remote
 
-	url="$1"
-
-	if [[ -z "$url" ]]; then
-		echoerr "$0 without url"
+	if [[ "$#" = "0" ]]; then
+		echoerr "url_to_remote without URLs"
 		return 1
 	fi
 
-	remote=$(git remote -v | grep -m 1 "$url" | cut -f 1)
-
-	if [[ -z "$remote" ]]; then
-		git_url=$(echo $url | sed -e 's/git\./anongit./' -e 's/ssh:/git:/')
-		remote=$(git remote -v | grep -m 1 "$git_url" | cut -f 1)
+	for url; do
+		remote=$(git remote -v | grep -m 1 "$url" | cut -f 1)
+		if [[ -n "$remote" ]]; then
+			echo "$remote"
+			return 0
+		fi
+	done
 
-		if [[ -z "$remote" ]]; then
-			echoerr "No git remote for url $url or $git_url found in $(pwd)"
-			remote=${url%.git}
-			remote=${remote##*/}
-			read -r -i "$remote" -e -p "Enter a name to auto-add this remote, leave blank to abort: " || true
-			if [[ "$REPLY" == "" ]] ; then
-				echoerr "Please set it up yourself using:"
-				echoerr "    $ git remote add <name> $url"
-				echoerr "with a name of your choice."
-				exit 1
-			fi
+	echoerr "No git remote for any of the URLs $* found in $(pwd)"
 
-			git remote add $remote $url
-		fi
+	url=$1
+	remote=${url%.git}
+	remote=${remote##*/}
+	read -r -i "$remote" -e -p "Enter a name to auto-add this remote, leave blank to abort: " || true
+	if [[ "$REPLY" == "" ]] ; then
+		echoerr "Please set it up yourself using:"
+		echoerr "    $ git remote add <name> $url"
+		echoerr "with a name of your choice."
+		exit 1
 	fi
 
+	git remote add $remote $url
+
 	echo $remote
 
 	return 0
 }
 
+function url_to_git_url # url [url ...]
+{
+	local url git_url
+
+	if [[ "$#" = "0" ]]; then
+		echoerr "url_to_git_url without URLs"
+		return 1
+	fi
+
+	# Find the git:// URL, converting from ssh:// URL as fallback
+	for url; do
+		case $url in
+			git://*)
+				git_url=$url
+				break
+				;;
+			ssh://*)
+				git_url=$(echo $url | sed -e 's/git\./anongit./' -e 's/ssh:/git:/')
+				;;
+		esac
+	done
+
+	if [[ -z "$git_url" ]]; then
+		echoerr "No git or ssh URL in any of the URLs $*"
+		return 1
+	fi
+
+	echo $git_url
+}
+
 function branch_to_remote # branch
 {
 	local branch remote
@@ -595,7 +624,7 @@  function commit_rerere_cache
 
 function dim_rebuild_tip
 {
-	local integration_branch specfile time first rerere repo url remote
+	local integration_branch specfile time first rerere repo url_list remote
 
 	integration_branch=drm-tip
 	specfile=$(mktemp)
@@ -627,8 +656,8 @@  function dim_rebuild_tip
 	echo "Done."
 
 	for repo in "${!drm_tip_repos[@]}"; do
-		url=${drm_tip_repos[$repo]}
-		remote=$(url_to_remote $url)
+		url_list=${drm_tip_repos[$repo]}
+		remote=$(url_to_remote $url_list)
 		echo -n "Fetching $repo (local remote $remote)... "
 		git_fetch_helper $remote
 		echo "Done."
@@ -639,8 +668,8 @@  function dim_rebuild_tip
 		local branch override sha1 fixup_file
 
 		read -r repo branch override <<< $conf
-		url=${drm_tip_repos[$repo]}
-		remote=$(url_to_remote $url)
+		url_list=${drm_tip_repos[$repo]}
+		remote=$(url_to_remote $url_list)
 		sha1=$remote/$branch
 
 		echo -n "Merging $repo (local remote $remote) $branch... "
@@ -1641,7 +1670,7 @@  function prep_pull_tag_summary
 # dim_pull_request branch upstream
 function dim_pull_request
 {
-	local branch upstream remote repo req_file url git_url suffix tag
+	local branch upstream remote repo req_file url_list git_url suffix tag
 
 	branch=${1:?$usage}
 	upstream=${2:?$usage}
@@ -1679,8 +1708,8 @@  function dim_pull_request
 		repo=$(branch_to_repo $branch)
 	fi
 
-	url=${drm_tip_repos[$repo]}
-	git_url=$(echo $url | sed -e 's/git\./anongit./' -e 's/ssh:/git:/')
+	url_list=${drm_tip_repos[$repo]}
+	git_url=$(url_to_git_url $url_list)
 
 	git request-pull $upstream $git_url $tag >> $req_file
 	$DRY $DIM_MUA -s "[PULL] $branch" \
@@ -1729,7 +1758,7 @@  function dim_list_branches
 dim_alias_ub=update-branches
 function dim_update_branches
 {
-	local repo remote
+	local repo remote url_list
 
 	cd $DIM_PREFIX/$DIM_DRM_INTEL
 
@@ -1740,8 +1769,8 @@  function dim_update_branches
 	fi
 
 	for repo in "${!drm_tip_repos[@]}"; do
-		url=${drm_tip_repos[$repo]}
-		if ! remote=$(url_to_remote $url 2>/dev/null); then
+		url_list=${drm_tip_repos[$repo]}
+		if ! remote=$(url_to_remote $url_list 2>/dev/null); then
 			continue
 		fi
 		echo -n "Fetching $repo (local remote $remote)... "