MkBugs is a simple bug manager that uses [tclhttpd] and [metakit]. Design somewhat inspired by Jitterbug. Just place the following script in your custom directory (of tclhttpd) See the last line to init database Test tracker at http://www.onemoonscientific.com/mkbugs/testdb If you attempt to reassign a bug to a different category in the test tracker it will ask for a user name and password: Use test and test Note: this is the very first version of this software, bugs in MkBugs are likely. -- [BAJ] 2 Dec 2004 -- [BAJ] 3 Dec 2004 -- updated with new access control scheme and fixed regexp check for invalid characters --[BAJ] 5 Dec 2004 -- fixed bug in switching category for summary display [JM] I am using windows, to play a little bit with this, I used: ::mkbugs::initDatabase testdb /testbugs.db and the database was created at c:\ [MkBugs Docs for Users] package require Mk4tcl package require ncgi Url_PrefixInstall /mkbugs [list MkBugsDomain /mkbugs] proc MkBugsDomain {prefix sock suffix} { upvar #0 Httpd$sock data if {![regexp {^[0-9a-zA-Z/_*]+$} $suffix]} { Httpd_ReturnData $sock text/plain "Invalid characters in url suffix" } set args [split [string trim $suffix /] /] if {[llength $args] == 0} { Httpd_ReturnData $sock text/plain "Must specifiy a database in url" return } set db [lindex $args 0] if {![::mkbugs::checkAccess $sock $db access]} { return } if {[llength $args] == 1} { Httpd_ReturnData $sock text/html [::mkbugs::wrapBody MkBugs [::mkbugs::mainBar $db]] return } set cmd [lindex $args 1] if {$cmd eq "submit_report"} { ::ncgi::reset $data(query) set cgilist [::ncgi::nvlist] if {[catch [list ::mkbugs::submitReport $db $cgilist] result]} { Httpd_ReturnData $sock text/html $result } else { Httpd_Redirect [Httpd_SelfUrl /mkbugs/$db/summary/incoming/end] $sock } return } elseif {$cmd eq "report"} { Httpd_ReturnData $sock text/html [::mkbugs::wrapBody "New Bug" [::mkbugs::makeReportPage $db]] return } elseif {$cmd eq "note"} { if {[llength $args] < 3} { Httpd_ReturnData $sock text/plain "No row for note" } else { set index [lindex $args 2] ::ncgi::reset $data(query) set cgilist [::ncgi::nvlist] ::mkbugs::addNote $db $index $cgilist Httpd_ReturnData $sock text/html [::mkbugs::wrapBody "New Bug" [::mkbugs::makeShowPage $db $index]] } return } elseif {$cmd eq "show"} { if {[llength $args] < 3} { Httpd_ReturnData $sock text/plain "No row for show" } else { set first [lindex $args 2] ::ncgi::reset $data(query) set cgilist [ncgi::nvlist] set first [::mkbugs::processShow $sock $args $cgilist] Httpd_ReturnData $sock text/html [::mkbugs::wrapBody "Display Bug" [::mkbugs::makeShowPage $db $first]] } return } elseif {$cmd eq "summary"} { ::ncgi::reset $data(query) set cgilist [ncgi::nvlist] foreach "category first count" [::mkbugs::processSummary $sock $args $cgilist] {} Httpd_ReturnData $sock text/html [::mkbugs::wrapBody Summary [::mkbugs::makeSummaryPage $db $category $first $count]] return } else { Httpd_ReturnData $sock text/plain "Invalid command" return } } namespace eval ::mkbugs { variable BugCategories "incoming bugs bugs_fixed feature_request feature_added low_priority duplicates" variable requiredFields {comments subject} proc initDatabase {dbHandle dbFile} { catch "::mk::file open $dbHandle $dbFile" set properties {id subject comments time category os version submitted_by full_name description {notes note} resolvedin audit priority} set views [::mk::file views $dbHandle] if {[lsearch $views bugs] == -1} { ::mk::view layout $dbHandle.bugs $properties } ::mk::view layout $dbHandle.bugs $properties if {[lsearch $views reportfields] == -1} { ::mk::view layout $dbHandle.reportfields "name var type params values" ::mk::row append $dbHandle.reportfields name subject var subject type textInputRow params {size=60} ::mk::row append $dbHandle.reportfields name "submitted by" var submitted_by type textInputRow params {size=40} ::mk::row append $dbHandle.reportfields name "software version" var version type textInputRow params {size=20} ::mk::row append $dbHandle.reportfields name "operating system" var os type select values { {} {Not Specified} {Linux} {Linux} {Windows} {Windows} {Solaris} {Solaris} {Mac OS X} {MacOSX} } ::mk::row append $dbHandle.reportfields name "priority" var priority type selectPlain values { low medium high extreme } ::mk::row append $dbHandle.reportfields name "comments" var comments type textarea params {rows=10 cols=50} } if {[lsearch $views showfields] == -1} { ::mk::view layout $dbHandle.showfields "name var type params values" ::mk::row append $dbHandle.showfields name subject var subject type textInputRow params {size=60} ::mk::row append $dbHandle.showfields name "submitted by" var submitted_by type textInputRow params {size=40} ::mk::row append $dbHandle.showfields name "time" var time type textInputRow params {size=40} ::mk::row append $dbHandle.showfields name "software version" var version type textInputRow params {size=20} ::mk::row append $dbHandle.showfields name "operating system" var os type select values ::mk::row append $dbHandle.showfields name "priority" var priority type select values ::mk::row append $dbHandle.showfields name "comments" var comments type textarea params {rows=10 cols=50} } ::mk::file commit $dbHandle } proc makeReportPage {db} { append result [mainBar $db] append result " Enter Bug Report