Browse Source

Base, nothing functional

spesk1 3 years ago
parent
commit
331a45688a
7 changed files with 238 additions and 8 deletions
  1. 16 8
      README.md
  2. 135 0
      gen_page.pl
  3. 46 0
      lib/Gsg/ConfigParse.pm
  4. 8 0
      lib/Gsg/Gather.pm
  5. 8 0
      lib/Gsg/Html.pm
  6. 9 0
      lib/Gsg/MdParse.pm
  7. 16 0
      tools/mkproject.sh

+ 16 - 8
README.md

@@ -1,9 +1,12 @@
 # git-site-gen #
 
-Placeholder repo right now as code is not ready to be public.
-Tracking features/TODO's in this README.
+* Tool used to generate a static website from information availble in a git project dir. See: https://spwbk.site/git.
+	* Also provides some tools for managing your git server.
 
-## Features/Plans/TODO ##
+* Inspired by the much better/full-featured https://git.suckless.org.
+* Not sure if this will be widely useful, mostly written for learning purposes.
+
+## Features ##
 
 * Generate top level index with links to all projects - POC DONE
 * Generate project specific index with links to git log/diffs and file content of repo - POC DONE
@@ -11,12 +14,17 @@ Tracking features/TODO's in this README.
 * Line numbers for file browsing
 * README.md markdown renderer/parser / display in project index
 * Figure out way to expose clone/merge/etc interface
+* (Stretch GoaL) HTML based syntax highlighting for files
 
 ## Framework Plans ##
 * gsg -- Perl script to generate the site, uses modules below
-* Shellex.pm -- lib to handle shell calls (can likely split Shellex from simply-git project into it's own repo and maintain it there for both things)
-* GitGather.pm -- module to assemble data structures from git trees that need to be obtained as part of generating the site
-* Html.pm -- probably a bad name, used for writing HTML files and/or editing text in other data structures with html content
-* MdParse.pm -- module for parsing markdown. Likely a fools errand to be writing this myself but I'd like to try
-* GsgConfigParse.pm -- module to parse gsg config, might be overkill to have it's own module
+* Gsg::Gather.pm -- module to assemble data structures from git trees that need to be obtained as part of generating the site
+* Gsg::Html.pm -- probably a bad name, used for writing HTML files and/or editing text in other data structures with html content
+* Gsg::MdParse.pm -- module for parsing markdown. Likely a fools errand to be writing this myself but I'd like to try
+* Gsg::ConfigParse.pm -- module to parse gsg config, might be overkill to have it's own module
     * gsg.config -- Config file that gsg reads to inform behavior (git repos dir, what to include/exclude, etc)
+
+## Deps ##
+* Shellex.pm ( https://spwbk.site/git/projects/perl-shellex.git/index.html )
+* git
+* Log4Perl

+ 135 - 0
gen_page.pl

@@ -0,0 +1,135 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my $top_level_dir = "/var/www/html/git/";
+my $projects_dir = $top_level_dir . "projects/";
+my $index = $top_level_dir . "index.html";
+
+my @ignore_dirs = ( "finance-perl.git/","misc-scripts.git/","git-site-gen.git/" );
+my @git_project_dirs;
+foreach my $dir ( split("\n",`ls -d */`) ) {
+	chomp $dir;
+	if ( grep( /^$dir$/, @ignore_dirs ) ) {
+		print "Skipping $dir\n";
+		next;
+	}
+	if ( $dir =~ /.git\/$/ ) {
+		push(@git_project_dirs,$dir);
+	}
+}
+
+my $write = sub {
+	my $content = shift;
+	my $path = shift;
+	open(my $fh, ">", $path) or die "Couldnt open $path\n";
+	print $fh "$content";
+	close $fh;
+};
+
+my $append = sub {
+	my $content = shift;
+	my $path = shift;
+	open(my $fh, ">>", $path) or die "Couldnt open $path\n";
+	print $fh "$content";
+	close $fh;
+};
+
+$write->("",$index);
+foreach my $dir ( split("\n", `cd $projects_dir ; ls -d */; cd /home/git`) ) {
+	if ( ! grep( /^$dir$/, @git_project_dirs ) ) {
+		print "Found $dir in webroot but not in git root, removing...\n";
+		my $rmdir = $projects_dir . $dir;
+		print "Removing $rmdir\n";
+		system("rm -rf $rmdir") == 0 or die "Couldnt rm $dir\n";
+	}
+}
+
+# Write index
+$append->("<html><body><b>Git Projects</b><br><head><META NAME=\"ROBOTS\" CONTENT=\"NOINDEX, NOFOLLOW\"></head>\n",$index);
+$append->("<small><i>Statically generated web root for browsing my git projects</i></small><br>",$index);
+$append->("<small><i>This is a read-only site and does not provide a merge/clone interface</i></small><hr/>",$index);
+foreach my $project ( @git_project_dirs ) {
+	$append->("<table><div id=\"cotent\"><table id=\"index\"><tbody>",$index);
+	$append->("<tr><td><a href=\"projects/$project/index.html\">$project</a></td>",$index);
+	#$append->("<a href=\"projects/$project/index.html\">$project</a><br>",$index);
+	system("mkdir -p $projects_dir$project") == 0 or die "Couldnt create $projects_dir/$project";
+}
+$append->("</tr></tbody></table></div></body></html>",$index);
+
+# Write files
+foreach my $project ( @git_project_dirs ) {
+	my $spec_project_dir = $projects_dir . $project . "/";
+	my $project_index = $spec_project_dir . "/index.html";
+	$write->("",$project_index);
+	$append->("<html><a href=\"../../../index.html\">Return to index</a></b><hr/>",$project_index);
+	$append->("<b>Files for $project</b><br>",$project_index);
+	$append->("<hr/>",$project_index);
+	my %fileTree;
+	foreach my $file ( split("\n", `cd $project ; git ls-tree --full-tree -r HEAD; cd ..`) ) {
+		chomp $file;
+		$file =~ /([a-z0-9]{40})\t(.*)$/;
+		# Name - commit hash
+		$fileTree{$2} = $1;
+	}
+
+	my %fileContent;
+	foreach my $filename ( keys %fileTree ) {
+		my $content = `cd $project ; git show $fileTree{$filename} ; cd ..`;
+		chomp $content;
+		$fileContent{$filename} = $content;
+	}
+
+	$append->("<table><div id=\"cotent\"><table id=\"index\"><thead><tr><td><b>File</b></td><td><b>Commit</b></td></tr></thead><tbody>",$project_index);
+	foreach my $filename ( sort keys %fileContent ) {
+		my $browserVersion = $filename . ".txt";
+		if ( $filename =~ m/\// ) {
+			my $copy = $filename;
+			$copy =~ s/\//_/g;
+			$browserVersion = $copy . ".txt";
+		}
+		#$append->("$fileTree{$filename} - <a href=\"$browserVersion\">$filename</a><br>",$project_index);
+		$append->("<tr><td><a href=\"$browserVersion\">$filename</a></td><td>$fileTree{$filename}</td>",$project_index);
+		$write->("$fileContent{$filename}",$spec_project_dir . $browserVersion);
+	}
+
+	$append->("</tr></tbody></table></div></body>",$project_index);
+	$append->("<br>", $project_index);
+
+}
+
+# Get logs hash and write out logs page
+foreach my $project ( @git_project_dirs ) {
+	my $spec_project_dir = $projects_dir . $project . "/";
+	my $project_index = $spec_project_dir . "/index.html";
+	my @commit_ids;
+	foreach my $log_line ( split("\n",`cd $project; git log ; cd ..`) ) {
+		if ( $log_line =~ m/commit\ ([a-z0-9]{40})/ ) {
+			push(@commit_ids,$1);
+		}
+	}
+
+	# Key: commit SHA, value commit info (git show)
+	my %commits;
+	foreach my $commit_id ( @commit_ids ) {
+		my $commit_info = `cd $project; git show $commit_id; cd ..`;
+		chomp $commit_info;
+		$commits{$commit_id} = $commit_info;
+	}
+
+	$append->("<html><b>Logs for $project</b><br>",$project_index);
+	$append->("<table><div id=\"cotent\"><table id=\"index\"><tbody>",$project_index);
+	$append->("<hr/>",$project_index);
+	# iterate over array to keep ordering
+	foreach my $commit_id ( @commit_ids ) {
+		my $filename = $commit_id . ".txt";
+		#$append->("<a href=\"$filename\">$commit_id</a><br>",$project_index);
+		$append->("<tr><td><a href=\"$filename\">$filename</a></td>",$project_index);
+		$write->($commits{$commit_id},$spec_project_dir . $filename);	
+	}
+	$append->("</tr></tbody></table></div></body>",$project_index);
+	$append->("</html>",$project_index);
+}
+
+print "Done\n";

+ 46 - 0
lib/Gsg/ConfigParse.pm

@@ -0,0 +1,46 @@
+package Gsg::ConfigParse;
+use strict;
+use warnings;
+use Log::Log4perl qw(:easy);
+use lib "/usr/local/lib";
+use Shellex::Shellex qw(shellex findBin);
+use Exporter qw(import);
+our @EXPORT_OK = qw();
+
+# https://perlmaven.com/trim
+sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
+
+sub parseGsgConfig($$) {
+
+	my $configPath = shift;
+	my $logger = shift;
+	if ( ! -e $config ) {
+		$logger->error("$config doesn't look like a regular file, exiting...");
+		exit 1;
+	}
+	my $catCmd = findBin("cat",$logger);
+	my @configLines = split("\n",shellex("$catCmd $config",$logger));
+	my %configHash;
+	foreach my $line ( @configLines ) {
+		chomp $line;
+		if ( $line =~ m/^(.*)\ =\ "(.*)"$/ ) {
+			$configHash{$1} = $2;
+		}
+
+		if ( $line =~ m/^(.*)\ =\ \[(.*)\]/ ) {
+			my @trimmedPorts;
+			my @ports = split(",",$2);
+			foreach my $port (@ports) {
+				$port =~ /(\d{1,5})/;
+				push(@trimmedPorts,trim($1));
+			}
+			$configHash{$1} = \@trimmedPorts;
+		}
+	}
+
+	return %configHash;
+
+}
+
+1;
+

+ 8 - 0
lib/Gsg/Gather.pm

@@ -0,0 +1,8 @@
+package Gsg::Gather;
+use strict;
+use warnings;
+use Log::Log4perl qw(:easy);
+use Exporter qw(import);
+our @EXPORT_OK = qw();
+
+1;

+ 8 - 0
lib/Gsg/Html.pm

@@ -0,0 +1,8 @@
+package Gsg::Html;
+use strict;
+use warnings;
+use Log::Log4perl qw(:easy);
+use Exporter qw(import);
+our @EXPORT_OK = qw();
+
+1;

+ 9 - 0
lib/Gsg/MdParse.pm

@@ -0,0 +1,9 @@
+package Gsg::MdParse;
+use strict;
+use warnings;
+use Log::Log4perl qw(:easy);
+use Exporter qw(import);
+our @EXPORT_OK = qw();
+
+1;
+

+ 16 - 0
tools/mkproject.sh

@@ -0,0 +1,16 @@
+#!/bin/bash
+
+NAME=$1;
+if [ "$NAME" == "" ]; then
+	echo "Need to pass a project name"
+	exit 1
+fi
+TLD=$PWD
+GIT_HOME="/home/git/"
+PROJECT_SUFFIX=".git"
+PROJECT_DIR="$GIT_HOME/$NAME$PROJECT_SUFFIX"
+
+mkdir $PROJECT_DIR || echo "Couldn't mkdir $PROJECT_DIR"
+cd $PROJECT_DIR || echo "Couldn't cd to $PROJECT_DIR"
+$(which git) init --bare || echo "Couldn't init git in $PROJECT_DIR"
+cd $TLD || echo "Couldnt cd back up to $TLD"