# Create New Golang Projects

Continuing our desire to be lazy efficient and automate common tasks, this is about a little helper for any new golang projects we create.

Continuing our desire to be lazy efficient and automate common tasks, this is about a little helper for any new golang projects we create.

## The Explanation

I started learning, and using, golang in late-2020. As my familiarity increased I realised I was repeating the same boring steps each time I created a new repository. Being who I am, I couldn’t keep repeating myself, so I wrote a script to repeat myself for me.

Because I wrote the script for myself it does make some assumptions, some of which you can override, some of which you’re stuck with unless you modify the script.

Assuming everything succeeds, the script will check to see if you have code (the wrapper script that launches VSCode) and open the new repository for you automatically.

## The Script

Save this into your path (e.g. ~/bin).

# file: "new-golang-project"
#!/bin/bash
set -euo pipefail

# grab $1 as the "original module name" origname="${1:?missing reponame}"

# start with reponame as the origname, then prefix with go- if we don't have it
reponame="${origname}" [[$reponame =~ ^go- ]] || reponame="go-${reponame}" # and trimname, get the reponame without the go-prefix; useful for packages trimname="${reponame/go-/}"
# also, we don't want dashes!
trimname="${trimname//-/}" # set a couple of things we may wish to make more configurable down the line: ## a github username (default: chiselwright) githubUsername="${GITHUB_USERNAME:-chiselwright}"

## the module name prefix (default: github.com/${githubuserName}) gomodPrefix="${NEWGO_MODPREFIX:-github.com/${githubUsername}/}" ## cloneRoot is the base for "development" checkouts (default: ~/development) ### we use CLONEINTO_ROOT as that matches what we're using in git-initial-commit cloneRoot="${CLONEINTO_REPO:-~/development}"

## pathPrefix .. appends the username to the cloneRoot
pathPrefix=${cloneRoot}/${githubUsername}
# expand any ~
# https://stackoverflow.com/questions/3963716/how-to-manually-expand-a-special-variable-ex-tilde-in-bash/27485157#27485157
pathPrefix="${pathPrefix/#\~/$HOME}"

# if we already exist, don't do anything
if [ -d "${pathPrefix}/${reponame}" ]; then
echo "# repository dorectory '${pathPrefix}/${reponame}' already exists"
else
mkdir -p "${pathPrefix}/${reponame}"
cd "${pathPrefix}/${reponame}"

# run our magical little repo creator
git initial-commit

# initialise the go module
go mod init ${gomodPrefix}${reponame}
git commit -v --no-verify -m "go mod init ${gomodPrefix}${reponame}"

# create a shell of a main.go, to give us something to test with
mkdir -p cmd/cli-client
cat <<EOF >cmd/cli-client/main.go
package main

import (
"fmt"

${trimname} "${gomodPrefix}${reponame}" ) func main() { // do nothing exciting ... for now fmt.Println(${trimname}.Global)
}
EOF

# create a simple initial module for main.go to work
cat <<EOF >${trimname}.go package${trimname}

// Global is just a thing you should delete
var Global string = "Hello World"
EOF

# ${reponame} ## Installation ~~~sh go get${gomodPrefix}${reponame} ~~~ ## cli-client You can experiment with the library by running: ~~~sh go run ./cmd/cli-client/main.go ~~~ EOF git add . git commit -m 'Skeleton files' # if it were just me, I'd just use git tt here, but let's have a fallback # for people that aren't me git tt 2>/dev/null || git log --decorate \ --pretty=format:'%Cred%h %C(blue)[%G?] %Cgreen[%cr] %C(bold black)<%an>%Creset%C(yellow)%d %Creset %s%Creset' \ --date=relative \ -n 10 echo "#${reponame} created in ${pathPrefix}/${reponame}"
fi

if type code >/dev/null; then
code -g ./cmd/cli-client/main.go "${pathPrefix}/${reponame}"
fi


## Assumptions

### It uses git initial-commit

I wrote about this recently, and it’s my preferred way to get a new git repo up and running.

If you really don’t want this, you can probably just replace the line with:

git init


### It assumes you’re releasing to github, as me

The module name is automatically written in a “github friendly” manner. For example flizz becomes module github.com/chiselwright/go-flizz

You can alter the prefix by setting the following in your shell:

export GITHUB_USERNAME="myusername"


### It assumes you’re using ~/development

By default clone-into-dir will use ~/development as the root location for all clone actions.

If you prefer to have your code somewhere else you can set a variable in your shell:

export CLONEINTO_ROOT=/path/to/your/preference


This value was chosen to match can read more about this in the clone-into-dir post.

## Source

Just in case the script moves on after the article is published, here’s the source file

## In Action

When you run the script you will see something like this. Output truncated for artistic brevity.