Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | package Psh::Builtins::Firsttime; |
2 | use strict; | |
3 | ||
4 | require Psh::Util; | |
5 | ||
6 | =item * C<firsttime> | |
7 | ||
8 | firsttime is a setup utility which should be used by first-time | |
9 | psh users. It will parse existing shell rc files and try to | |
10 | convert as much settings as possible and generate a .pshrc | |
11 | file. It currently can only convert aliases, bash completions | |
12 | and environment variables. | |
13 | ||
14 | =cut | |
15 | ||
16 | my (%aliases,$env,$complete); | |
17 | ||
18 | sub bi_firsttime | |
19 | { | |
20 | my $line; | |
21 | ||
22 | print <<EOT; | |
23 | Welcome to the Firsttime Setup Utility! | |
24 | ||
25 | This utility will try to setup an initial .pshrc file for you. | |
26 | You can interrupt the process anytime using ^C | |
27 | ||
28 | EOT | |
29 | ||
30 | my $home=Psh::OS::get_home_dir(); | |
31 | ||
32 | unless ($home) { | |
33 | print <<EOT; | |
34 | You unfortunately do not have a home directory where the .pshrc file could | |
35 | be stored. Please set the environment variable HOME to a sensible value. | |
36 | EOT | |
37 | return (0,undef); | |
38 | } | |
39 | ||
40 | my $tmp; | |
41 | ||
42 | $tmp= Psh::OS::catfile($home,'.pshrc'); | |
43 | if (-r $tmp) { | |
44 | $line=Psh::Util::prompt('yn', | |
45 | "Warning - you already have a .pshrc file!!!!\n". | |
46 | "Do you really want to continue (y/n)? "); | |
47 | return (0,undef) if $line eq 'n'; | |
48 | } | |
49 | ||
50 | my $text= "# This file was autogenerated by psh firsttime\n\n"; | |
51 | print "Please press ENTER to start...\n"; | |
52 | $line=<STDIN>; | |
53 | ||
54 | %aliases=(); | |
55 | $env=''; | |
56 | $complete=''; | |
57 | ||
58 | my @sh_files=qw(.bashrc .bash_login .login); | |
59 | my @csh_files=qw(.cshrc); | |
60 | ||
61 | # .alias files usually _only_ contain aliases and functions | |
62 | # so we offer to source them | |
63 | $tmp= Psh::OS::catfile($home,'.alias'); | |
64 | if (-r $tmp) { | |
65 | $line=Psh::Util::prompt('ics', | |
66 | "We have found a .alias file. Do you want to\n". | |
67 | "(c)all it from your .pshrc file\n". | |
68 | "(i)nsert it into your .pshrc file\n". | |
69 | "(s)kip ? "); | |
70 | ||
71 | if ($line eq 'c') { | |
72 | $text.="source ~/.alias\n"; | |
73 | } elsif ($line eq 'i') { | |
74 | _parse_sh_file($tmp); | |
75 | } | |
76 | } | |
77 | ||
78 | $line=Psh::Util::prompt('cs',"Parse (s) bash/sh files or\n (c) csh files? "); | |
79 | if ($line eq 's') { | |
80 | foreach my $file (@sh_files) { | |
81 | $tmp= Psh::OS::catfile($home,$file); | |
82 | if (-r $tmp) { | |
83 | $line=Psh::Util::prompt('yn', | |
84 | "Found file $file - parse it (y/n)? "); | |
85 | if ($line eq 'y') { | |
86 | _parse_sh_file($tmp); | |
87 | } | |
88 | } | |
89 | } | |
90 | } else { | |
91 | foreach my $file (@csh_files) { | |
92 | $tmp= Psh::OS::catfile($home,$file); | |
93 | if (-r $tmp) { | |
94 | $line=Psh::Util::prompt('yn', | |
95 | "Found file $file - parse it (y/n)? "); | |
96 | if ($line eq 'y') { | |
97 | _parse_csh_file($tmp); | |
98 | } | |
99 | } | |
100 | } | |
101 | } | |
102 | ||
103 | $text.=_generate_stuff(); | |
104 | ||
105 | print "The setup process is finished now.\n"; | |
106 | print "Press ENTER to save to $home/.pshrc now or ^C to stop.\n"; | |
107 | $line=<STDIN>; | |
108 | open(FILE,"> $home/.pshrc"); | |
109 | print FILE $text; | |
110 | close(FILE); | |
111 | print "$home/.pshrc saved\n"; | |
112 | return (1,undef); | |
113 | } | |
114 | ||
115 | sub _generate_stuff { | |
116 | my $text=''; | |
117 | my ($key,$value); | |
118 | ||
119 | $text=$env.$complete; | |
120 | while ( ($key,$value)= each %aliases) { | |
121 | $text.="alias $key=$value\n"; | |
122 | } | |
123 | return $text; | |
124 | } | |
125 | ||
126 | sub _parse_sh_file { | |
127 | my $file= shift; | |
128 | my $text=''; | |
129 | open(FILE,"< $file"); | |
130 | while (<FILE>) { | |
131 | my $line=$_; | |
132 | chomp $line; | |
133 | next if $line=~/^\s*#/; | |
134 | if ($line=~/^\s*alias (\S+)\=(.+)$/) { | |
135 | my $key= $1; | |
136 | my $value= $2; | |
137 | if (exists $aliases{$key}) { | |
138 | print STDERR "Warning: alias $key redefined.\n"; | |
139 | } | |
140 | $aliases{$key}=$value; | |
141 | } elsif ($line=~/^\s*function (\S+) \{/) { | |
142 | my $tmp=$line; | |
143 | while (Psh::Parser::incomplete_expr($tmp)>0 && <FILE>) { | |
144 | $tmp.=$_; | |
145 | } | |
146 | $env.="$tmp\n"; | |
147 | } elsif ($line=~/^\s*(\S+)\=(.*)$/) { | |
148 | my $key= uc($1); | |
149 | my $value= _change_env_value($2); | |
150 | $env.="setenv $key=$value\n"; | |
151 | } elsif ($line=~/^\s*export (\S+)\=(.+)$/) { | |
152 | my $key= uc($1); | |
153 | my $value= _change_env_value($2); | |
154 | $env.="setenv $key=$value\n"; | |
155 | } | |
156 | ||
157 | } | |
158 | close(FILE); | |
159 | return undef; | |
160 | } | |
161 | ||
162 | ||
163 | sub _parse_csh_file { | |
164 | my $file= shift; | |
165 | my $text=''; | |
166 | open(FILE,"< $file"); | |
167 | while (<FILE>) { | |
168 | my $line=$_; | |
169 | chomp $line; | |
170 | next if $line=~/^\s*#/; | |
171 | if ($line=~/^\s*alias (\S+)\s+(.+)$/) { | |
172 | my $key= $1; | |
173 | my $value= $2; | |
174 | if (exists $aliases{$key}) { | |
175 | print STDERR "Warning: alias $key redefined.\n"; | |
176 | } | |
177 | $aliases{$key}=$value; | |
178 | } elsif ($line=~/^\s*setenv\s+(\S+)\s+(.+)$/) { | |
179 | my $key= uc($1); | |
180 | my $value= _change_env_value($2); | |
181 | $env.="setenv $key=\"$value\"\n"; | |
182 | } elsif ($line=~/^\s*set\s+(\S+)\=\s*["]([^\"]+)["]\s*$/ || | |
183 | $line=~/^\s*set\s+(\S+)\=\s*[']([^\']+)[']\s*$/ || | |
184 | $line=~/^\s*set\s+(\S+)\=\s*(\([^\']+\))\s*$/ || | |
185 | $line=~/^\s*set\s+(\S+)\=([^#\s]+)\s*/) { | |
186 | my $key= uc($1); | |
187 | my $value= _change_env_value($2); | |
188 | $env.="setenv $key=$value\n"; | |
189 | } | |
190 | } | |
191 | close(FILE); | |
192 | return undef; | |
193 | } | |
194 | ||
195 | sub _change_env_value | |
196 | { | |
197 | my $val= shift; | |
198 | return $val if ($val=~/^\'(.*)\'$/); # do not modify if single quotes | |
199 | $val=~s/\$([a-zA-Z0-9_]+)/\$ENV\{$1\}/g; | |
200 | $val=~s/\@/\\@/g; | |
201 | return "\"$val\"" if ($val !~ /^\"(.*)\"$/); | |
202 | return $val; | |
203 | } | |
204 | ||
205 | 1; |