aboutsummaryrefslogtreecommitdiff
path: root/IkiWiki/Setup/Automator.pm
blob: 7d9eca3afef7f929edfb8a1c4ddc1da2fc3be875 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/perl
# Ikiwiki setup automator.

package IkiWiki::Setup::Automator;

use warnings;
use strict;
use IkiWiki;
use IkiWiki::UserInfo;
use Term::ReadLine;
use File::Path;
use Encode;

sub ask ($$) {
	my ($question, $default)=@_;

	my $r=Term::ReadLine->new("ikiwiki");
	$r->readline(encode_utf8($question)." ", $default);
}

sub prettydir ($) {
	my $dir=shift;
	$dir=~s/^\Q$ENV{HOME}\E\//~\//;
	return $dir;
}

sub import (@) {
	my $this=shift;
	IkiWiki::Setup::merge({@_});

	# Sanitize this to avoid problimatic directory names.
	$config{wikiname}=~s/[^-A-Za-z0-9_]//g;
	if (! length $config{wikiname}) {
		error gettext("you must enter a wikiname (that contains alphanumerics)");
	}

	# Avoid overwriting any existing files.
	foreach my $key (qw{srcdir destdir repository dumpsetup}) {
		next unless exists $config{$key};
		my $add="";
		my $dir=IkiWiki::dirname($config{$key})."/";
		my $base=IkiWiki::basename($config{$key});
		while (-e $dir.$add.$base) {
			$add=1 if ! $add;
			$add++;
		}
		$config{$key}=$dir.$add.$base;
	}
	
	# Set up wrapper
	if ($config{rcs}) {
		if ($config{rcs} eq 'git') {
			$config{git_wrapper}=$config{repository}."/hooks/post-update";
		}
		elsif ($config{rcs} eq 'svn') {
			$config{svn_wrapper}=$config{repository}."/hooks/post-commit";
		}
		elsif ($config{rcs} eq 'monotone') {
			$config{mtn_wrapper}=$config{srcdir}."_MTN/ikiwiki-netsync-hook";
		}
		elsif ($config{rcs} eq 'bzr') {
			# TODO
		}
		elsif ($config{rcs} eq 'mercurial') {
			# TODO
		}
		else {
			error sprintf(gettext("unsupported revision control system %s"),
			       	$config{rcs});
		}
	}

	IkiWiki::checkconfig();

	print "\n\nSetting up $config{wikiname} ...\n";

	# Set up the srcdir.
	mkpath($config{srcdir}) || die "mkdir $config{srcdir}: $!";
	# Copy in example wiki.
	if (exists $config{example}) {
		# cp -R is POSIX
		# Another reason not to use -a is so that pages such as blog
		# posts will not have old creation dates on this new wiki.
		system("cp -R $IkiWiki::installdir/share/ikiwiki/examples/$config{example}/* $config{srcdir}");
		delete $config{example};
	}

	# Set up the repository.
	delete $config{repository} if ! $config{rcs} || $config{rcs}=~/bzr|mercurial/;
	if ($config{rcs}) {
		my @params=($config{rcs}, $config{srcdir});
		push @params, $config{repository} if exists $config{repository};
		if (system("ikiwiki-makerepo", @params) != 0) {
			error gettext("failed to set up the repository with ikiwiki-makerepo");
		}
	}

	# Generate setup file.
	require IkiWiki::Setup;
	IkiWiki::Setup::dump($config{dumpsetup});

	# Build the wiki, but w/o wrappers, so it's not live yet.
	mkpath($config{destdir}) || die "mkdir $config{destdir}: $!";
	if (system("ikiwiki", "--refresh", "--setup", $config{dumpsetup}) != 0) {
		die "ikiwiki --refresh --setup $config{dumpsetup} failed";
	}

	# Create admin user(s).
	foreach my $admin (@{$config{adminuser}}) {
		next if $admin=~/^http\?:\/\//; # openid
		
		# Prompt for password w/o echo.
		my ($password, $password2);
		system('stty -echo 2>/dev/null');
		local $|=1;
		print "\n\nCreating wiki admin $admin ...\n";
		for (;;) {
			print "Choose a password: ";
			chomp($password=<STDIN>);
			print "Confirm password: ";
			chomp($password2=<STDIN>);

			last if $password2 eq $password;

			print "Password mismatch.\n\n";
		}
		print "\n\n\n";
		system('stty sane 2>/dev/null');

		if (IkiWiki::userinfo_setall($admin, { regdate => time }) &&
		    IkiWiki::Plugin::passwordauth::setpassword($admin, $password)) {
			IkiWiki::userinfo_set($admin, "email", $config{adminemail}) if defined $config{adminemail};
		}
		else {
			error("problem setting up $admin user");
		}
	}
	
	# Add wrappers, make live.
	if (system("ikiwiki", "--wrappers", "--setup", $config{dumpsetup}) != 0) {
		die "ikiwiki --wrappers --setup $config{dumpsetup} failed";
	}

	# Add it to the wikilist.
	mkpath("$ENV{HOME}/.ikiwiki");
	open (WIKILIST, ">>$ENV{HOME}/.ikiwiki/wikilist") || die "$ENV{HOME}/.ikiwiki/wikilist: $!";
	print WIKILIST "$ENV{USER} $config{dumpsetup}\n";
	close WIKILIST;
	if (system("ikiwiki-update-wikilist") != 0) {
		print STDERR "** Failed to add you to the system wikilist file.\n";
		print STDERR "** (Probably ikiwiki-update-wikilist is not SUID root.)\n";
		print STDERR "** Your wiki will not be automatically updated when ikiwiki is upgraded.\n";
	}
	
	# Done!
	print "\n\nSuccessfully set up $config{wikiname}:\n";
	foreach my $key (qw{url srcdir destdir repository}) {
		next unless exists $config{$key};
		print "\t$key: ".(" " x (10 - length($key)))." ".
			prettydir($config{$key})."\n";
	}
	print "To modify settings, edit ".prettydir($config{dumpsetup})." and then run:\n";
	print "	ikiwiki -setup ".prettydir($config{dumpsetup})."\n";
	exit 0;
}

1