summaryrefslogtreecommitdiffstats
path: root/bin/modpkg
blob: f1c8c90faa5a05bcaa513972d960d3284c477deb (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
168
169
170
171
#!/usr/bin/env tclsh

set prog modpkg
set pbfields {pkgname pkgver pkgrel pkgdesc pkgbase
	epoch url license install changelog source noextract
	md5sums sha1sums sha256sums sha384sums sha512sums
	groups arch backup
	depends makedepends checkdepends optdepends
	conflicts provides replaces
	options}
set pbfuncs {build check package}
set dotfuncs {pre_install post_install
	pre_upgrade post_upgrade
	pre_remove post_remove}

proc scanfields {inchan} {
	global pkgdata

	set fld {}
	while {[gets $inchan line] >= 0} {
		if {$fld eq {}} {
			# Skip extra (>1) empty lines.
			if {$line ne {}} {
				lassign [list $line] fld vals
			}
		} elseif {$line eq {}} {
			set pkgdata($fld) $vals
			lassign {} fld vals
		} else {
			lappend vals $line
		}
	}
	if {$fld != {}} { set pkgdata($fld) $vals }
}

proc printfields {outchan} {
	global pkgdata

	foreach {fld vals} [array get pkgdata] {
		puts $outchan [join [concat $fld $vals] "\n"]
		puts ""
	}
}

if {$argc != 1} {
	puts stderr "usage: $prog \[path to modifier script\] < PKGDATA > PKGDATA.new"
	exit 2
}

set mod [lindex $argv 0]
if {! [file exists $mod]} {
	puts stderr "$prog: error: mod file does not exist"
	exit 1
}
set modch [open $mod]

scanfields stdin

set modi [interp create]

foreach {name vals} [array get pkgdata] {
	if {$name in $pbfields} {
		$modi eval [list set $name $vals]
	}
}
$modi eval [list set pbfuncs $pbfuncs]
$modi eval [list set dotfuncs $dotfuncs]
$modi eval {
	proc trimbash {code} {
		set code [string trim $code]
		set lines [split $code "\n"]
		set code {}
		for {set i 0} {$i < [llength $lines]} {incr i} {
			set ln "  [string trim [lindex $lines $i]]"
			set code "$code$ln\n"
		}
		return $code
	}

	proc initfunc {file func} {
		if {! [file exists PKGTREE/$file/$func]} {
			exec putpkgtree $file $func beg << "${func}()\n(\n"
			exec putpkgtree $file $func end << ")\n"
		}
	}

	proc initdotfunc {func} {
		global pkgname source
		if {! [file exists PKGTREE/$pkgname.install]} {
			lappend source "$pkgname.install"
		}
		initfunc $pkgname.install $func
	}

	proc fput {name code section} {
		global dotfuncs pbfuncs pkgname

		if {$name in $dotfuncs} {
			initdotfunc $name
			set file $pkgname.install
		} elseif {$name in $pbfuncs} {
			initfunc PKGBUILD $name
			set file PKGBUILD
		} else {
			puts stderr "$prog: error: $name is not a known func"
			exit 2
		}

		set code [trimbash $code]
		exec putpkgtree $file $name $section << $code
	}

	proc fappend {name code} {
		fput $name $code body
	}

	proc fprepend {name code} {
		fput $name $code beg
	}

	proc move {srcname destname args} {
		upvar #0 $srcname src $destname dest
		foreach pat $args {
			set idx [lsearch -glob $src "$pat*"]
			if {$idx == -1} { error "$pat was not found in $srcname" }
			lappend $dest [lindex $src $idx]
			set src [lreplace $src $idx $idx]
		}
	}

	proc splitdep {dep} {
		set re {(?x) ^ ([^<>=]+) ([<>]=?.+)? $}
		if {[regexp $re $dep -> name cmp]} {
			return [list $name $cmp]
		} else {
			error "Invalid dependency string: $dep"
		}
	}

	proc setdep {type newdep} {
		if {! [string match *depends $type]} {
			error "setdep can only be used with depends fields"
		}
		upvar #0 $type deps
		if {! [info exists deps]} {
			error "Unknown dependency field: $type"
		}

		lassign [splitdep $newdep] depname newcmp
		for {set i 0} {$i < [llength $deps]} {incr i} {
			set dep [lindex $deps $i]
			lassign [splitdep $dep] name cmp
			if {$name eq $depname} {
				set deps [lreplace $deps $i $i $name$newcmp]
				return
			}
		}

		error "$name was not found in $type"
	}
}

$modi eval [read $modch]

foreach name $pbfields {
	if {[$modi eval info exists $name]} {
		set pkgdata($name) [$modi eval set $name]
	}
}

printfields stdout