| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2015 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of go-ethereum. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // go-ethereum is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // go-ethereum is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | package utils | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	"flag" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"os/user" | 
					
						
							| 
									
										
										
										
											2015-08-06 15:18:32 +01:00
										 |  |  | 	"path" | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-09 11:44:42 +02:00
										 |  |  | 	"gopkg.in/urfave/cli.v1" | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Custom type which is registered in the flags library which cli uses for | 
					
						
							|  |  |  | // argument parsing. This allows us to expand Value to an absolute path when | 
					
						
							|  |  |  | // the argument is parsed | 
					
						
							|  |  |  | type DirectoryString struct { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	Value string | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 20:06:27 +02:00
										 |  |  | func (self *DirectoryString) String() string { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	return self.Value | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 20:06:27 +02:00
										 |  |  | func (self *DirectoryString) Set(value string) error { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	self.Value = expandPath(value) | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Custom cli.Flag type which expand the received string to an absolute path. | 
					
						
							|  |  |  | // e.g. ~/.ethereum -> /home/username/.ethereum | 
					
						
							|  |  |  | type DirectoryFlag struct { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	cli.GenericFlag | 
					
						
							|  |  |  | 	Name   string | 
					
						
							|  |  |  | 	Value  DirectoryString | 
					
						
							|  |  |  | 	Usage  string | 
					
						
							|  |  |  | 	EnvVar string | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self DirectoryFlag) String() string { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	var fmtString string | 
					
						
							|  |  |  | 	fmtString = "%s %v\t%v" | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	if len(self.Value.Value) > 0 { | 
					
						
							|  |  |  | 		fmtString = "%s \"%v\"\t%v" | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		fmtString = "%s %v\t%v" | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	return withEnvHint(self.EnvVar, fmt.Sprintf(fmtString, prefixedNames(self.Name), self.Value.Value, self.Usage)) | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func eachName(longName string, fn func(string)) { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	parts := strings.Split(longName, ",") | 
					
						
							|  |  |  | 	for _, name := range parts { | 
					
						
							|  |  |  | 		name = strings.Trim(name, " ") | 
					
						
							|  |  |  | 		fn(name) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | // called by cli library, grabs variable from environment (if in env) | 
					
						
							|  |  |  | // and adds variable to flag set for parsing. | 
					
						
							|  |  |  | func (self DirectoryFlag) Apply(set *flag.FlagSet) { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	if self.EnvVar != "" { | 
					
						
							|  |  |  | 		for _, envVar := range strings.Split(self.EnvVar, ",") { | 
					
						
							|  |  |  | 			envVar = strings.TrimSpace(envVar) | 
					
						
							|  |  |  | 			if envVal := os.Getenv(envVar); envVal != "" { | 
					
						
							|  |  |  | 				self.Value.Value = envVal | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	eachName(self.Name, func(name string) { | 
					
						
							| 
									
										
										
										
											2015-04-09 20:06:27 +02:00
										 |  |  | 		set.Var(&self.Value, self.Name, self.Usage) | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func prefixFor(name string) (prefix string) { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	if len(name) == 1 { | 
					
						
							|  |  |  | 		prefix = "-" | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		prefix = "--" | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	return | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func prefixedNames(fullName string) (prefixed string) { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	parts := strings.Split(fullName, ",") | 
					
						
							|  |  |  | 	for i, name := range parts { | 
					
						
							|  |  |  | 		name = strings.Trim(name, " ") | 
					
						
							|  |  |  | 		prefixed += prefixFor(name) + name | 
					
						
							|  |  |  | 		if i < len(parts)-1 { | 
					
						
							|  |  |  | 			prefixed += ", " | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func withEnvHint(envVar, str string) string { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	envText := "" | 
					
						
							|  |  |  | 	if envVar != "" { | 
					
						
							|  |  |  | 		envText = fmt.Sprintf(" [$%s]", strings.Join(strings.Split(envVar, ","), ", $")) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return str + envText | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self DirectoryFlag) getName() string { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	return self.Name | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *DirectoryFlag) Set(value string) { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	self.Value.Value = value | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Expands a file path | 
					
						
							|  |  |  | // 1. replace tilde with users home dir | 
					
						
							|  |  |  | // 2. expands embedded environment variables | 
					
						
							|  |  |  | // 3. cleans the path, e.g. /a/b/../c -> /a/c | 
					
						
							|  |  |  | // Note, it has limitations, e.g. ~someuser/tmp will not be expanded | 
					
						
							|  |  |  | func expandPath(p string) string { | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 	if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") { | 
					
						
							| 
									
										
										
										
											2016-09-16 11:53:50 +02:00
										 |  |  | 		if home := homeDir(); home != "" { | 
					
						
							|  |  |  | 			p = home + p[1:] | 
					
						
							| 
									
										
										
										
											2015-04-09 10:26:26 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-06 15:18:32 +01:00
										 |  |  | 	return path.Clean(os.ExpandEnv(p)) | 
					
						
							| 
									
										
										
										
											2015-04-08 15:43:55 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-16 11:53:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func homeDir() string { | 
					
						
							|  |  |  | 	if home := os.Getenv("HOME"); home != "" { | 
					
						
							|  |  |  | 		return home | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if usr, err := user.Current(); err == nil { | 
					
						
							|  |  |  | 		return usr.HomeDir | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return "" | 
					
						
							|  |  |  | } |