Created
January 9, 2021 23:38
-
-
Save ewen-lbh/3d530c029fcf3d1fe0a64ed50e17e5df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function startproject --description "Start a project." | |
argparse --name="startproject" \ | |
'd/description=' \ | |
'h/help' \ | |
'p/path=' \ | |
'l/language=' \ | |
'o/owner=' \ | |
'k/kind=!startproject__validate_flag__kind' \ | |
'D/debug' \ | |
-- $argv | |
if test $status != 0 | |
return | |
end | |
if not which gh jq git 1>/dev/null | |
echo "Please install the following required software:" | |
echo "· gh https://cli.github.com/" | |
echo "· jq https://stedolan.github.io/jq/" | |
echo "· git https://git-scm.org" | |
echo "" | |
echo "Additionnaly, to manage changelogs, it is recommended to use:" | |
echo "· chachacha https://github.com/aogier/chachacha" | |
return 1 | |
end | |
set --local wd (pwd) | |
set --local name "$argv[1]" | |
set --local today (date +%Y-%m-%d) | |
set --local is_wsl (cat /proc/version | grep "Microsoft@Microsoft.com") | |
set --local tags "" | |
set --local technologies "" | |
set --local description "$_flag_description" | |
set --local language "$_flag_language" | |
set --local path "$_flag_path" | |
set --local owner "$_flag_owner" | |
if test -z $owner | |
set owner ewen-lbh | |
end | |
set --local kind $_flag_kind | |
if test -z $kind | |
set kind bin | |
end | |
echo "-----Running with-------" | |
echo "name: $name" | |
echo "description: $description" | |
echo "language: $language" | |
echo "path: $path" | |
echo "owner: $owner" | |
echo "kind: $kind" | |
echo "------------------------" | |
echo "" | |
if set -q _flag_debug | |
return | |
end | |
if test -z "$name" | |
echo "Provide a name as the first argument" | |
return 1 | |
end | |
if test -z "$path" | |
set path $name | |
end | |
if test -e "$HOME/projects/$path" | |
echo "You already have a project at ~/projects/$path" | |
return 1 | |
end | |
cd ~/projects | |
# Just in case a directory named $name already exists | |
set --local tempname $name.startproject-temp-move-(random) | |
if test -e $name | |
echo "WARN: ~/projects/$name already exists. Do not interrupt the command." | |
echo " If you must, you'll find ~/projects/$name at ~/projects/$tempname" | |
mv $name $tempname | |
or return $status | |
end | |
# Github | |
# Do this first cuz it can't initialize in the current directory, it must create one. | |
# Test if the repo already exists. | |
if gh api repos/$owner/$name 1>/dev/null | |
# Here the repo already exists. Ask if you want to abort or add it as a remote to the new project. | |
echo "The github repository https://github.com/$owner/$name already exists. What to do?" | |
echo " 1. Abort" | |
echo " 2. Create a folder and add the repo as a remote. This requires having jq installed." | |
read --prompt 'echo "[1|2] "' answer | |
if test $answer = 2 | |
mkdir $path | |
cd $path | |
set remote_url (gh api repos/$owner/$name | jq .clone_url -r) | |
set branches (gh api repos/$owner/$name/branches | jq ".[].name" -r) | |
# Decide which branch to use: main or master or the first one | |
if test -z $branches | |
set --local default_init_branch_git (git config --global init.defaultBranch; or echo master) | |
echo "Remote has no branches, defaulting to $default_init_branch_git" | |
set upstream_branch $default_init_branch_git | |
else if echo $branches | grep main | |
set upstream_branch main | |
else if echo $branches | grep master | |
set upstream_branch master | |
else | |
set upstream_branch (echo $branches | head -n 1) | |
echo "WARN: Neither main nor master branches exists on remote" | |
if test -z $upstream_branch | |
echo "Could not get the upstream branch from the following branches:" (echo $branches | string join ', ') | |
end | |
end | |
git init | |
git remote add origin $remote_url | |
else | |
echo "Aborting." | |
return | |
end | |
else | |
if test -n "$description" | |
gh repo create $name -y --public --description "$description" | |
else | |
gh repo create $name -y --public | |
end | |
# There's also no way to separate the repo's name from the created directory | |
if test $name != $path | |
mv $name $path | |
end | |
cd $path | |
end | |
# Some languages have code generation utilities | |
# This also sets tags | |
set --local target generated-(random) | |
if test $kind = "lib" | |
set tags "library" | |
else | |
set tags "program" | |
end | |
set technologies $language | |
switch $language | |
case rust | |
if not which cargo 1>/dev/null | |
echo "Install cargo to use --language=rust" | |
return 1 | |
end | |
set --local cargo_kind $kind | |
if test $cargo_kind = "app" | |
set cargo_kind "bin" | |
end | |
cargo new --$cargo_kind --name $name $target --vcs git | |
or return $status | |
case python | |
if not which poetry 1>/dev/null | |
echo "Install poetry to use --language=python" | |
return 1 | |
end | |
poetry new --name $name $target | |
or return $status | |
case svelte | |
set tags "web, app" | |
if not which degit 1>/dev/null | |
echo "Install degit to use --language=svelte" | |
return 1 | |
end | |
degit sveltejs/template $name | |
or return $status | |
mv $name $target | |
if test -e $tempname | |
mv $tempname $name | |
end | |
case crystal | |
if not which crystal 1>/dev/null | |
echo "Install crystal to use --language=crystal" | |
return 1 | |
end | |
crystal init $kind $name "$target" | |
case ruby | |
if not which bundle 1>/dev/null | |
echo "Install bundle to use --language=ruby" | |
return 1 | |
end | |
if test $kind = "app" | |
bundle gem $target --bin | |
else | |
bundle gem $target | |
end | |
case rails | |
set technologies "ruby-on-rails" | |
if not which rails 1>/dev/null | |
echo "Install rails to use --language=rails" | |
return 1 | |
end | |
set --local args "" | |
if test -n $is_wsl | |
set args "$args --skip-spring --skip-listen" | |
# See https://guides.rubyonrails.org/getting_started.html#creating-a-new-rails-project | |
end | |
set target $name | |
rails new $target $args | |
case go | |
echo "package $name" > $name.go | |
go mod init github.com/$owner/$name | |
case '*' | |
set tags "" | |
mkdir $target | |
end | |
# Some utils init git repositories, don't want to override gh's .git | |
if test -e $target/.git | |
rm -rf $target/.git | |
end | |
# Pull all files from $target to the current directory | |
if find . -maxdepth 1 -name "*" 2>/dev/null | grep -q . | |
mv $target/* . | |
end | |
if find . -maxdepth 1 -name ".*" 2>/dev/null | grep -q . | |
mv $target/.* . | |
end | |
if test -e $target | |
rmdir $target | |
end | |
or return 1 | |
# Install deps | |
# NB: this makes it clear which programming languages | |
# have one standard package manager everyone aggrees on | |
# and which are just a mess haha | |
if test -e package.json | |
set --local pm npm | |
if which pnpm 1>/dev/null | |
set pm pnpm | |
else if which yarn 1>/dev/null | |
set pm yarn | |
else if not which npm 1>/dev/null | |
echo "Install pnpm, yarn or npm" | |
return 1 | |
end | |
$pm install | |
else if test -e Cargo.toml | |
cargo build | |
else if test -e pyproject.toml | |
set --local pm pip | |
if which poetry 1>/dev/null | |
set pm poetry | |
else if which pipenv 1>/dev/null | |
set pm pipenv | |
else if not which npm 1>/dev/null | |
echo "Install poetry, pip or pipenv" | |
return 1 | |
end | |
$pm install | |
else if test -e shard.yml | |
shards install | |
else if test -e go.mod | |
go install | |
end | |
# Changelog | |
if not which chachacha 1>/dev/null | |
echo "WARN: chachacha is not installed, not initializing CHANGELOG.md" | |
else | |
chachacha init | |
end | |
# README | |
if not test -e README.md | |
echo "# $name" > README.md | |
if test -n "$description" | |
echo "$description" >> README.md | |
end | |
end | |
# portfoliodb | |
mkdir .portfoliodb | |
cd .portfoliodb | |
touch description.md | |
echo "---" >> description.md | |
echo "started: $today" >> description.md | |
echo "tags: [$tags]" >> description.md | |
echo "made with: [$technologies]" >> description.md | |
echo "---" >> description.md | |
echo "" >> description.md | |
echo "# $name" >> description.md | |
if test -n "$description" | |
echo "" >> description.md | |
echo ":: en" >> description.md | |
echo "" >> description.md | |
echo "$description" >> description.md | |
end | |
cd .. | |
# Gitignore | |
if test -n $language -a ! -e .gitignore | |
create-gitignore $language 1>/dev/null | |
end | |
git add . | |
and git commit -m "🎉 Initial commit" | |
and git branch -M $upstream_branch | |
and git push -u origin $upstream_branch & | |
code-insiders . | |
# Move back the old $name folder (see beginning of script) | |
cd ~/projects | |
if test -e $tempname -a ! -e $name | |
mv $tempname $name | |
end | |
cd "$wd" | |
end | |
function startproject__validate_flag__kind --no-scope-shadowing | |
set alloweds "lib app" | |
echo $alloweds | grep $_flag_value 1>/dev/null | |
if test $status != 0 | |
echo "Illegal value for --kind: $_flag_value" | |
echo "Allowed values are: " | |
for value in (echo $alloweds | string split ' ') | |
echo "· $value" | |
end | |
return 1 | |
end | |
return 0 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment