├── start.sh └── README.md /start.sh: -------------------------------------------------------------------------------- 1 | start(){ 2 | local foreman=false 3 | local executinglabel="Executing:" 4 | local planblabel="Command failed, time for Plan B" 5 | local yellow="\033[1;33m" 6 | local cyan="\033[1;36m" 7 | local reset="\033[0;0m" 8 | local port="3000" 9 | 10 | # Reset, so getopts will parse options every time function is called 11 | OPTIND=1 12 | 13 | while getopts ":p:" opt; do 14 | case $opt in 15 | p) 16 | port=$OPTARG 17 | ;; 18 | \?) 19 | echo "Invalid option: -$OPTARG" >&2 20 | exit 1 21 | ;; 22 | :) 23 | echo "Option -$OPTARG requires an argument." >&2 24 | exit 1 25 | ;; 26 | esac 27 | done 28 | 29 | if [ -f ./Procfile.dev ]; 30 | then 31 | local messagea="Procfile.dev detected" 32 | local commanda="foreman start -f Procfile.dev -p $port" 33 | foreman=true 34 | elif [ -f ./Procfile ]; 35 | then 36 | local messagea="Procfile detected" 37 | local commanda="foreman start -p $port" 38 | foreman=true 39 | elif [ -f ./config/boot.rb ] 40 | then 41 | local messagea="No Procfiles detected, falling back to rails" 42 | local commanda="rails server" 43 | elif [ -f ./config.ru ] 44 | then 45 | local messagea="Rack app detected" 46 | local commanda="rackup --port $port config.ru" 47 | elif [ -f ./package.json ] 48 | then 49 | local messagea="NPM app detected" 50 | local commanda="npm start" 51 | elif [[ -f ./_config.yml && -d ./_site ]] 52 | then 53 | local messagea="Jekyll site detected" 54 | local commanda="jekyll serve --watch --port $port" 55 | local messageb="Jekyll < 1.0 detected" 56 | local commandb="jekyll --server $port --pygments --auto" 57 | elif [ -f ./home.* ] 58 | then 59 | local messagea="Gollum wiki detected" 60 | local commanda="gollum --css --js --port $port" 61 | elif [ -f ./config.toml && -f ./themes ] 62 | then 63 | local messagea="Hugo site detected" 64 | local commanda="hugo server -p $port" 65 | elif [ -f ./manage.py ]; 66 | then 67 | local messagea="Django app detected" 68 | local commanda="python manage.py runserver $port" 69 | else 70 | local messagea="Could not detect app type, do nothing" 71 | fi 72 | 73 | if [[ -n "$commanda" && -f Gemfile && ! $foreman ]]; 74 | then 75 | commanda="bundle exec $commanda" 76 | if [ -n "$commandb" ]; 77 | then 78 | commandb="bundle exec $commandb" 79 | fi 80 | fi 81 | 82 | echo -e "$yellow$messagea$reset" 83 | if [[ -n "$commanda" && -n "$commandb" ]] 84 | then 85 | { 86 | echo -e "$cyan$executinglabel$reset $commanda" 87 | $commanda 88 | } || { 89 | echo $planblabel 90 | echo -e "$yellow$messageb$reset" 91 | echo -e "$cyan$executinglabel$reset $commandb" 92 | $commandb 93 | } 94 | elif [ -n "$commanda" ] 95 | then 96 | echo -e "$cyan$executinglabel$reset $commanda" 97 | $commanda 98 | fi 99 | } 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Start.sh 2 | 3 | A simple bash command to start your local web project without having to 4 | remember whether it's a Rails app, Node app, Sinatra app, Jekyll site, 5 | Gollum wiki, Rack app, Foreman project, or whatever else; whether it uses 6 | Bundler or not; what the server command is; or what port the project runs 7 | on by default. 8 | 9 | Just `cd` into the project's directory and run 10 | 11 | ``` 12 | start 13 | ``` 14 | 15 | That's it. 16 | 17 | ## Why? 18 | 19 | I tend to write lots of little web utilities, sites, and applications. I 20 | got tired of trying to remember what the command was to serve the app up 21 | locally so I could open it in my browser and get to coding. 22 | 23 | Every framework seems to have its own webserver shortcut and its own 24 | default port. Even when I did finally remember what command to use to 25 | start that app's webserver, I'd have to and wait for the 26 | command output to the terminal to remember what port it would run on 27 | before I could open it in my browser. Rails would run on 3000, Sinatra 28 | and Gollum on 4567, Jekyll on 4000; then I'd add Foreman to the mix 29 | and now the port changes to 5000. Ugh. 30 | 31 | And then frameworks like Jekyll change their webserver 32 | commands entirely; now I have to remember when I built this Jekyll app, so I can 33 | figure out which version it uses and whether to use the new command or the old one. 34 | 35 | Enough already! Now I just run `start` and open my browser to 36 | http://localhost:3000. 37 | 38 | ## How? 39 | 40 | This command line utility uses some shortcuts and hacks to detect what 41 | kind of project the current directory is, so that it can stay *fast*. 42 | 43 | This means, it doesn't try to invoke Ruby or Node or any other language 44 | when it can use Bash to determine with acceptable confidence what type 45 | of project the current directory is. This usually means 46 | checking for the existence of certain files that are required for 47 | projects of a given framework. 48 | 49 | ## Options 50 | 51 | Currently, Start only has one option for the port. By default, all 52 | projects started with Start run on port 3000. If you'd like to run the 53 | app on a different port, use the `-p` flag: 54 | 55 | ``` 56 | start -p 4567 57 | ``` 58 | 59 | ## Current detection types 60 | 61 | ### Foreman 62 | 63 | If a `Procfile` is detected in the root directory of the current 64 | project, then Start simply runs `foreman start` and not use any 65 | further detection, since Foreman manages the processes already. 66 | 67 | By convention, Start will first look for `Procfile.dev` if it exists, 68 | and then it will look secondly for `Procfile`. 69 | 70 | ### Bundler 71 | 72 | If a `Gemfile` is detected in the root directory, Start will still try 73 | to detect what type of project the current directory is, but once it 74 | finds that command, it will preface it with `bundle exec`. 75 | 76 | ### Rack 77 | 78 | If a `config.ru` file is detected in the root directory, Start will run 79 | `rackup`. 80 | 81 | ### NPM 82 | 83 | If a `package.json` file is detected in the root directory, Start will 84 | run `npm start`. This also works for Express and other apps, so no 85 | additional detection is built specifically for them. 86 | 87 | ### Jekyll 88 | 89 | If a `_config.yml` file and `_site` directory are detected in the root 90 | directory, Start will run `jekyll serve`. If that fails, it will 91 | fallback to `jekyll --server`, which is the command for older versions 92 | of Jekyll. 93 | 94 | It's faster to try the first way and fallback to the second than it is 95 | to run a command like `gem list` to try to figure out what version of 96 | Jekyll is being used. 97 | 98 | ### Gollum 99 | 100 | If a `home.*` file is detected in the root directory, where the 101 | extension can be any markup template extension, Start will run `gollum`. 102 | 103 | We may need to make this detection more specific the first time we add a 104 | project-type that may also conventionally have a `home.*` file. 105 | 106 | ### Hugo 107 | 108 | If a `config.toml` file and `themes` directory are detected in the root directory, Start will run `hugo server` 109 | 110 | ### Django 111 | 112 | If a `manage.py` file is detected in the root directory, Start will run `python manage.py runserver` 113 | 114 | ## More 115 | 116 | If you have another application that isn't currently detected, please 117 | open an issue or pull request. 118 | --------------------------------------------------------------------------------