nix-configs

Personal NixOS and home-manager configuration files
Log | Files | Refs

stagit-generate.nix (5316B)


      1 { pkgs, vars, ... }:
      2 
      3 let
      4   css = ''
      5     body,pre{font-family:monospace}
      6     #blob,article img{max-width:100%}
      7     html{font-size:12px;height:100%}
      8     body{margin:5rem auto;color:#aaa;background-color:#272727;width:66rem}
      9     pre{-moz-tab-size:4;tab-size:4}
     10     h1,h2,h3,h4,h5,h6{font-size:1em;margin:0}
     11     h1,h2,img{vertical-align:middle}
     12     img{border:0}
     13     a,a.d,a.h,a.i,a.line{color:#3498db;text-decoration:none}
     14     #blob{display:block;overflow-x:scroll}
     15     article.markup{font-size:15px;border:2px solid #00000017;border-radius:10px;font-family:sans-serif;padding:2.5em;margin:2em 0}
     16     article.markup code{font-size:.9em;border:1px solid #dbdbdb;background-color:#f7f7f7;padding:0 .3em;border-radius:.3em}
     17     article.markup pre code{border:none;background:0 0;padding:0;border-radius:0}
     18     article.markup pre{background-color:#f7f7f7;padding:1em;border:1px solid #dbdbdb;border-radius:.3em}
     19     article.markup h1{font-size:2.4em;padding-bottom:6px;border-bottom:5px solid #0000000a}
     20     article.markup h2{font-size:1.9em;padding-bottom:5px;border-bottom:2px solid #00000014}
     21     article.markup h3{font-size:1.5em}
     22     article.markup h4{font-size:1.3em}
     23     article.markup h5{font-size:1.1em}
     24     article.markup h6{font-size:1em}
     25     .linenos{margin-right:0;border-right:1px solid;user-select:none}
     26     .linenos a{margin-right:.9em;user-select:none;text-decoration:none}
     27     #blob a,.desc{color:#777}
     28     table thead td{font-weight:700}
     29     table td{padding:0 .4em}
     30     #content table td{vertical-align:top;white-space:nowrap}
     31     #branches tr:hover td,#files tr:hover td,#index tr:hover td,#log tr:hover td,#tags tr:hover td{background-color:#414141}
     32     #branches tr td:nth-child(3),#index tr td:nth-child(2),#log tr td:nth-child(2),#tags tr td:nth-child(3){white-space:normal}
     33     td.num{text-align:right}
     34     hr{border:0;border-top:1px solid #777;height:1px}
     35     .A,pre a.i,span.i{color:#29b74e}
     36     .D,pre a.d,span.d{color:#e42533}
     37     .url td:nth-child(2){padding-top:.2em;padding-bottom:.9em}
     38     .url td:nth-child(2) span{padding:1px 5px;background-color:#eee;border:1px solid #ddd;border-radius:5px}
     39     .url td:nth-child(2) span a{color:#444}
     40   '';
     41   stagit-generate = pkgs.writeShellScriptBin "stagit-generate" ''
     42     # variables
     43     source_directory="$HOME/vault/src"
     44     destination_directory="$HOME/docker/stagit"
     45     state_file="$destination_directory/.stagit-state"
     46 
     47     mkdir -p "$destination_directory"
     48 
     49     # state file
     50     if [ ! -f "$state_file" ]; then
     51       echo "# stagit-generate state file" > "$state_file"
     52       echo "# format: repo_path:last_commit_hash" >> "$state_file"
     53     fi
     54     get_latest_commit() {
     55       local repo_path="$1"
     56       cd "$repo_path" || return 1
     57       git rev-parse HEAD 2>/dev/null || echo "no-commits"
     58     }
     59     get_stored_commit() {
     60       local repo_name="$1"
     61       grep "^$repo_name:" "$state_file" 2>/dev/null | cut -d':' -f2- || echo ""
     62     }
     63     update_stored_commit() {
     64       local repo_name="$1"
     65       local commit_hash="$2"
     66       grep -v "^$repo_name:" "$state_file" > "$state_file.tmp" 2>/dev/null || touch "$state_file.tmp"
     67       echo "$repo_name:$commit_hash" >> "$state_file.tmp"
     68       mv "$state_file.tmp" "$state_file"
     69     }
     70 
     71     updated_repos=0
     72     skipped_repos=0
     73     index_needs_update=false
     74 
     75     # stagit loop
     76     for repo in $(find "$source_directory" -type d -name '.git' | sed 's|/\.git$||'); do
     77       repo_name=$(basename "$repo")
     78       output_directory="$destination_directory/$repo_name"
     79       current_commit=$(get_latest_commit "$repo")
     80       stored_commit=$(get_stored_commit "$repo_name")
     81 
     82       # repo update check
     83       if [ "$current_commit" != "$stored_commit" ] || [ ! -d "$output_directory" ]; then
     84         echo "Updating $repo_name... (was: $stored_commit, now: $current_commit)"
     85 
     86         mkdir -p "$output_directory"
     87         cd "$output_directory" || exit
     88 
     89         ${pkgs.stagit}/bin/stagit "$repo"
     90 
     91         cat > "style.css" <<EOF
     92         ${css}
     93 EOF
     94 
     95         # update state
     96         update_stored_commit "$repo_name" "$current_commit"
     97         updated_repos=$((updated_repos + 1))
     98         index_needs_update=true
     99       else
    100         echo "Skipping $repo_name (no changes since $stored_commit)"
    101         skipped_repos=$((skipped_repos + 1))
    102       fi
    103     done
    104 
    105     # re-generate index repositories were updated
    106     if [ "$index_needs_update" = true ]; then
    107       echo "Regenerating index..."
    108       cd "$destination_directory" || exit
    109       ${pkgs.stagit}/bin/stagit-index "''${source_directory}/"*/ >index.html
    110       cat > "style.css" <<EOF
    111       ${css}
    112 EOF
    113     else
    114       echo "Index unchanged, skipping re-generation"
    115     fi
    116 
    117     echo "Summary: Updated $updated_repos repositories, skipped $skipped_repos repositories"
    118     '';
    119 in {
    120   environment.systemPackages = [ stagit-generate ];
    121 
    122   systemd.services.stagit-generate = {
    123     description = "Regenerate stagit static pages";
    124     serviceConfig = {
    125       Type = "oneshot";
    126       User = vars.user.username;
    127       ExecStart = "${stagit-generate}/bin/stagit-generate";
    128       Environment = "PATH=/run/current-system/sw/bin:/run/wrappers/bin";
    129     };
    130   };
    131 
    132   systemd.timers.stagit-generate = {
    133     description = "Run stagit-generate every 10 minutes";
    134     wantedBy = [ "timers.target" ];
    135     timerConfig = {
    136       OnCalendar = "*:0/10";
    137       Persistent = true;
    138     };
    139   };
    140 }