batcave 0.0.9 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +2 -4
- data/Gemfile.lock +13 -3
- data/batcave.gemspec +3 -1
- data/bin/dk +1 -1
- data/lib/batcave/command/github-issue-milestone.rb +97 -0
- data/lib/batcave/command/smart-edit.rb +63 -0
- data/lib/batcave/main.rb +7 -0
- metadata +42 -19
checksums.yaml
ADDED
@@ -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
data/Gemfile.lock
CHANGED
@@ -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:
|
10
|
+
remote: https://rubygems.org/
|
3
11
|
specs:
|
4
|
-
|
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
|
-
|
20
|
+
batcave!
|
data/batcave.gemspec
CHANGED
@@ -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.
|
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
@@ -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
|
data/lib/batcave/main.rb
CHANGED
@@ -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.
|
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:
|
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:
|
126
|
+
rubygems_version: 2.2.2
|
103
127
|
signing_key:
|
104
|
-
specification_version:
|
128
|
+
specification_version: 4
|
105
129
|
summary: Experiments in tools, boilerplatery, debugging, etc.
|
106
130
|
test_files: []
|
107
|
-
has_rdoc:
|