(arg string)
| 134 | var errFileSpecDoesntMatchFormat = errors.New("filespec must match the canonical format: [container:]file/path") |
| 135 | |
| 136 | func parseCpFileSpec(arg string) (*copyFileSpec, error) { |
| 137 | if arg == "" { |
| 138 | return ©FileSpec{ |
| 139 | Path: "-", |
| 140 | }, nil |
| 141 | } |
| 142 | |
| 143 | i := strings.Index(arg, ":") |
| 144 | |
| 145 | // filespec starting with a semicolon is invalid |
| 146 | if i == 0 { |
| 147 | return nil, errFileSpecDoesntMatchFormat |
| 148 | } |
| 149 | |
| 150 | if filepath.IsAbs(arg) { |
| 151 | // Explicit local absolute path, e.g., `C:\foo` or `/foo`. |
| 152 | return ©FileSpec{ |
| 153 | Container: nil, |
| 154 | Path: arg, |
| 155 | }, nil |
| 156 | } |
| 157 | |
| 158 | parts := strings.SplitN(arg, ":", 2) |
| 159 | |
| 160 | if len(parts) == 1 || strings.HasPrefix(parts[0], ".") { |
| 161 | // Either there's no `:` in the arg |
| 162 | // OR it's an explicit local relative path like `./file:name.txt`. |
| 163 | return ©FileSpec{ |
| 164 | Path: arg, |
| 165 | }, nil |
| 166 | } |
| 167 | |
| 168 | return ©FileSpec{ |
| 169 | Container: &parts[0], |
| 170 | Path: parts[1], |
| 171 | }, nil |
| 172 | } |
| 173 | |
| 174 | type copyFileSpec struct { |
| 175 | Container *string |
no outgoing calls
no test coverage detected
searching dependent graphs…