Skip to content

Source: scripts/create_skeleton.sh#

#!/usr/bin/env bash
set -eo pipefail
# set -x

this_dir=$(dirname "$(readlink -e "$0")")
this_dir_short=$(basename "${this_dir}")
shared_dir=$(readlink -f "${this_dir}/..")
shared_dir_short=$(basename "${shared_dir}")
project_dir="${this_dir}/../.."

usage() {
    cat - <<EOF
Usage: $(basename "$0") [--project-dir dirname] [--name-library dirname] --yes

Creates directories and minimal files needed for a new project.

--yes                   Confirms the execution of the script

--project-dir dirname   Specify the project directory. If provided,
    it's treated as relative to the current working directory
    If not specified, defaults to '../../'
    (relative to the script's parent directory: ${this_dir}/../..)

--name-library dirname  If specified, this dirname will be used instead the
  current one for the references to the shared infrastructure dir, eg. "infra"

EOF
}

if test "$1" = "--project-dir" -a "$2" != ""; then
    project_dir="$2"
    shift 2
fi
if test "$1" = "--name-library" -a "$2" != ""; then
    shared_dir_short="$2"
    shift 2
fi
if test "$1" != "--yes"; then
    echo "Error: The --yes flag is mandatory." >&2
    usage
    exit 1
fi

# Convert project_dir to an absolute path.
#   If it was provided as an argument, it's relative to CWD
#   If default was used, it's relative to the script's parent dir
project_dir=$(readlink -f "${project_dir}")
project_name=$(basename "${project_dir}")

create_ifnotexist() { #1 filename relative to project_dir
    fname="${project_dir}/$1"
    if test ! -e "$fname"; then
        echo "Writing file: $fname"
        cat - >"$fname"
    else
        echo "Warning: not touching existing file $fname"
        # discard stdin if we're not using it
        cat - >/dev/null
    fi
}

# test for .git or create and initialize project_dir
if [ -d "${project_dir}" ]; then
    if [ ! -d "${project_dir}/.git" ]; then
        echo "Error: Project directory ${project_dir} exists but is not a Git repository." >&2
        echo "Please initialize it as a Git repository or choose a different directory." >&2
        exit 1
    fi
else
    echo "Project directory ${project_dir} does not exist. \nCreating and initializing as a Git repository..."
    mkdir -p "${project_dir}"
    if ! git init "${project_dir}"; then
        echo "Error: Failed to initialize Git repository in ${project_dir}." >&2
        rmdir "${project_dir}" 2>/dev/null || echo "Warning: Could not remove directory ${project_dir} after failed git init." >&2
        exit 1
    fi
fi

# create subdirs and add .gitkeep file
for d in docs state target; do
    mkdir -p "${project_dir}/${d}"
    create_ifnotexist "${d}/.gitkeep" </dev/null
done

# copy and template: Makefile, pyproject.toml
for f in Makefile pyproject.toml; do
    # replace hardcoded instances of infra/ and project_name for custom naming
    cat "${shared_dir}/examples/skeleton/${f}" |
        sed -r "s#infra/#${shared_dir_short}/#g" |
        sed -r "s#project_name#${project_name}#g" |
        create_ifnotexist "${f}"
done

# create an empty authorized_keys for appending to it later
create_ifnotexist authorized_keys </dev/null

# symlink README.md to docs
# Check if docs/README.md already exists to avoid error if it's a regular file or different symlink
if [ ! -e "${project_dir}/docs/README.md" ]; then
    ln -s ../README.md "${project_dir}/docs/README.md"
else
    echo "Warning: ${project_dir}/docs/README.md already exists. Skipping symlink creation."
fi

create_ifnotexist README.md <<EOF
# ${project_name}

Software Defined Git Operated Infrastructure

EOF

create_ifnotexist __main__.py <<EOF
"""A Python Pulumi program"""


import ${shared_dir_short}.authority

EOF

create_ifnotexist Pulumi.yaml <<EOF
name: ${project_name}
runtime:
  name: python
  options:
    virtualenv: .venv
description: ${project_name} pulumi infrastructure

EOF

create_ifnotexist config-template.yaml <<EOF
config:
  libvirt:uri: qemu:///system
  ${project_name}:locale:
    lang: en_US.UTF-8
    keymap: us
    timezone: UTC
    country_code: UN

EOF

create_ifnotexist .gitignore <<EOF
# python virtualenv
.venv

# directory for temporary files
build/tmp

# saltstack state files
build/salt

# mkdocs generated documentation files
build/docs

# pulumi state for stacks "*sim"
state/pulumi/.pulumi/backups/*sim
state/pulumi/.pulumi/history/*sim
state/pulumi/.pulumi/locks/*sim
state/pulumi/.pulumi/stacks/*sim.json*

# pulumi config for stacks "*sim"
Pulumi.*sim.yaml

# exported infrastructure states files for stacks "*sim"
state/files/*sim

# interactive python checkpoints
.ipynb_checkpoints

# python package info
${project_name}.egg-info

# compiled python
*.pyc
__pycache__

# editor artifacts
.zed

EOF

create_ifnotexist mkdocs.yml <<EOF
site_name: ${project_name} Infrastructure

theme:
  name: material

plugins:
  - search
  - include-markdown

markdown_extensions:
  - smarty
  - toc:
      permalink: "#"
  - pymdownx.magiclink
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid
          format: !!python/name:pymdownx.superfences.fence_code_format

nav:
  - README.md

EOF

echo "Skeleton for project ${project_name} created in ${project_dir}"