diff --git a/CHANGELOG.md b/CHANGELOG.md index d497c96a..b98569ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ master * DRY-up config.rb-specific commands like `ignore` or `path`. * Fix automatic images with absolute (or images dir missing) paths in markdown. Fixes #1755 * Fix asset_host in combination with Google Analytics snippet. #1751 +* Show an error message when git CLI is not available. #1765 # 4.0.0 diff --git a/middleman-cli/lib/middleman-cli/init.rb b/middleman-cli/lib/middleman-cli/init.rb index 469d9d4c..86e2ef91 100644 --- a/middleman-cli/lib/middleman-cli/init.rb +++ b/middleman-cli/lib/middleman-cli/init.rb @@ -4,6 +4,8 @@ module Middleman::Cli class Init < Thor::Group include Thor::Actions + GIT_CMD = 'git' + check_unknown_options! argument :target, type: :string, default: '.' @@ -25,6 +27,13 @@ module Middleman::Cli require 'fileutils' require 'tmpdir' + if !git_present? + msg = "You need to install the git command line tool to initialize a new project. " + msg << "For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git" + say msg, :red + exit 1 + end + repo_path, repo_branch = if shortname?(options[:template]) require 'open-uri' require 'json' @@ -51,10 +60,11 @@ module Middleman::Cli begin branch_cmd = repo_branch ? "-b #{repo_branch} " : '' - run("git clone --depth 1 #{branch_cmd}#{repo_path} #{dir}") + git_path = "#{branch_cmd}#{repo_path}" + run("#{GIT_CMD} clone --depth 1 #{branch_cmd}#{repo_path} #{dir}") - unless File.directory?(dir) - say 'Git clone failed, maybe the url is invalid or you don\'t have the permissions?', :red + if !$?.success? + say "Git clone command failed. Make sure git repository exists: #{git_path}", :red exit 1 end @@ -79,6 +89,25 @@ module Middleman::Cli protected + # Copied from Bundler + def git_present? + return @git_present if defined?(@git_present) + @git_present = which(GIT_CMD) || which("git.exe") + end + + # Copied from Bundler + def which(executable) + if File.file?(executable) && File.executable?(executable) + executable + elsif ENV['PATH'] + path = ENV['PATH'].split(File::PATH_SEPARATOR).find do |p| + abs_path = File.join(p, executable) + File.file?(abs_path) && File.executable?(abs_path) + end + path && File.expand_path(executable, path) + end + end + def shortname?(repo) repo.split('/').length == 1 end diff --git a/middleman-core/features/cli_init.feature b/middleman-core/features/cli_init.feature index 52aa8f7b..8591d1be 100644 --- a/middleman-core/features/cli_init.feature +++ b/middleman-core/features/cli_init.feature @@ -63,6 +63,13 @@ Feature: Middleman CLI And the file "Gemfile" should contain "middleman-blog" And the file ".gitignore" should exist + Scenario: Create an invalid project using Middleman directory + When I run `middleman init MY_PROJECT -T does-not-exist-for-reals` + Then a directory named "MY_PROJECT" should exist + When I cd to "MY_PROJECT" + And the file "Gemfile" should contain "middleman-blog" + And the file ".gitignore" should exist + Scenario: Create a new project using github(user/repository) When I run `middleman init MY_PROJECT -T middleman/middleman-templates-default` interactively And I type "y"