batcave 0.0.9 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a25e16c495db47fa2c3282ecca632718045bc953
4
+ data.tar.gz: b37c25923e024cb02ce42f67cc91f249da7e844b
5
+ SHA512:
6
+ metadata.gz: c39256bb430dd27a3bab682a63a0721ff855ed210336b06b54528d38086b2fc151b384d15c589d66cb85a3c84e70bc14a7223520f18f4cc846b8dcc09f46e483
7
+ data.tar.gz: 9ce8d3bce04ca99686e88adf9840216a80c391d0ac44d17456d7fafc9e2c3cbb012ca754bdb56f720634eebec016b53e05893d95e71ebb8737b55d17d1019351
data/Gemfile CHANGED
@@ -1,4 +1,2 @@
1
- source :rubygems
2
-
3
- gem "clamp"
4
- gem "cabin"
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -1,10 +1,20 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ batcave (0.0.10)
5
+ cabin
6
+ clamp
7
+ stud (>= 0.0.14)
8
+
1
9
  GEM
2
- remote: http://rubygems.org/
10
+ remote: https://rubygems.org/
3
11
  specs:
4
- clamp (0.3.0)
12
+ cabin (0.6.1)
13
+ clamp (0.6.3)
14
+ stud (0.0.18)
5
15
 
6
16
  PLATFORMS
7
17
  ruby
8
18
 
9
19
  DEPENDENCIES
10
- clamp
20
+ batcave!
@@ -2,7 +2,7 @@ Gem::Specification.new do |spec|
2
2
  files = %x{git ls-files}.split("\n")
3
3
 
4
4
  spec.name = "batcave"
5
- spec.version = "0.0.9"
5
+ spec.version = "0.0.11"
6
6
  spec.summary = "Experiments in tools, boilerplatery, debugging, etc."
7
7
  spec.description = spec.summary
8
8
  spec.add_dependency("clamp")
@@ -11,6 +11,8 @@ Gem::Specification.new do |spec|
11
11
  spec.bindir = "bin"
12
12
  spec.executables << "dk"
13
13
 
14
+ spec.add_dependency("stud", ">= 0.0.14")
15
+ spec.add_dependency("octokit")
14
16
  spec.author = "Jordan Sissel"
15
17
  spec.email = "jls@semicomplete.com"
16
18
  spec.homepage = "https://github.com/jordansissel/batcave"
data/bin/dk CHANGED
@@ -5,4 +5,4 @@ require "clamp"
5
5
 
6
6
  $: << File.join(File.dirname(__FILE__), "..", "lib")
7
7
  require "batcave/main"
8
- exit(BatCave::Main.run)
8
+ exit(BatCave::Main.run || 0)
@@ -0,0 +1,97 @@
1
+ require "clamp"
2
+ require "faraday"
3
+ require "json"
4
+ require "insist"
5
+ require "clamp"
6
+
7
+ class BatCave::Command::GithubIssueMilestone < Clamp::Command
8
+ option ["--log-level", "-l"], "LEVEL", "The log level. Default is 'warn'. Can be 'debug', 'info', 'warn', 'error'", :default => "warn" do |val|
9
+ insist { ["warn", "debug", "info", "error"] }.include?(val.downcase)
10
+ val.downcase.to_sym
11
+ end
12
+ option "--override", :flag, "Override milestone on an issue if one is already set.", :default => false
13
+
14
+ parameter "USER/PROJECT", "The user/project repo name on github.", :attribute_name => "repo"
15
+ parameter "ISSUE", "The issue number. Can be '-' to read issue numbers from stdin.", :attribute_name => :issue_number
16
+ parameter "MILESTONE", "The milestone to set", :attribute_name => :milestone_name
17
+
18
+ def logger
19
+ @logger ||= Cabin::Channel.get
20
+ end
21
+
22
+ def execute
23
+ logger.subscribe(STDOUT)
24
+ logger.level = log_level
25
+ logger[:repo] = repo
26
+ logger[:milestone] = milestone_name
27
+
28
+ # verify milestone exists
29
+ milestones = client.milestones(repo)
30
+ selector = proc { |m| m["title"] == milestone_name }
31
+ if milestones.none?(&selector)
32
+ raise "No such milestone '#{milestone_name}' found in #{repo}"
33
+ end
34
+ milestone_number = milestones.find(&selector)["number"]
35
+
36
+ logger.debug("Found milestone number", :number => milestone_number)
37
+
38
+ if issue_number == "-"
39
+ STDIN.each_line do |issue_number|
40
+ set_milestone(repo, issue_number.chomp, milestone_number)
41
+ end
42
+ else
43
+ set_milestone(repo, issue_number, milestone_number)
44
+ end
45
+ 0
46
+ rescue RuntimeError => e
47
+ puts "Error: #{e}"
48
+ 1
49
+ rescue => e
50
+ if logger.debug?
51
+ logger.error("An error occurred", :exception => e, :backtrace => e.backtrace)
52
+ else
53
+ logger.error("An error occurred", :exception => e)
54
+ end
55
+ 1
56
+ end # def execute
57
+
58
+ def set_milestone(repo, issue_number, milestone_number)
59
+ logger[:issue] = issue_number
60
+
61
+ # TODO(sissel): Verify issue exists
62
+ issue = client.issue(repo, issue_number)
63
+ if issue.milestone
64
+ if issue.milestone.title == milestone_name
65
+ logger.debug("Skipping because milestone is already set", :current_milestone => issue.milestone.title)
66
+ return
67
+ end
68
+ if issue.milestone.title != milestone_name
69
+ if override?
70
+ logger.info("Milestone already set on issue, but override is given, so I will override it.", :current_milestone => issue.milestone.title)
71
+ else
72
+ logger.info("Milestone already set on issue, skipping this issue.", :current_milestone => issue.milestone.title)
73
+ #raise "Milestone is already set on '#{repo}' issue #{issue_number}"
74
+ end
75
+ end
76
+ end
77
+ client.update_issue(repo, issue_number, issue.title, issue.body, :milestone => milestone_number)
78
+ logger.info("Updated issue milestone successfully", :repo => repo)
79
+ end # def execute
80
+
81
+ def client
82
+ # This requires you have ~/.netrc setup correctly
83
+ # I don't know if it works with 2FA
84
+ require "octokit"
85
+ @client ||= Octokit::Client.new(:netrc => true).tap do |client|
86
+ client.login
87
+ client.auto_paginate = true
88
+ end
89
+ end
90
+
91
+ def http
92
+ @http ||= Faraday.new(:url => "https://github.com") do |faraday|
93
+ faraday.request :url_encoded
94
+ faraday.adapter Faraday.default_adapter
95
+ end # http
96
+ end # def http
97
+ end # class BatCave::Command::GithubIssueMilestone
@@ -0,0 +1,63 @@
1
+ require "clamp"
2
+ require "batcave/namespace"
3
+ require "stud/temporary"
4
+
5
+ class BatCave::Command::SmartEdit < Clamp::Command
6
+ def execute
7
+ rspec_failure = /^ *Failure\/Error/
8
+ rspec_stack_trace = /^ *# (?<path>[^:]+):(?<line>[0-9]+):/
9
+ text = capture_tmux
10
+ if text =~ rspec_failure
11
+ lines = text.split("\n")
12
+ # first failure/error
13
+ index = lines.find_index { |l| l =~ rspec_failure }
14
+ # then find all lines that look like stack traces.
15
+ traces = []
16
+ last_line = index
17
+ lines[index..-1].each_with_index do |line, i|
18
+ m = rspec_stack_trace.match(line)
19
+ if m
20
+ traces << Hash[m.names.zip(m.captures)]
21
+ elsif traces.count > 0 && line =~ /^ *$/
22
+ # already found traces, and a blank line means the end of the trace.
23
+ last_line = i
24
+ break
25
+ end
26
+ end
27
+
28
+ if traces.any?
29
+ # Find the most-recently modified file.
30
+ candidate = traces.sort_by { |t| File.stat(t["path"]).mtime }.reverse.first
31
+ Stud::Temporary.file do |fd|
32
+ lines[index .. last_line + index].each do |line|
33
+ fd.puts(line)
34
+ end
35
+ fd.flush
36
+
37
+ system("tmux split-window -l 7 'cat #{fd.path}; sleep 3000 ' \\; last-pane")
38
+ system("#{ENV["EDITOR"]} #{candidate["path"]} +#{candidate["line"]}")
39
+ system("tmux last-pane \\; kill-pane")
40
+ end
41
+ end
42
+ end
43
+
44
+ return 0
45
+ end
46
+
47
+ def tmux?
48
+ return ENV["TMUX"]
49
+ end
50
+
51
+ def screen?
52
+ return ENV["STY"]
53
+ end
54
+
55
+ def capture_tmux
56
+ Stud::Temporary.file do |fd|
57
+ # Capture the current screen plus 50 lines of history
58
+ system("tmux capture-pane -S -50")
59
+ system("tmux save-buffer -b 0 #{fd.path}")
60
+ return fd.read
61
+ end
62
+ end
63
+ end
@@ -3,6 +3,8 @@ require "batcave/namespace"
3
3
  require "batcave/command/add"
4
4
  require "batcave/command/update"
5
5
  require "batcave/command/test"
6
+ require "batcave/command/smart-edit"
7
+ require "batcave/command/github-issue-milestone"
6
8
  require "cabin"
7
9
 
8
10
  class BatCave::Main < Clamp::Command
@@ -22,4 +24,9 @@ class BatCave::Main < Clamp::Command
22
24
 
23
25
  # Run a file's tests.
24
26
  subcommand "test", "Run the tests for a given file", BatCave::Command::Test
27
+
28
+ # Figure out what file to edit and do it.
29
+ subcommand "smart-edit", "Scan the screen for a file to edit", BatCave::Command::SmartEdit
30
+
31
+ subcommand "github-issue-milestone", "Set a milestone on an issue", BatCave::Command::GithubIssueMilestone
25
32
  end
metadata CHANGED
@@ -1,46 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: batcave
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
5
- prerelease:
4
+ version: 0.0.11
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jordan Sissel
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-10-18 00:00:00.000000000 Z
11
+ date: 2014-11-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: clamp
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: cabin
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: stud
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.0.14
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.0.14
55
+ - !ruby/object:Gem::Dependency
56
+ name: octokit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
44
67
  - !ruby/object:Gem::Version
45
68
  version: '0'
46
69
  description: Experiments in tools, boilerplatery, debugging, etc.
@@ -50,7 +73,7 @@ executables:
50
73
  extensions: []
51
74
  extra_rdoc_files: []
52
75
  files:
53
- - .gitignore
76
+ - ".gitignore"
54
77
  - Gemfile
55
78
  - Gemfile.lock
56
79
  - Makefile
@@ -59,6 +82,8 @@ files:
59
82
  - bin/dk
60
83
  - lib/batcave/action/add.rb
61
84
  - lib/batcave/command/add.rb
85
+ - lib/batcave/command/github-issue-milestone.rb
86
+ - lib/batcave/command/smart-edit.rb
62
87
  - lib/batcave/command/test.rb
63
88
  - lib/batcave/command/update.rb
64
89
  - lib/batcave/dsl.rb
@@ -81,27 +106,25 @@ files:
81
106
  - things/user.sh/THING
82
107
  homepage: https://github.com/jordansissel/batcave
83
108
  licenses: []
109
+ metadata: {}
84
110
  post_install_message:
85
111
  rdoc_options: []
86
112
  require_paths:
87
113
  - lib
88
114
  required_ruby_version: !ruby/object:Gem::Requirement
89
- none: false
90
115
  requirements:
91
- - - ! '>='
116
+ - - ">="
92
117
  - !ruby/object:Gem::Version
93
118
  version: '0'
94
119
  required_rubygems_version: !ruby/object:Gem::Requirement
95
- none: false
96
120
  requirements:
97
- - - ! '>='
121
+ - - ">="
98
122
  - !ruby/object:Gem::Version
99
123
  version: '0'
100
124
  requirements: []
101
125
  rubyforge_project:
102
- rubygems_version: 1.8.24
126
+ rubygems_version: 2.2.2
103
127
  signing_key:
104
- specification_version: 3
128
+ specification_version: 4
105
129
  summary: Experiments in tools, boilerplatery, debugging, etc.
106
130
  test_files: []
107
- has_rdoc: