diff --git a/.gitignore b/.gitignore index 1bef0bd..850f17e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ doc .bundle pkg presentation +a_file.rb +git_presenter*.gem diff --git a/.travis.yml b/.travis.yml index 566b34c..7f8535f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,8 @@ language: ruby rvm: - 1.9.2 - 1.9.3 - - jruby-19mode # JRuby in 1.9 mode + - 2.0.0 + - 2.1.0 + - 3.0.0 + # - jruby-19mode # JRuby in 1.9 mode +script: "bundle exec rspec spec" diff --git a/Gemfile b/Gemfile index 6165fe1..23ca1d6 100644 --- a/Gemfile +++ b/Gemfile @@ -3,14 +3,14 @@ source "http://rubygems.org" # Example: # gem "activesupport", ">= 2.3.5" # -gem "grit", "~> 2.4" +gem "git", "1.8.1" +gem 'launchy', "2.5.0" # Add dependencies to develop your gem here. # Include everything needed to run rake, tests, features, etc. group :development do - gem "pry" - gem "rspec", "~> 2.7" - gem "bundler" - gem "jeweler", "~> 1.6" - gem "rcov", "~> 0.9" + gem "pry", "0.14.1" + gem "rspec", "3.10.0" + gem "bundler", "2.2.3" + gem 'jeweler', "2.3.5" end diff --git a/Gemfile.lock b/Gemfile.lock index cf52975..7e15336 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,47 +1,102 @@ GEM remote: http://rubygems.org/ specs: - coderay (1.0.6) - diff-lcs (1.1.3) - git (1.2.5) - grit (2.5.0) - diff-lcs (~> 1.1) - mime-types (~> 1.15) - posix-spawn (~> 0.3.6) - jeweler (1.8.3) - bundler (~> 1.0) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + builder (3.2.4) + coderay (1.1.3) + descendants_tracker (0.0.4) + thread_safe (~> 0.3, >= 0.3.1) + diff-lcs (1.4.4) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + ffi (1.15.0-java) + git (1.8.1) + rchardet (~> 1.8) + github_api (0.11.3) + addressable (~> 2.3) + descendants_tracker (~> 0.0.1) + faraday (~> 0.8, < 0.10) + hashie (>= 1.2) + multi_json (>= 1.7.5, < 2.0) + nokogiri (~> 1.6.0) + oauth2 + hashie (4.1.0) + highline (2.0.3) + jar-dependencies (0.4.1) + jeweler (2.3.5) + builder + bundler (>= 1.0) git (>= 1.2.5) + github_api (~> 0.11.0) + highline (>= 1.6.15) + nokogiri (>= 1.5.10) + psych (~> 2.2) rake rdoc - json (1.7.3) - method_source (0.7.1) - mime-types (1.18) - posix-spawn (0.3.6) - pry (0.9.9.6) - coderay (~> 1.0.5) - method_source (~> 0.7.1) - slop (>= 2.4.4, < 3) - rake (0.9.2.2) - rcov (0.9.11) - rdoc (3.12) - json (~> 1.4) - rspec (2.10.0) - rspec-core (~> 2.10.0) - rspec-expectations (~> 2.10.0) - rspec-mocks (~> 2.10.0) - rspec-core (2.10.1) - rspec-expectations (2.10.0) - diff-lcs (~> 1.1.3) - rspec-mocks (2.10.1) - slop (2.4.4) + semver2 + jwt (2.2.3) + launchy (2.5.0) + addressable (~> 2.7) + method_source (1.0.0) + mini_portile2 (2.1.0) + multi_json (1.15.0) + multi_xml (0.6.0) + multipart-post (2.1.1) + nokogiri (1.6.8.1) + mini_portile2 (~> 2.1.0) + nokogiri (1.6.8.1-java) + oauth2 (1.4.7) + faraday (>= 0.8, < 2.0) + jwt (>= 1.0, < 3.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (>= 1.2, < 3) + pry (0.14.1) + coderay (~> 1.1) + method_source (~> 1.0) + pry (0.14.1-java) + coderay (~> 1.1) + method_source (~> 1.0) + spoon (~> 0.0) + psych (2.2.4) + psych (2.2.4-java) + jar-dependencies (>= 0.1.7) + public_suffix (4.0.6) + rack (2.2.3) + rake (13.0.3) + rchardet (1.8.0) + rdoc (6.3.0) + rspec (3.10.0) + rspec-core (~> 3.10.0) + rspec-expectations (~> 3.10.0) + rspec-mocks (~> 3.10.0) + rspec-core (3.10.1) + rspec-support (~> 3.10.0) + rspec-expectations (3.10.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.10.0) + rspec-mocks (3.10.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.10.0) + rspec-support (3.10.2) + semver2 (3.4.2) + spoon (0.0.6) + ffi + thread_safe (0.3.6) + thread_safe (0.3.6-java) PLATFORMS + java ruby DEPENDENCIES - bundler - grit (~> 2.4) - jeweler (~> 1.6) - pry - rcov (~> 0.9) - rspec (~> 2.7) + bundler (= 2.2.3) + git (= 1.8.1) + jeweler (= 2.3.5) + launchy (= 2.5.0) + pry (= 0.14.1) + rspec (= 3.10.0) + +BUNDLED WITH + 2.2.3 diff --git a/README.markdown b/README.markdown index 5f25ff3..12e2089 100644 --- a/README.markdown +++ b/README.markdown @@ -1,6 +1,6 @@ # git-presenter -[![Build Status](https://secure.travis-ci.org/pythonandchips/git-presenter.png?branch=master)](http://travis-ci.org/pythonandchips/git-presenter) +[![Build Status](https://drone.io/github.com/pythonandchips/git-presenter/status.png)](https://drone.io/github.com/pythonandchips/git-presenter/latest) When presenting code live on stage you have a few choices: @@ -11,13 +11,12 @@ Git-presenter hope to solve this problem by giving a presentation style interfac ## Current status -Early version but the basics are there to be used. -Any and all feedback is welcome +Complete. ## Pre-requisites * Git -* Ruby version 1.9.2 or 1.9.3 or jruby in 1.9 mode (basically anything with 1.9 at the end) +* Ruby version 1.9.2, 1.9.3, 2.0.0, 2.1.0 and jruby ## Installation @@ -28,6 +27,7 @@ gem install git_presenter * Commit to git as you develop your code. * When the code is ready use the "git-presenter init" command to initialise * Once it is initialised you can start the presentation with "git-presenter start" +* Make more commits if need be and use "git-presenter update" * Then use the following command to navigate the presentation * next/n: move to next slide * back/b: move back a slide @@ -36,7 +36,20 @@ gem install git_presenter * list/l : list slides in presentation * help/h: display this message -## Bugs/Features/Prase +### Command mode + +The default for git presenter is interactive mode however if you want to use git presenter from a text editor you can use command mode. + +To start a presentation in command mode use "git-presenter start -c" + +Once started you run "git-presenter {{command}}" e.g. to move to the next slide run "git-presenter next" + +## Other resources +There are couple of videos showing git presenter and how to us it +* (video 1)[https://vimeo.com/38949496] +* (video 2)[https://vimeo.com/39225144] + +## Bugs/Features/Praise It you find any bugs or have some feature requests please add an issue on the repository. Or if you just want to get in touch and tell me how awesome git presenter is you can get me on twitter @colin_gemmell or drop me an email at pythonandchips{at}gmail.com @@ -51,6 +64,10 @@ It you find any bugs or have some feature requests please add an issue on the re * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally. * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it. +## Contributors + +* (Luís Ferreira - Zamith)[https://github.com/zamith] + ## Copyright Copyright (c) 2012 Colin Gemmell @@ -73,4 +90,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/Rakefile b/Rakefile index c334f91..307ee28 100644 --- a/Rakefile +++ b/Rakefile @@ -24,26 +24,3 @@ Jeweler::Tasks.new do |gem| # dependencies defined in Gemfile end Jeweler::RubygemsDotOrgTasks.new - -require 'rspec/core' -require 'rspec/core/rake_task' -RSpec::Core::RakeTask.new(:spec) do |spec| - spec.pattern = FileList['spec/**/*_spec.rb'] -end - -RSpec::Core::RakeTask.new(:rcov) do |spec| - spec.pattern = 'spec/**/*_spec.rb' - spec.rcov = true -end - -task :default => :spec - -require 'rake/rdoctask' -Rake::RDocTask.new do |rdoc| - version = File.exist?('VERSION') ? File.read('VERSION') : "" - - rdoc.rdoc_dir = 'rdoc' - rdoc.title = "git_presenter #{version}" - rdoc.rdoc_files.include('README*') - rdoc.rdoc_files.include('lib/**/*.rb') -end diff --git a/VERSION b/VERSION index f477849..88c5fb8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.2 \ No newline at end of file +1.4.0 diff --git a/bin/git-presenter b/bin/git-presenter old mode 100644 new mode 100755 index b7be041..f2c7fe8 --- a/bin/git-presenter +++ b/bin/git-presenter @@ -1,8 +1,14 @@ -#!/usr/bin/ruby +#!/usr/bin/env ruby require "rubygems" require_relative "../lib/git_presenter" -YAML::ENGINE.yamler = 'psych' +YAML::ENGINE.yamler = 'psych' if defined?(Psych::ENGINE) -presenter = GitPresenter.new(Dir.pwd) +if ARGV[1] == "-c" + interactive = false +else + interactive = true +end + +presenter = GitPresenter.new(Dir.pwd, interactive) presenter.execute(ARGV[0]) diff --git a/git_presenter.gemspec b/git_presenter.gemspec index d7fc137..b6c4a85 100644 --- a/git_presenter.gemspec +++ b/git_presenter.gemspec @@ -2,17 +2,19 @@ # DO NOT EDIT THIS FILE DIRECTLY # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' # -*- encoding: utf-8 -*- +# stub: git_presenter 1.4.0 ruby lib Gem::Specification.new do |s| - s.name = "git_presenter" - s.version = "0.2.2" + s.name = "git_presenter".freeze + s.version = "1.4.0" - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Colin Gemmell"] - s.date = "2012-04-17" - s.description = "Code presentation tool using git" - s.email = "pythonandchips@gmail.com" - s.executables = ["git-presenter"] + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Colin Gemmell".freeze] + s.date = "2021-05-01" + s.description = "Code presentation tool using git".freeze + s.email = "pythonandchips@gmail.com".freeze + s.executables = ["git-presenter".freeze] s.extra_rdoc_files = [ "LICENSE.txt", "README.markdown" @@ -29,48 +31,45 @@ Gem::Specification.new do |s| "bin/git-presenter", "git_presenter.gemspec", "lib/git_presenter.rb", - "lib/git_presenter/parser.rb", + "lib/git_presenter/controller.rb", "lib/git_presenter/presentation.rb", + "lib/git_presenter/shell.rb", "lib/git_presenter/slide.rb", - "lib/git_presenter/writer.rb", + "spec/bugs/max_10_commits_being_parsed_spec.rb", "spec/integration/initialize_presentation_spec.rb", "spec/integration/moving_through_presentation_spec.rb", "spec/integration/start_presentation_spec.rb", + "spec/integration/update_presentation_spec.rb", + "spec/lib/git_presenter/controller_spec.rb", "spec/lib/git_presenter/presentation_spec.rb", "spec/lib/git_presenter/slide_spec.rb", - "spec/lib/git_presenter/writer_spec.rb", "spec/spec_helper.rb", "spec/support/command_line_helper.rb", "spec/support/git_helpers.rb" ] - s.homepage = "http://github.com/pythonandchips/git-presenter" - s.licenses = ["MIT"] - s.require_paths = ["lib"] - s.rubygems_version = "1.8.15" - s.summary = "Code presentation tool using git" + s.homepage = "http://github.com/pythonandchips/git-presenter".freeze + s.licenses = ["MIT".freeze] + s.rubygems_version = "3.2.3".freeze + s.summary = "Code presentation tool using git".freeze if s.respond_to? :specification_version then - s.specification_version = 3 + s.specification_version = 4 + end - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, ["~> 2.4"]) - s.add_development_dependency(%q, ["~> 2.7"]) - s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, ["~> 1.6"]) - s.add_development_dependency(%q, ["~> 0.9"]) - else - s.add_dependency(%q, ["~> 2.4"]) - s.add_dependency(%q, ["~> 2.7"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 1.6"]) - s.add_dependency(%q, ["~> 0.9"]) - end + if s.respond_to? :add_runtime_dependency then + s.add_runtime_dependency(%q.freeze, ["= 1.8.1"]) + s.add_runtime_dependency(%q.freeze, ["= 2.5.0"]) + s.add_development_dependency(%q.freeze, ["= 0.14.1"]) + s.add_development_dependency(%q.freeze, ["= 3.10.0"]) + s.add_development_dependency(%q.freeze, ["= 2.2.3"]) + s.add_development_dependency(%q.freeze, ["= 2.3.5"]) else - s.add_dependency(%q, ["~> 2.4"]) - s.add_dependency(%q, ["~> 2.7"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 1.6"]) - s.add_dependency(%q, ["~> 0.9"]) + s.add_dependency(%q.freeze, ["= 1.8.1"]) + s.add_dependency(%q.freeze, ["= 2.5.0"]) + s.add_dependency(%q.freeze, ["= 0.14.1"]) + s.add_dependency(%q.freeze, ["= 3.10.0"]) + s.add_dependency(%q.freeze, ["= 2.2.3"]) + s.add_dependency(%q.freeze, ["= 2.3.5"]) end end diff --git a/lib/git_presenter.rb b/lib/git_presenter.rb index 9dc764c..0bd4efb 100644 --- a/lib/git_presenter.rb +++ b/lib/git_presenter.rb @@ -1,11 +1,13 @@ -require "grit" -require "yaml" -require "readline" +require 'git' +require 'yaml' +require 'readline' +require 'launchy' class GitPresenter - require "git_presenter/presentation" - require "git_presenter/controller" - require "git_presenter/slide" + require_relative 'git_presenter/presentation' + require_relative 'git_presenter/controller' + require_relative 'git_presenter/slide' + require_relative 'git_presenter/shell' def initialize(current_dir, interactive=true) @controller = Controller.new(current_dir) @@ -13,21 +15,28 @@ def initialize(current_dir, interactive=true) end def execute(command) - if command == "init" + if command == 'init' @controller.initialise_presentation - elsif command == "start" + elsif command == 'start' @presentation = @controller.start_presentation if @interactive enter_run_loop end - elsif command == "update" + elsif command == 'update' @controller.update_presentation else + if @presentation.nil? + @presentation = @controller.load_presentation + end puts @presentation.execute(command) end @presentation end + def current_slide + @presentation.current_slide + end + private def enter_run_loop diff --git a/lib/git_presenter/controller.rb b/lib/git_presenter/controller.rb index 685b072..c047ba2 100644 --- a/lib/git_presenter/controller.rb +++ b/lib/git_presenter/controller.rb @@ -6,7 +6,7 @@ def initialize(file_path) end def initialise_presentation - yaml = {"slides" => create_slides}.to_yaml + yaml = {"slides" => create_slides, "branch" => current_branch}.to_yaml File.open(presentation_file_location, "w") do |file| file.write(yaml) end @@ -14,9 +14,13 @@ def initialise_presentation puts "run 'git-presenter start' to begin the presentation" end - def start_presentation + def load_presentation yaml = YAML.parse(File.open(@presentation_dir + "/.presentation", "r")).to_ruby - presenter = GitPresenter::Presentation.new(yaml) + GitPresenter::Presentation.new(yaml) + end + + def start_presentation + presenter = load_presentation puts presenter.start presenter end @@ -24,7 +28,6 @@ def start_presentation def update_presentation yaml = YAML.parse(File.open(@presentation_dir + "/.presentation", "r")).to_ruby slides = create_slides(yaml['slides'].last["slide"]["commit"]) - last_commit = yaml["slides"].last yaml["slides"] = yaml["slides"] + slides yaml["slides"].uniq! write_file(yaml.to_yaml) @@ -44,14 +47,18 @@ def presentation_file_location end def create_slides(last_commit=nil) - repo = Grit::Repo.new(".", "master") - commits = repo.commits("master", false).reverse - commits = commits.drop_while{|commit| commit.id != last_commit}[1..-1] unless last_commit.nil? + repo = Git.open(".") + commits = repo.log.to_a.reverse + commits = commits.drop_while{|commit| commit.sha != last_commit}[1..-1] unless last_commit.nil? commits.map do |commit| {"slide" => - {"commit" => commit.id, + {"commit" => commit.sha, "message" => commit.message} } end end + + def current_branch + `git rev-parse --abbrev-ref HEAD`.strip + end end diff --git a/lib/git_presenter/presentation.rb b/lib/git_presenter/presentation.rb index 3894c6a..ebf00cc 100644 --- a/lib/git_presenter/presentation.rb +++ b/lib/git_presenter/presentation.rb @@ -1,9 +1,16 @@ class GitPresenter::Presentation attr_reader :slides, :current_slide - def initialize(presentation) + def initialize(presentation, shell=GitPresenter::Shell.new) + @branch = presentation["branch"] @slides = presentation["slides"].map{|slide| GitPresenter::Slide.new(slide["slide"])} - @current_slide = slides.first + @shell = shell + @current_slide = find_current_slide + end + + def find_current_slide + sha = @shell.run("git rev-parse HEAD").strip + @slides.detect{|s| s.commit == sha} end def command_for(command) @@ -27,7 +34,6 @@ def execute(user_command) end return commit(user_command.to_i) if command == :commit return bash_command(user_command) if command == :command - return :exit if command == :exit self.send(command) end @@ -39,8 +45,13 @@ def status_line "#{position+1}/#{total_slides} >" end + def exit + `git checkout -q #{@branch}` + :exit + end + def position - slides.index(@current_slide) + @slides.index(@current_slide) end def total_slides diff --git a/lib/git_presenter/shell.rb b/lib/git_presenter/shell.rb new file mode 100644 index 0000000..9da374d --- /dev/null +++ b/lib/git_presenter/shell.rb @@ -0,0 +1,5 @@ +class GitPresenter::Shell + def run(command) + `#{command}`.strip + end +end diff --git a/lib/git_presenter/slide.rb b/lib/git_presenter/slide.rb index 95d6b2d..b7c38e5 100644 --- a/lib/git_presenter/slide.rb +++ b/lib/git_presenter/slide.rb @@ -5,12 +5,14 @@ def initialize(slide) @commit = slide["commit"] @message = slide["message"] @run = slide["run"] + @launch = slide["launch"] end def execute output = "" output << checkout unless @commit.nil? output << `#{run}` unless @run.nil? + Launchy.open(@launch) unless @launch.nil? output end diff --git a/spec/bugs/max_10_commits_being_parsed_spec.rb b/spec/bugs/max_10_commits_being_parsed_spec.rb index d4706c3..3e966d1 100644 --- a/spec/bugs/max_10_commits_being_parsed_spec.rb +++ b/spec/bugs/max_10_commits_being_parsed_spec.rb @@ -7,7 +7,7 @@ it "should parse more than 10 commits" do @helper.initialise_presentation({:no_of_commits => 13}) do |commits, yaml| - yaml["slides"].length.should eql 13 + expect(yaml["slides"].length).to eql 13 end end end diff --git a/spec/integration/initialize_presentation_spec.rb b/spec/integration/initialize_presentation_spec.rb index a0aa9bb..8653628 100644 --- a/spec/integration/initialize_presentation_spec.rb +++ b/spec/integration/initialize_presentation_spec.rb @@ -10,31 +10,37 @@ context ".presentation file" do it "should be written to root directory" do @helper.initialise_presentation do - File.exists?(".presentation").should be_true + expect(File.exists?(".presentation")).to be_truthy end end it "should have a slides node" do @helper.initialise_presentation do |commits, yaml| - yaml["slides"].should_not be_nil + expect(yaml["slides"]).not_to be_nil + end + end + + it 'should have a branch note' do + @helper.initialise_presentation do |commits, yaml| + expect(yaml["branch"]).not_to be_nil end end it "should contain a line for each commit to the repository" do @helper.initialise_presentation do |commits, yaml| - yaml["slides"].length.should eql commits.length + expect(yaml["slides"].length).not_to eql commits.length end end it "first line should contain the first commit number" do @helper.initialise_presentation({:delay => true}) do |commits, yaml| - yaml["slides"][0]["slide"]["commit"].should eql commits.first.id + expect(yaml["slides"][0]["slide"]["commit"]).to eql commits.first.sha end end it "second line should contain the second commit number" do @helper.initialise_presentation({:delay => true}) do |commits, yaml| - yaml["slides"][1]["slide"]["commit"].should eql commits[1].id + expect(yaml["slides"][1]["slide"]["commit"]).to eql commits[1].sha end end end diff --git a/spec/integration/moving_through_presentation_spec.rb b/spec/integration/moving_through_presentation_spec.rb index 74371bd..7dd7e49 100644 --- a/spec/integration/moving_through_presentation_spec.rb +++ b/spec/integration/moving_through_presentation_spec.rb @@ -11,7 +11,7 @@ it "should move to the next commit" do @helper.start_presentation do |commits, presenter| presenter.execute("next") - @helper.head_position.should eql commits[1].id + expect(@helper.head_position).to eql commits[1].sha end end @@ -19,7 +19,7 @@ @helper.start_presentation do |commits, presenter| presenter.execute("next") presenter.execute("next") - @helper.head_position.should eql commits[2].id + expect(@helper.head_position).to eql commits[2].sha end end end @@ -30,7 +30,7 @@ presenter.execute("next") @helper.edit_file("inner commit") presenter.execute("next") - @helper.head_position.should eql commits[2].id + expect(@helper.head_position).to eql commits[2].sha end end end @@ -42,7 +42,7 @@ presenter.execute("next") presenter.execute("next") presenter.execute("next") - @helper.head_position.should eql commits[2].id + expect(@helper.head_position).to eql commits[2].sha end end end @@ -53,7 +53,7 @@ presenter.execute("next") presenter.execute("next") presenter.execute("back") - @helper.head_position.should eql commits[1].id + expect(@helper.head_position).to eql commits[1].sha end end end @@ -67,7 +67,7 @@ presenter.execute("back") presenter.execute("back") presenter.execute("back") - @helper.head_position.should eql commits[0].id + expect(@helper.head_position).to eql commits[0].sha end end end @@ -78,7 +78,7 @@ presenter.execute("next") presenter.execute("next") presenter.execute("start") - @helper.head_position.should eql commits[0].id + expect(@helper.head_position).to eql commits[0].sha end end end @@ -87,7 +87,7 @@ it "should move the last commit" do @helper.start_presentation do |commits, presenter| presenter.execute("end") - @helper.head_position.should eql commits.last.id + expect(@helper.head_position).to eql commits.last.sha end end end @@ -96,7 +96,7 @@ it "should checkout the specific commit" do @helper.start_presentation do |commits, presenter| presenter.execute("2") - @helper.head_position.should eql commits[1].id + expect(@helper.head_position).to eql commits[1].sha end end end @@ -104,9 +104,9 @@ context "list presentation" do it "should print a list of commits" do @helper.start_presentation do |commits, presenter| - expected_output = (["*#{commits.first.id[0..9]}, #{commits.first.message}"] + commits[1..-1].map{|commit| "#{commit.id[0..9]}, #{commit.message}"}).join("\n") + expected_output = (["*#{commits.first.sha[0..9]}, #{commits.first.message}"] + commits[1..-1].map{|commit| "#{commit.sha[0..9]}, #{commit.message}"}).join("\n") presentation = presenter.execute("list") - presentation.should eql expected_output + expect(presentation).to eql expected_output end end end @@ -127,7 +127,7 @@ exit: exit from the presentation EOH message = presenter.execute("help") - message.should eql help_text + expect(message).to eql help_text end end end @@ -135,10 +135,10 @@ context "when the slide contains a run command only" do it "should execute the command" do command_line_helper = CommandLineHelper.capture_output - @helper.start_presentation("echo hello world") do |commits, presenter| + @helper.start_presentation([:run => "echo hello world"]) do |commits, presenter| presenter.execute("next") presenter.execute("next") - presenter.execute("next").strip.should eql "hello world" + expect(presenter.execute("next").strip).to eql "hello world" end end end @@ -146,9 +146,9 @@ context "when the slide has a commit and a run command" do it "should checkout the commit and then execute the command" do command_line_helper = CommandLineHelper.capture_output - @helper.start_presentation("echo hello world", 2) do |commits, presenter| + @helper.start_presentation([:run => "echo hello world",:on_slide => 2]) do |commits, presenter| presenter.execute("next") - presenter.execute("next").should eql "#{commits[2].message}\nhello world\n" + expect(presenter.execute("next")).to eql "#{commits[2].message}\nhello world\n" end end end @@ -158,7 +158,38 @@ command_line_helper = CommandLineHelper.capture_output @helper.start_presentation do |commits, presenter| presenter.execute("!echo hello world") - command_line_helper.command_output.strip.should end_with "hello world" + expect(command_line_helper.command_output.strip).to end_with "hello world" + end + end + end + + context "when opening an application" do + it "should open the with launchy" do + command_line_helper = CommandLineHelper.capture_output + @helper.start_presentation([:launch => 'readme', :on_slide => 2]) do |commits, presenter| + expect(Launchy).to receive(:open).with('readme').once + presenter.execute("next") + presenter.execute("next") + end + end + end + + context "when exiting a presentation" do + it "should set the repo back to the master branch" do + @helper.start_presentation do |commits, presenter| + presenter.execute("next") + presenter.execute("exit") + expect(@helper.current_branch).not_to be_nil + expect(@helper.current_branch).to eql "master" + end + end + end + + context "when running in command mode" do + it "should set the current slide to commit" do + @helper.start_presentation([], 1) do |commits, presenter| + presenter.execute("list") + expect(presenter.current_slide.commit).to eql commits[1].sha end end end diff --git a/spec/integration/start_presentation_spec.rb b/spec/integration/start_presentation_spec.rb index 150e163..b820638 100644 --- a/spec/integration/start_presentation_spec.rb +++ b/spec/integration/start_presentation_spec.rb @@ -13,32 +13,32 @@ Dir.chdir(presentation_dir) do presenter = GitPresenter.new(".", false) presentation = presenter.execute('start') - presentation.slides.length.should eql 4 + expect(presentation.slides.length).to eql 4 end end it "first commit should be first commit in file" do @helper.start_presentation do |commits, presenter| - presenter.slides[0].commit.should eql commits[0].id + expect(presenter.slides[0].commit).to eql commits[0].sha end end it "second commit should be second commit in file" do @helper.start_presentation do |commits, presenter| - presenter.slides[1].commit.should eql commits[1].id + expect(presenter.slides[1].commit).to eql commits[1].sha end end it "the last commit should be a command" do command = "echo hello world" - @helper.start_presentation(command) do |commits, presenter| - presenter.slides[3].run.should eql command + @helper.start_presentation([:run => command]) do |commits, presenter| + expect(presenter.slides[3].run).to eql command end end it "should have the presentation at first commit" do @helper.start_presentation do |commits, presenter| - @helper.head_position.should eql commits.first.id + expect(@helper.head_position).to eql commits.first.sha end end end diff --git a/spec/integration/update_presentation_spec.rb b/spec/integration/update_presentation_spec.rb index 1e2507c..fafb4d6 100644 --- a/spec/integration/update_presentation_spec.rb +++ b/spec/integration/update_presentation_spec.rb @@ -10,7 +10,7 @@ commits = @helper.initialise_presentation({:delay => true}) new_commit = @helper.edit_file_and_commit("forth commit", "d") @helper.update_presentation do |yaml| - yaml["slides"].length.should eql (commits.length + 1) + expect(yaml["slides"].length).to eql (commits.length + 1) end end @@ -18,7 +18,7 @@ commits = @helper.initialise_presentation({:delay => true}) new_commit = @helper.edit_file_and_commit("forth commit", "d") @helper.update_presentation do |yaml| - yaml["slides"].last["slide"]["commit"].should eql new_commit.id + expect(yaml["slides"].last["slide"]["commit"]).to eql new_commit.sha end end @@ -27,7 +27,7 @@ removed_commit = @helper.remove_from_presentation_at(1) new_commit = @helper.edit_file_and_commit("forth commit", "d") @helper.update_presentation do |yaml| - yaml["slides"].length.should eql (commits.length) + expect(yaml["slides"].length).to eql (commits.length) end end @@ -36,7 +36,7 @@ removed_commit = @helper.remove_from_presentation_at(1) new_commit = @helper.edit_file_and_commit("forth commit", "d") @helper.update_presentation - @command_line.command_output.should include "Your presentation has been updated" + expect(@command_line.command_output).to include "Your presentation has been updated" end end diff --git a/spec/lib/git_presenter/presentation_spec.rb b/spec/lib/git_presenter/presentation_spec.rb index 5a24142..c40ef5c 100644 --- a/spec/lib/git_presenter/presentation_spec.rb +++ b/spec/lib/git_presenter/presentation_spec.rb @@ -1,24 +1,37 @@ require "spec_helper" +class FakeShell + attr_reader :ran_commands + def initialize() + @ran_commands = [] + end + def run(command) + @ran_commands << command + end +end describe GitPresenter::Presentation do let(:presentation){ {"slides" => [ {"slide" => {"commit" => "0"}}, {"slide" => {"commit" => "1"}}, - {"slide" => {"commit" => "2"}}] + {"slide" => {"commit" => "2"}}], + "branch" => "test" } } + let(:fake_shell){ FakeShell.new } context "when displaying the command line" do it "should display the current position" do - presenter = GitPresenter::Presentation.new(presentation) - presenter.status_line.should eql "1/3 >" + fake_shell.should_receive(:run).with("git rev-parse HEAD").and_return("0") + presenter = GitPresenter::Presentation.new(presentation, fake_shell) + expect(presenter.status_line).to eql "1/3 >" end end context "when calculating the position" do it "should return the index of the current commit" do - presenter = GitPresenter::Presentation.new(presentation) - presenter.position.should eql 0 + expect(fake_shell).to receive(:run).with("git rev-parse HEAD").and_return("0") + presenter = GitPresenter::Presentation.new(presentation, fake_shell) + expect(presenter.position).to eql 0 end end @@ -29,59 +42,70 @@ def given_command(command) end context "with bash command" do - it { given_command("!echo hello world").should eql :command } + it { expect(given_command("!echo hello world")).to eql :command } end context "with next" do - it { given_command("next").should eql :next } + it { expect(given_command("next")).to eql :next } end context "with next" do - it { given_command("n").should eql :next } + it { expect(given_command("n")).to eql :next } end context "with back" do - it { given_command("back").should eql :previous } + it { expect(given_command("back")).to eql :previous } end context "with b" do - it { given_command("b").should eql :previous } + it { expect(given_command("b")).to eql :previous } end context "with start" do - it { given_command("start").should eql :start } + it { expect(given_command("start")).to eql :start } end context "with s" do - it { given_command("s").should eql :start } + it { expect(given_command("s")).to eql :start } end context "with end" do - it { given_command("end").should eql :end } + it { expect(given_command("end")).to eql :end } end context "with e" do - it { given_command("e").should eql :end } + it { expect(given_command("e")).to eql :end } end context "with list" do - it { given_command("list").should eql :list } + it { expect(given_command("list")).to eql :list } end context "with l" do - it { given_command("l").should eql :list } + it { expect(given_command("l")).to eql :list } end context "with any number" do - it { given_command("6").should eql :commit} + it { expect(given_command("6")).to eql :commit} end context "with h" do - it { given_command("h").should eql :help} + it { expect(given_command("h")).to eql :help} end context "with help" do - it { given_command("help").should eql :help} + it { expect(given_command("help")).to eql :help} + end + + context "with exit" do + it { given_command("exit").should eql :exit} + it 'checks out to the correct branch' do + presenter = GitPresenter::Presentation.new(presentation) + + expect(presenter).to receive(:'`').with("git checkout -q #{presentation['branch']}") + + presenter.exit + end end end end diff --git a/spec/lib/git_presenter/slide_spec.rb b/spec/lib/git_presenter/slide_spec.rb index 79f5d54..b4bff4f 100644 --- a/spec/lib/git_presenter/slide_spec.rb +++ b/spec/lib/git_presenter/slide_spec.rb @@ -4,12 +4,12 @@ context "when displaying as string" do it "should write out the commit id and the message" do slide = GitPresenter::Slide.new({"commit" => "012345678901234567890","message" => "message"}) - slide.to_s.should eql "0123456789, message" + expect(slide.to_s).to eql "0123456789, message" end it "should not blow up if no command exists" do slide = GitPresenter::Slide.new({"run" => "echo hello world"}) - slide.to_s.should eql "run: echo hello world" + expect(slide.to_s).to eql "run: echo hello world" end end @@ -18,7 +18,7 @@ it "should run that command" do command_line_helper = CommandLineHelper.capture_output slide = GitPresenter::Slide.new({"run" => "echo hello world"}) - slide.execute.strip.should eql "hello world" + expect(slide.execute.strip).to eql "hello world" end end @@ -27,7 +27,24 @@ command_line_helper = CommandLineHelper.capture_output slide = GitPresenter::Slide.new({"commit" => "number", "message" => "checkout", "run" => "echo hello world"}) slide.stub(:checkout).and_return("checkout\n") - slide.execute.should eql "checkout\nhello world\n" + expect(slide.execute).to eql "checkout\nhello world\n" + end + end + + context "when slide contains a launch command" do + it "should launch the application for the file type" do + command_line_helper = CommandLineHelper.capture_output + expect(Launchy).to receive(:open).with("readme").once + slide = GitPresenter::Slide.new({"launch" => "readme"}) + slide.execute + end + + it "should not try and launch if no launch supplied" do + command_line_helper = CommandLineHelper.capture_output + expect(Launchy).to receive(:open).with("readme").never + slide = GitPresenter::Slide.new({"commit" => "number", "message" => "checkout", "run" => "echo hello world"}) + slide.stub(:checkout).and_return("checkout\n") + expect(slide.execute).to eql "checkout\nhello world\n" end end @@ -36,7 +53,7 @@ command_line_helper = CommandLineHelper.capture_output slide = GitPresenter::Slide.new({"commit" => "number", "message" => "checkout"}) slide.stub(:checkout).and_return("checkout\n") - slide.execute.should eql "checkout\n" + expect(slide.execute).to eql "checkout\n" end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0fffbba..8a26d3d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,5 @@ require 'rspec' +require 'pry' require "support/git_helpers" require "support/command_line_helper" require_relative "../lib/git_presenter" diff --git a/spec/support/git_helpers.rb b/spec/support/git_helpers.rb index bbe4b0d..547320b 100644 --- a/spec/support/git_helpers.rb +++ b/spec/support/git_helpers.rb @@ -16,10 +16,10 @@ def initialise_test_repo(presentation_dir, delay, no_of_commits) content = ('a'..'z').to_a Dir.mkdir(presentation_dir) Dir.chdir(presentation_dir) do - @git_repo = Grit::Repo.init(".") + @git_repo = Git.init(".") (1..no_of_commits).each do |n| - edit_file_and_commit("commit number #{n}", content[n]) - commits << @git_repo.commits[0] + commit = edit_file_and_commit("commit number #{n}", content[n]) + commits << commit #need to make it sleep for a second. #git is not accurate enough with the speed of the test #to sort correctly only when required @@ -40,7 +40,7 @@ def edit_file_and_commit(commit_message, content) edit_file(content) @git_repo.add(".") @git_repo.commit_all(commit_message) - @git_repo.commits[0] + @git_repo.log.to_a[0] end def setup_presentation_file(commits) @@ -56,7 +56,7 @@ def clean_up_repo(dir) end def head_position - File.open(@presentation_dir + '/.git/HEAD').lines.first.strip + File.open(@presentation_dir + '/.git/HEAD').each_line.first.strip end def initialise_presentation(params={}) @@ -71,12 +71,17 @@ def initialise_presentation(params={}) commits end - def start_presentation(command="", add_command_to_commit=nil) + def start_presentation(commands=[], start_slide=0) commits = initialise_presentation({:delay => true}) Dir.chdir(@presentation_dir) do - add_command(command, add_command_to_commit) unless command.empty? + add_commands(commands) unless commands.empty? + if start_slide != 0 + `git checkout -q #{commits[start_slide]}` + end presenter = GitPresenter.new('.', false) - presenter = presenter.execute('start') + if start_slide == 0 + presenter = presenter.execute('start') + end yield(commits, presenter) if block_given? end end @@ -102,6 +107,31 @@ def remove_from_presentation_at(index) removed_commit end + def add_commands(commands) + commands.each do |command| + if command.include?(:run) + add_command(command[:run], command[:on_slide]) + end + if command.include?(:launch) + add_launch(command[:launch], command[:on_slide]) + end + end + end + + def add_launch(command, add_command_to_commit=nil) + Dir.chdir(PRESENTATION_DIR) do + presentation = YAML.parse(File.open(".presentation")).to_ruby + if !add_command_to_commit.nil? + presentation["slides"][add_command_to_commit]["slide"]["launch"] = command + else + presentation["slides"] << {"slide" => {"launch" => command}} + end + File.open(".presentation", "w") do |file| + file.write(presentation.to_yaml) + end + end + end + def add_command(command, add_command_to_commit=nil) Dir.chdir(PRESENTATION_DIR) do presentation = YAML.parse(File.open(".presentation")).to_ruby @@ -115,4 +145,12 @@ def add_command(command, add_command_to_commit=nil) end end end + + def current_branch + Dir.chdir(PRESENTATION_DIR) do + repo = Git.open('.') + repo.current_branch + end + end + end