new website
This commit is contained in:
parent
17e6bd38e3
commit
464f925c5c
10 changed files with 670 additions and 460 deletions
|
|
@ -1,160 +0,0 @@
|
|||
* {
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 100%;
|
||||
line-height: 1;
|
||||
font-family: Roboto, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #222222;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #222222;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #333333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div#container {
|
||||
width: 90ch;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 2.5rem;
|
||||
font-family: Iosevka, monospace;
|
||||
}
|
||||
|
||||
nav {
|
||||
font-family: Iosevka, monospace;
|
||||
font-size: 1.2rem;
|
||||
background-color: #e3e3e3;
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul li {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul li:not(:first-child) {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
nav a {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
main {
|
||||
line-height: 1.25;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
main a:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
main h1 {
|
||||
padding: 0;
|
||||
border-bottom: 1px dashed #333;
|
||||
font-family: Mina, Iosevka, monospace;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
main h2 {
|
||||
padding: 0;
|
||||
font-family: Mina, Iosevka, monospace;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
dl {
|
||||
padding: 1rem;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
|
||||
dl dt {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
dl dt:not(:first-child) {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
dl dd {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 1rem;
|
||||
border-top: 1px solid #cccccc;
|
||||
padding-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
table, tr, td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
dl.project-list {
|
||||
width: 100%;
|
||||
font-size: 1rem;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
dl.project-list dt {
|
||||
width: 100%;
|
||||
margin-top: 1rem;
|
||||
padding: 0.5rem;
|
||||
display: block;
|
||||
background-color: #f0f0f0;
|
||||
border-top: 1px solid #999;
|
||||
border-left: 1px solid #999;
|
||||
border-right: 1px solid #999;
|
||||
font-family: Iosevka, monospace;
|
||||
}
|
||||
|
||||
dl.project-list dd {
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
border-bottom: 1px solid #999;
|
||||
border-left: 1px solid #999;
|
||||
border-right: 1px solid #999;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: Iosevka, monospace;
|
||||
font-size: 1rem;
|
||||
color: #000;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
|
@ -1,55 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Garrity Software - Contact</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="Garrity Software - Contact" />
|
||||
<link rel="stylesheet" type="text/css" href="assets/gs.css">
|
||||
</head>
|
||||
<body>
|
||||
<head>
|
||||
<title>Garrity Software - Contact</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="garrity software contact information" />
|
||||
<link rel="stylesheet" type="text/css" href="gs.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<header><a href="https://garrity.co">λ garrity software</a></header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="index.html">about</a></li>
|
||||
<li><a href="open-source.html">open source</a></li>
|
||||
<li><a href="writing.html">writing</a></li>
|
||||
<li><a href="contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<h1>Email</h1>
|
||||
<p><code>pfm@garrity.co</code></p>
|
||||
</section>
|
||||
|
||||
<div id="container">
|
||||
<section>
|
||||
<h1>Social Media</h1>
|
||||
<p>I do not use any social media platforms.</p>
|
||||
</section>
|
||||
|
||||
<!-- Header/Logo -------------------------------------------------------------->
|
||||
<header>
|
||||
<h1>garrity software</h1>
|
||||
</header>
|
||||
<section>
|
||||
<h1>Chat</h1>
|
||||
<p>Email me for an invitation to the garrity-software
|
||||
<a class="external" href="https://zulip.com/">Zulip</a> organization.
|
||||
Zulip provides web and desktop clients.</p>
|
||||
</section>
|
||||
|
||||
<!-- Navigation --------------------------------------------------------------->
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="index.html">about</a></li>
|
||||
<li><a href="oss.html">open source</a></li>
|
||||
<li><a href="donate.html">donate</a></li>
|
||||
<li><a href="contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content ------------------------------------------------------------->
|
||||
<main>
|
||||
|
||||
<section id="contact">
|
||||
<h1>Contact</h1>
|
||||
<h2>Community Discord</h2>
|
||||
<p><a href="https://discord.gg/nphkquBhw3">The Garrity Software Discord Community</a>
|
||||
is intended to be a place to discuss and ask questions about open source
|
||||
software, as well as discuss GS or software development in general. This Discord
|
||||
server should not be used for product support.</p>
|
||||
<p>This is also a viable option for getting in touch with Pat directly.</p>
|
||||
|
||||
<h2>Email</h2>
|
||||
<p>pfm@garrity.co is an appropriate email address for reaching out to Pat
|
||||
directly.</p>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer ------------------------------------------------------------------->
|
||||
<footer>
|
||||
Content Copyright © Patrick Garrity
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<section>
|
||||
<h1>Git</h1>
|
||||
<p>All source repositories are currently hosted under
|
||||
<a class="external" href="https://git.garrity.co">git.garrity.co</a>
|
||||
(my self-hosted <a class="external" href="https://forgejo.org/">Forgejo</a> instance),
|
||||
though I may mirror open source repositories on
|
||||
<a class="external" href="https://codeberg.org/">codeberg</a>.</p>
|
||||
</section>
|
||||
</main>
|
||||
<footer>Copyright <span class="focus">pfm</span></footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Garrity Software - Donate</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="Garrity Software - Donate" />
|
||||
<link rel="stylesheet" type="text/css" href="assets/gs.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<!-- Header/Logo -------------------------------------------------------------->
|
||||
<header>
|
||||
<h1>garrity software</h1>
|
||||
</header>
|
||||
|
||||
<!-- Navigation --------------------------------------------------------------->
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="index.html">about</a></li>
|
||||
<li><a href="oss.html">open source</a></li>
|
||||
<li><a href="donate.html">donate</a></li>
|
||||
<li><a href="contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content ------------------------------------------------------------->
|
||||
<main>
|
||||
|
||||
<section id="donate">
|
||||
<h1>Donate</h1>
|
||||
<p>Garrity Software is a fledgling organization that produces open source
|
||||
libraries and intends to eventually sell software. If you like the open source
|
||||
work, or you want to support Pat in one day going independent:</p>
|
||||
<p><strong><a href="https://ko-fi.com/gspfm">Donate to Pat on Ko-fi</a></strong></p>
|
||||
|
||||
<h2>What do my donations do?</h2>
|
||||
<p>Donations help to cover the costs of anything related to open source
|
||||
development (servers, subscriptions, etc.) or community development. Donations
|
||||
also serve as a general source of encouragement, and help move the needle
|
||||
towards independence.</p>
|
||||
|
||||
<p>Donations are not (and will not be) used for any paid product hosting or
|
||||
other payment-related services.</p>
|
||||
</section>
|
||||
|
||||
<section id="sponsor">
|
||||
<h1>Sponsorship</h1>
|
||||
<p>If, for some reason, your company wants to <em>sponsor</em> Garrity Software,
|
||||
please <a href="contact.html">contact Pat directly</a>.</p>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer ------------------------------------------------------------------->
|
||||
<footer>
|
||||
Content Copyright © Patrick Garrity
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
220
src/gs.css
Normal file
220
src/gs.css
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
* {
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
body {
|
||||
line-height: 1.2;
|
||||
font-family: "Libre Baskerville", serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: #f0f0f0;
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
div#wrapper {
|
||||
margin-top: 1rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 90ch;
|
||||
}
|
||||
|
||||
header {
|
||||
font-size: 1.15rem;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header a {
|
||||
color: #000000;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
header a:visited {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
header a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
nav {
|
||||
font-size: 1.25rem;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
width: 100%;
|
||||
background-color: #f6f6f6;
|
||||
border: 1px solid #ccc;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul li {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul li:not(:first-child) {
|
||||
margin-left: 0rem;
|
||||
}
|
||||
|
||||
nav a {
|
||||
color: #333333;
|
||||
padding: 0.5rem;
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
nav a:visited {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
main {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
footer {
|
||||
font-size: 1rem;
|
||||
margin-top: 3rem;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
padding-top: 0.5rem;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.6rem;
|
||||
font-family: Lato;
|
||||
padding-bottom: 0.2rem;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.4rem;
|
||||
font-family: Lato;
|
||||
padding-bottom: 0.2rem;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2rem;
|
||||
font-family: Lato;
|
||||
display: block;
|
||||
}
|
||||
|
||||
span.focus {
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
main a {
|
||||
color: #444444;
|
||||
}
|
||||
|
||||
main a:visited {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
main a:hover {
|
||||
color: #777777;
|
||||
}
|
||||
|
||||
main a.internal {
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid #333333;
|
||||
padding-bottom: 0.1rem;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
main a.internal:hover {
|
||||
color: #777777;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
main a.external {
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #333333;
|
||||
padding: 0.1rem;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
main a.external:hover {
|
||||
color: #777777;
|
||||
border-bottom: 1px dotted #cccccc;
|
||||
}
|
||||
|
||||
ul#entry-list {
|
||||
width: 100%;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 1px solid #999999;
|
||||
border-bottom: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
ul#entry-list li {
|
||||
color: #222222;
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #999999;
|
||||
transition: background 0.5s ease;
|
||||
}
|
||||
|
||||
ul#entry-list li:hover {
|
||||
border-bottom: 1px solid #999999;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
ul#entry-list a {
|
||||
display: block;
|
||||
padding: 0.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul#entry-list a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
ul#entry-list li div.tags {
|
||||
margin-left: 1rem;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
small {
|
||||
border-radius: 6px;
|
||||
font-size: 0.8rem;
|
||||
padding: 0.25rem;
|
||||
color: #333333;
|
||||
background-color: #cccccc;
|
||||
border: 1px solid #cccccc;
|
||||
display: inline-block;
|
||||
}
|
||||
108
src/index.html
108
src/index.html
|
|
@ -1,53 +1,75 @@
|
|||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Garrity Software - About</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="Garrity Software Homepage" />
|
||||
<link rel="stylesheet" type="text/css" href="assets/gs.css">
|
||||
</head>
|
||||
<body>
|
||||
<head>
|
||||
<title>Garrity Software</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="garrity software homepage" />
|
||||
<link rel="stylesheet" type="text/css" href="gs.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<header><a href="https://garrity.co">λ garrity software</a></header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="index.html">about</a></li>
|
||||
<li><a href="open-source.html">open source</a></li>
|
||||
<li><a href="writing.html">writing</a></li>
|
||||
<li><a href="contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<p><em>garrity software</em> (<span class="focus">gs</span>) is my software organization.
|
||||
It is currently focused on open source projects and writing. It is
|
||||
intended to one day develop software products.</p>
|
||||
</section>
|
||||
|
||||
<div id="container">
|
||||
<section>
|
||||
<h1>Who Am I?</h1>
|
||||
<p><span class="focus">pfm</span> [Pat] — Presumably human;
|
||||
programming enthusiast and professional.</p>
|
||||
</section>
|
||||
|
||||
<!-- Header/Logo -------------------------------------------------------------->
|
||||
<header>
|
||||
<h1>garrity software</h1>
|
||||
</header>
|
||||
<section>
|
||||
<h1>What I Do</h1>
|
||||
<p><span class="focus">gs</span> produces libraries and
|
||||
applications that support things I enjoy working on, such as
|
||||
note taking, developer tooling, and software development;
|
||||
I create libraries intended to be used in general settings.</p>
|
||||
|
||||
<!-- Navigation --------------------------------------------------------------->
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="index.html">about</a></li>
|
||||
<li><a href="oss.html">open source</a></li>
|
||||
<li><a href="donate.html">donate</a></li>
|
||||
<li><a href="contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<p>For a list of <span class="focus">gs</span> projects,
|
||||
please refer to <a class="internal" href="open-source.html">open source</a>.</p>
|
||||
|
||||
<!-- Main Content ------------------------------------------------------------->
|
||||
<main>
|
||||
<section id="short-description">
|
||||
<p><em>Garrity Software</em> (GS) is an organization devoted to producing high
|
||||
quality, robust software. GS is also committed to producing as much free and
|
||||
open source content as possible.</p>
|
||||
<p>At this point in time, GS is not in a position to release commerical
|
||||
software. Product development may occur in the future.</p>
|
||||
</section>
|
||||
<p>I also <a class="internal" href="writing.html">write</a> about software from time to time.</p>
|
||||
|
||||
<section id="team">
|
||||
<h1>Team</h1>
|
||||
<h2>Pat Garrity (pfm)</h2>
|
||||
<p>Founder and visionary of Garrity Software.</p>
|
||||
</section>
|
||||
</main>
|
||||
<h2>Languages & Ecosystems</h2>
|
||||
<p>I primarily work in
|
||||
<a class="external" href="https://scala-lang.org/">Scala 3</a>,
|
||||
leveraging the <a class="external" href="https://typelevel.org/cats/">Cats</a> ecosystem.</p>
|
||||
|
||||
<!-- Footer ------------------------------------------------------------------->
|
||||
<footer>
|
||||
Content Copyright © Patrick Garrity
|
||||
</footer>
|
||||
<h2>My Development Approach</h2>
|
||||
<p>I strive to write <em>robust</em> code that meets its goals and stands the test of time.
|
||||
I enjoy rapid iteration backed by thought and preparation. I work best when I'm having fun,
|
||||
and work best when I'm working on an interesting problem.</p>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
<section>
|
||||
<h1>My Goals</h1>
|
||||
<p>One day I hope to commit entirely to <span class="focus">gs</span>, producing software
|
||||
and documentation that I find useful, releasing as much as possible for free. My minimum
|
||||
runway to this end appears to be 2030 - I expect it to be further in the future, and the
|
||||
ultimate timeline depends on my family and what I can scrape together at night. In the
|
||||
meantime, my goal is to keep coding in my free time and preserve my love for my craft.</p>
|
||||
|
||||
</body>
|
||||
<p>If you want to support my goals, discuss software with me in my <a href="contact.html">Zulip organization</a> or
|
||||
<a class="external" href="https://ko-fi.com/gspfm">donate</a> if you find my contributions useful and are
|
||||
in a position to do so.</p>
|
||||
</section>
|
||||
</main>
|
||||
<footer>Copyright <span class="focus">pfm</span></footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
64
src/open-source.html
Normal file
64
src/open-source.html
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Garrity Software - Open Source</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="garrity software open source" />
|
||||
<link rel="stylesheet" type="text/css" href="gs.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<header><a href="https://garrity.co">λ garrity software</a></header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="index.html">about</a></li>
|
||||
<li><a href="open-source.html">open source</a></li>
|
||||
<li><a href="writing.html">writing</a></li>
|
||||
<li><a href="contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<ul id="entry-list">
|
||||
<li>
|
||||
<a href="https://git.garrity.co/garrity-software/gs-uuid">gs-uuid</a>
|
||||
<div class="tags">
|
||||
<small>2025-07-23</small>
|
||||
<small>scala</small>
|
||||
<small>library</small>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://git.garrity.co/garrity-software/gs-timing">gs-timing</a>
|
||||
<div class="tags">
|
||||
<small>2025-07-23</small>
|
||||
<small>scala</small>
|
||||
<small>library</small>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://git.garrity.co/garrity-software/gs-datagen">gs-datagen</a>
|
||||
<div class="tags">
|
||||
<small>2025-07-23</small>
|
||||
<small>scala</small>
|
||||
<small>library</small>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://git.garrity.co/garrity-software/gs-config">gs-config</a>
|
||||
<div class="tags">
|
||||
<small>2025-07-23</small>
|
||||
<small>scala</small>
|
||||
<small>library</small>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
<footer>Copyright <span class="focus">pfm</span></footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
143
src/oss.html
143
src/oss.html
|
|
@ -1,143 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Garrity Software - Open Source</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="Garrity Software - Open Source" />
|
||||
<link rel="stylesheet" type="text/css" href="assets/gs.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="container">
|
||||
|
||||
<!-- Header/Logo -------------------------------------------------------------->
|
||||
<header>
|
||||
<h1>garrity software</h1>
|
||||
</header>
|
||||
|
||||
<!-- Navigation --------------------------------------------------------------->
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="index.html">about</a></li>
|
||||
<li><a href="oss.html">open source</a></li>
|
||||
<li><a href="donate.html">donate</a></li>
|
||||
<li><a href="contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content ------------------------------------------------------------->
|
||||
<main>
|
||||
|
||||
<section id="open-source">
|
||||
<h1>Open Source</h1>
|
||||
<p>Garrity Software exposes all non-product software as open source. The MIT
|
||||
License is standard for GS projects.</p>
|
||||
|
||||
<p>If you have questions or want to discuss these projects, consider joining the
|
||||
<a href="https://discord.gg/nphkquBhw3">Garrity Software Discord Community</a>.</p>
|
||||
</section>
|
||||
|
||||
<section id="vcs">
|
||||
<h2>Version Control (Git)</h2>
|
||||
<p>GS uses self-hosted version control at
|
||||
<a href="https://git.garrity.co/garrity-software">https://git.garrity.co/garrity-software</a>.
|
||||
All code is available, though registration and contributions are not accepted at
|
||||
this time.</p>
|
||||
|
||||
<h3>Mirrors</h3>
|
||||
<p>GS does not currently mirror repositories.</p>
|
||||
</section>
|
||||
|
||||
<section id="maven">
|
||||
<h2>Maven</h2>
|
||||
<p>GS provides a Maven server and does not upload artifacts to other public
|
||||
Maven/Ivy repositories at this time.</p>
|
||||
<pre><code>resolvers += "garrity-software-gs" at "https://maven.garrity.co/gs"</code></pre>
|
||||
<p>No credentials are required to use this repository.</p>
|
||||
</section>
|
||||
|
||||
<section id="api-docs">
|
||||
<h2>API Documentation</h2>
|
||||
<p>Code documentation is not yet published publicly.</p>
|
||||
</section>
|
||||
|
||||
<section id="projects">
|
||||
<h2>Projects</h2>
|
||||
<dl class="project-list">
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/gs-uuid">gs-uuid</a>
|
||||
(Scala 3) (Library)</dt>
|
||||
<dd>Uses <a href="https://github.com/cowtowncoder/java-uuid-generator/">JUG</a>
|
||||
and ported code from Jackson to provide an opaque <code>UUID</code> type
|
||||
over <code>java.util.UUID</code>, backed by custom rendering and parsing.</dd>
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/gs-slug">gs-slug</a>
|
||||
(Scala 3) (Library)</dt>
|
||||
<dd>Provides a <code>Slug</code> type. This type relies on a very small set of
|
||||
ASCII characters and is intended for URL-safe identifiers.</dd>
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/gs-hex">gs-hex</a>
|
||||
(Scala 3) (Library)</dt>
|
||||
<dd>Small, efficient, Hexadecimal conversion library with encoder/decoder type
|
||||
classes and support for basic types. Based on handling byte arrays.</dd>
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/gs-blob">gs-blob</a>
|
||||
(Scala 3) (Library)</dt>
|
||||
<dd>Opaque type (<code>Blob</code>) and tools (e.g. encoding) for "blobs" -
|
||||
arrays of bytes.</dd>
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/gs-datagen">gs-datagen</a>
|
||||
(Scala 3) (Library)</dt>
|
||||
<dd>Random data generation library for Scala 3. Intended for use in tests, but
|
||||
not limited to that case. Provides a composable type for generators and
|
||||
several standard generators.</dd>
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/gs-config">gs-config</a>
|
||||
(Scala 3) (Library)</dt>
|
||||
<dd>Library for loading, and specifically <em>auditing</em>, configuration.
|
||||
Provides a complete digest of what configuration keys were queried and what
|
||||
happened to them.</dd>
|
||||
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="incubator">
|
||||
<h2>Incubator</h2>
|
||||
<dl class="project-list">
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/gs-test">gs-test</a>
|
||||
(Scala 3) (Library)</dt>
|
||||
<dd>Test framework for Scala 3. Based on Cats Effect. Notably provides
|
||||
structured test output and envisions a more powerful method of expressing
|
||||
test execution.</dd>
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/gs-log">gs-log</a>
|
||||
(Scala 3) (Library)</dt>
|
||||
<dd>FP logging library for Scala 3.</dd>
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/gs-crypto">gs-crypto</a>
|
||||
(Scala 3) (Library)</dt>
|
||||
<dd>Based on JVM standard implementations and Bouncy Castle. Working to define
|
||||
some crypto interfaces for GS projects in a way that works well with
|
||||
Scala.</dd>
|
||||
|
||||
<dt><a href="https://git.garrity.co/garrity-software/smolban">smolban</a>
|
||||
(Scala 3) (Application)</dt>
|
||||
<dd>Fun side-project to create a small/minimal Kanban oriented system. Light on
|
||||
process, helps prove out certain concepts in a non-critical
|
||||
application.</dd>
|
||||
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer ------------------------------------------------------------------->
|
||||
<footer>
|
||||
Content Copyright © Patrick Garrity
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
40
src/writing.html
Normal file
40
src/writing.html
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Garrity Software - Writing</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="garrity software writing" />
|
||||
<link rel="stylesheet" type="text/css" href="gs.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<header><a href="https://garrity.co">λ garrity software</a></header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="index.html">about</a></li>
|
||||
<li><a href="open-source.html">open source</a></li>
|
||||
<li><a href="writing.html">writing</a></li>
|
||||
<li><a href="contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<ul id="entry-list">
|
||||
<li>
|
||||
<a href="writing/semantic-type-refinement.html">Semantic Type Refinement</a>
|
||||
<div class="tags">
|
||||
<small>2025-09-25</small>
|
||||
<small>scala</small>
|
||||
<small>types</small>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
<footer>Copyright <span class="focus">pfm</span></footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
73
src/writing/optimizing-shell-history.html
Normal file
73
src/writing/optimizing-shell-history.html
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Garrity Software - Optimizing Shell History</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="writing - optimizing shell history" />
|
||||
<link rel="stylesheet" type="text/css" href="../gs.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/go.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<header><a href="#">λ garrity software</a></header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="../index.html">about</a></li>
|
||||
<li><a href="../open-source.html">open source</a></li>
|
||||
<li><a href="../writing.html">writing</a></li>
|
||||
<li><a href="../contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<h1>Optimizing Shell History</h1>
|
||||
<p>I've spent a lot of time fiddling with my local development environment over
|
||||
the years. As a result, I've also evolved how I interact with my shell history.</p>
|
||||
<p>I would say that I use my history as a convenience and efficiency booster,
|
||||
though I do not use it to drive workflow to the extent I see from others.</p>
|
||||
<p>I take advantage of three things:</p>
|
||||
<ol>
|
||||
<li>History configuration settings.</li>
|
||||
<li>Shell comments.</li>
|
||||
<li>Fuzzy search (FZF, in this case).</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section>
|
||||
<h2 id="history-configuration">History Configuration</h2>
|
||||
<p>I currently use <code>zsh</code>, so the example below is
|
||||
for <code>zsh</code>.</p>
|
||||
<pre><code class="language-bash">export HISTFILE="$HOME/.zsh_history"
|
||||
export HISTSIZE=25000
|
||||
export SAVEHIST=$HISTSIZE
|
||||
export HISTORY_IGNORE="(ls|cd|pwd|exit)*"
|
||||
|
||||
setopt EXTENDED_HISTORY # Write the history file in the ':start:elapsed;command' format.
|
||||
setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits.
|
||||
setopt SHARE_HISTORY # Share history between all sessions.
|
||||
setopt HIST_IGNORE_DUPS # Do not record an event that was just recorded again.
|
||||
setopt HIST_IGNORE_ALL_DUPS # Delete an old recorded event if a new event is a duplicate.
|
||||
setopt HIST_IGNORE_SPACE # Do not record an event starting with a space.
|
||||
setopt HIST_SAVE_NO_DUPS # Do not write a duplicate event to the history file.
|
||||
setopt HIST_VERIFY # Do not execute immediately upon history expansion.
|
||||
setopt APPEND_HISTORY # append to history file (Default)
|
||||
setopt HIST_NO_STORE # Don't store history commands
|
||||
setopt HIST_REDUCE_BLANKS # Remove superfluous blanks from each command line being added to the history.
|
||||
setopt INTERACTIVE_COMMENTS # Allow comments in interactive shell.
|
||||
|
||||
# Example of what I have - you can use your own configuration. Note that this
|
||||
# example is intended for use on wayland with wl-copy.
|
||||
export FZF_CTRL_R_OPTS="
|
||||
--preview 'echo {}' --preview-window up:3:hidden:wrap
|
||||
--bind 'ctrl-/:toggle-preview'
|
||||
--bind 'ctrl-y:execute-silent(echo -n {2..} | wl-copy)+abort'
|
||||
--color header:italic
|
||||
--header 'Press CTRL-Y to copy command into clipboard'"</code></pre>
|
||||
</section>
|
||||
</main>
|
||||
<footer>Copyright <span class="focus">pfm</span></footer>
|
||||
</div>
|
||||
<script>hljs.highlightAll();</script>
|
||||
</body>
|
||||
</html>
|
||||
160
src/writing/semantic-type-refinement.html
Normal file
160
src/writing/semantic-type-refinement.html
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Semantic Type Refinement (GS)</title>
|
||||
<meta name="author" content="pfm" />
|
||||
<meta name="description" content="semantic type refinement" />
|
||||
<link rel="stylesheet" type="text/css" href="../gs.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/scala.min.js"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<header><a href="https://garrity.co">λ garrity software</a></header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="../index.html">about</a></li>
|
||||
<li><a href="../open-source.html">open source</a></li>
|
||||
<li><a href="../writing.html">writing</a></li>
|
||||
<li><a href="../contact.html">contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<main>
|
||||
<section>
|
||||
<h1>Semantic Type Refinement</h1>
|
||||
<p>Types can be great. In the context of Scala, I like using types heavily.
|
||||
They help me think and write better code more quickly. The notion of <em>refined types</em>
|
||||
is a way to leverage types to enforce certain constraints - often at compile time.</p>
|
||||
<p>Excellent libraries such as
|
||||
<a class="external" href="https://github.com/fthomas/refined">refined</a>
|
||||
have an obvious introductory example:</p>
|
||||
<pre><code class="language-scala">scala> val i2: Int Refined Positive = -5
|
||||
error: Predicate failed: (-5 > 0).</code></pre>
|
||||
<p>To be clear: this is great! I want to talk about another way to refine types
|
||||
without taking away from the standard case.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 id="another-approach-to-refinement">Another Approach to Refinement</h2>
|
||||
|
||||
<p>The basic refinement example essentially makes the type more specific. Another way to look
|
||||
at it is that it removes unwanted values from the range of possible values. Rather than a
|
||||
type that accepts integers, we have a type which only accepts <em>positive</em> integers.</p>
|
||||
|
||||
<p>This is useful, though in many context I prefer to go further. At the end of the day,
|
||||
with this example, I just have a positive integer. What is the purpose of that integer?
|
||||
Adding specific semantics to a type can make it <em>stronger</em> and <em>more meaningful</em>.</p>
|
||||
|
||||
<p>Let's pretend that our positive integer is actually intended to express some configurable
|
||||
maximum concurrency value (please bear with the exception for now):</p>
|
||||
|
||||
<pre><code class="language-scala">opaque type MaximumConcurrency = Int
|
||||
|
||||
object MaximumConcurrency:
|
||||
|
||||
def apply(candidate: Int): MaximumConcurrency =
|
||||
if candidate <= 0 then
|
||||
throw new IllegalArgumentException(
|
||||
"Maximum concurrency must be 1 or greater."
|
||||
)
|
||||
else candidate
|
||||
|
||||
given CanEqual[MaximumConcurrency, MaximumConcurrency] = CanEqual.derived
|
||||
|
||||
extension (mc: MaximumConcurrency) def toInt(): Int = mc
|
||||
|
||||
end MaximumConcurrency</code></pre>
|
||||
|
||||
<p>While this involves slightly more typing, it has several benefits:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>MaximumConcurrency</code> obviously describes the purpose of the type.</li>
|
||||
<li>The type can be independently documented.</li>
|
||||
<li>Some value of this type can only be equated to other <code>MaximumConcurrency</code> values.</li>
|
||||
<li>Logic and functions can be contextualized to this type.</li>
|
||||
<li>Values of this type cannot exist unless they meet validation criteria.</li>
|
||||
<li>Zero dependencies.</li>
|
||||
</ul>
|
||||
|
||||
<p>Lest we forget the drawbacks:</p>
|
||||
|
||||
<ul>
|
||||
<li>Value validation does not occur at compile time.</li>
|
||||
<li>Implementation is manual.</li>
|
||||
</ul>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 id="addressing-drawbacks">Addressing Drawbacks</h2>
|
||||
|
||||
<p>First off: many values are <em>not</em> known at compile time. Refinement libraries
|
||||
are not unaware of this, and provide tools for refining at runtime.</p>
|
||||
|
||||
<p>Manual implementation simply does not bother me -- it is a small effort, and that
|
||||
effort <em>forces</em> me to think about each type and document each type. I am also forced
|
||||
to <em>justify</em> a <em>purpose</em> for each type. I spend more time thinking, and less
|
||||
time actually writing; a common theme with specific types.</p>
|
||||
|
||||
<p>That being said, this approach isn't for everything. Sometimes there are literals that
|
||||
just need to be non-semantic, because trying to apply that layer has no value. That's okay,
|
||||
and lines need to be drawn.</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 id="what-about-exceptions">What About Exceptions?</h2>
|
||||
|
||||
<p>There is no reason a type <em>must</em> rely on exceptions to perform validation:</p>
|
||||
|
||||
<pre><code class="language-scala">opaque type MaximumConcurrency = Int
|
||||
|
||||
object MaximumConcurrency:
|
||||
|
||||
def validate(candidate: Int): Either[MyError, MaximumConcurrency] =
|
||||
if candidate <= 0 then Left(MyError.InvalidMaximumConcurrency(candidate))
|
||||
else candidate</code></pre>
|
||||
|
||||
<p>Refinement of the type can be catered to the case at hand. Use whatever mechanism
|
||||
best fits the type.</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 id="types-without-validation">Types Without Validation</h2>
|
||||
|
||||
<p>This same approach can be used to give type restrictions to unconstrained values:</p>
|
||||
|
||||
<pre><code class="language-scala">opaque type MaximumConcurrency = Int
|
||||
|
||||
object MaximumConcurrency:
|
||||
|
||||
def apply(value: Int): MaximumConcurrency = value</code></pre>
|
||||
|
||||
<p>Opaque type aliases are a technique that I use often, as these types still
|
||||
prevent the use of mismatched types and communicate valuable information.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 id="summary">Summary</h2>
|
||||
|
||||
<p>Restrictions are often power, and clarity is also often power. I enjoy both,
|
||||
and make heavy use of them in my code. In general, I tend to rely on a dependency-free
|
||||
manual approach to refining my types in a way that forces me to justify the existence
|
||||
of every single type - I think the approach is at least worth consideration. I think
|
||||
that libraries which solve a general case well are valuable in their own right and hope
|
||||
that this brief writeup is not taken as a reason to avoid them.</p>
|
||||
|
||||
<p>I particularly like the inclusion of <code>opaque</code> types in Scala 3 and use
|
||||
them heavily in lieu of fundamental types.</p>
|
||||
</section>
|
||||
</main>
|
||||
<footer>Copyright <span class="focus">pfm</span></footer>
|
||||
</div>
|
||||
<script>hljs.highlightAll();</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Reference in a new issue