github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/url/format.go (about)

     1  package url
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  // Format formats a URL into a human-readable (and reparsable) format.
     8  func (u *URL) Format(environmentPrefix string) string {
     9  	if u.Protocol == Protocol_Local {
    10  		return u.formatLocal()
    11  	} else if u.Protocol == Protocol_SSH {
    12  		return u.formatSSH()
    13  	} else if u.Protocol == Protocol_Docker {
    14  		return u.formatDocker(environmentPrefix)
    15  	}
    16  	panic("unknown URL protocol")
    17  }
    18  
    19  // formatLocal formats a local URL.
    20  func (u *URL) formatLocal() string {
    21  	return u.Path
    22  }
    23  
    24  // formatSSH formats an SSH URL into an SCP-style URL.
    25  func (u *URL) formatSSH() string {
    26  	// Create the base result.
    27  	result := u.Host
    28  
    29  	// Add username if present.
    30  	if u.User != "" {
    31  		result = fmt.Sprintf("%s@%s", u.User, result)
    32  	}
    33  
    34  	// Add port if present.
    35  	if u.Port != 0 {
    36  		result = fmt.Sprintf("%s:%d", result, u.Port)
    37  	}
    38  
    39  	// Add path.
    40  	result = fmt.Sprintf("%s:%s", result, u.Path)
    41  
    42  	// Done.
    43  	return result
    44  }
    45  
    46  // invalidDockerURLFormat is the value returned by formatDocker when a URL is
    47  // provided that breaks invariants.
    48  const invalidDockerURLFormat = "<invalid-docker-url>"
    49  
    50  // formatDocker formats a Docker URL.
    51  func (u *URL) formatDocker(environmentPrefix string) string {
    52  	// Start with the container name.
    53  	result := u.Host
    54  
    55  	// Add username if present.
    56  	if u.User != "" {
    57  		result = fmt.Sprintf("%s@%s", u.User, result)
    58  	}
    59  
    60  	// Append the path in a manner that depends on the URL kind.
    61  	if u.Kind == Kind_Synchronization {
    62  		// If this is a home-directory-relative path or a Windows path, then we
    63  		// need to prepend a slash.
    64  		if u.Path == "" {
    65  			return invalidDockerURLFormat
    66  		} else if u.Path[0] == '/' {
    67  			result += u.Path
    68  		} else if u.Path[0] == '~' || isWindowsPath(u.Path) {
    69  			result += fmt.Sprintf("/%s", u.Path)
    70  		} else {
    71  			return invalidDockerURLFormat
    72  		}
    73  	} else if u.Kind == Kind_Forwarding {
    74  		result += fmt.Sprintf(":%s", u.Path)
    75  	} else {
    76  		panic("unhandled URL kind")
    77  	}
    78  
    79  	// Add the scheme.
    80  	result = dockerURLPrefix + result
    81  
    82  	// Add environment variable information if requested.
    83  	if environmentPrefix != "" {
    84  		for _, variable := range DockerEnvironmentVariables {
    85  			if value, present := u.Environment[variable]; present {
    86  				result += fmt.Sprintf("%s%s=%s", environmentPrefix, variable, value)
    87  			}
    88  		}
    89  	}
    90  
    91  	// Add parameter information, if requested.
    92  	if environmentPrefix != "" {
    93  		for _, name := range dockerParameterNames {
    94  			if value, present := u.Parameters[name]; present {
    95  				if value == "" {
    96  					result += fmt.Sprintf("%s%s=true", environmentPrefix, name)
    97  				} else {
    98  					result += fmt.Sprintf("%s%s=%s", environmentPrefix, name, value)
    99  				}
   100  			}
   101  		}
   102  	}
   103  
   104  	// Done.
   105  	return result
   106  }