wassup 0.1.2 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/Gemfile.lock +19 -1
  4. data/README.md +19 -13
  5. data/bin/wassup +6 -1
  6. data/docs/.gitignore +20 -0
  7. data/docs/README.md +41 -0
  8. data/docs/babel.config.js +3 -0
  9. data/docs/blog/2021-12-09-welcome/index.md +8 -0
  10. data/docs/blog/authors.yml +5 -0
  11. data/docs/docs/Supfile-basics/_category_.json +4 -0
  12. data/docs/docs/Supfile-basics/understanding-the-supfile.md +50 -0
  13. data/docs/docs/intro.md +54 -0
  14. data/docs/docusaurus.config.js +110 -0
  15. data/docs/package-lock.json +21196 -0
  16. data/docs/package.json +43 -0
  17. data/docs/sidebars.js +31 -0
  18. data/docs/src/components/HomepageFeatures.module.css +10 -0
  19. data/docs/src/components/HomepageFeatures.tsx +60 -0
  20. data/docs/src/css/custom.css +28 -0
  21. data/docs/src/pages/index.module.css +36 -0
  22. data/docs/src/pages/index.tsx +39 -0
  23. data/docs/src/pages/markdown-page.md +7 -0
  24. data/docs/static/.nojekyll +0 -0
  25. data/docs/static/img/demo-supfile.png +0 -0
  26. data/docs/static/img/favicon.ico +0 -0
  27. data/docs/static/img/logo.svg +27 -0
  28. data/docs/static/img/tutorial/docsVersionDropdown.png +0 -0
  29. data/docs/static/img/tutorial/localeDropdown.png +0 -0
  30. data/docs/static/img/tutorial-intro-starter-screenshot.png +0 -0
  31. data/docs/static/img/undraw_docusaurus_mountain.svg +170 -0
  32. data/docs/static/img/undraw_docusaurus_react.svg +169 -0
  33. data/docs/static/img/undraw_docusaurus_tree.svg +1 -0
  34. data/docs/static/img/wassup-long.png +0 -0
  35. data/docs/static/img/wassup-screenshot.png +0 -0
  36. data/docs/static/img/wassup.png +0 -0
  37. data/docs/static/video/wassup-demo.mov +0 -0
  38. data/docs/tsconfig.json +7 -0
  39. data/examples/basic/Supfile +183 -16
  40. data/examples/debug/Supfile +90 -13
  41. data/examples/josh-fastlane/Supfile +61 -117
  42. data/examples/simple/Supfile +17 -0
  43. data/examples/starter/Supfile +44 -0
  44. data/lib/wassup/app.rb +167 -6
  45. data/lib/wassup/color.rb +5 -0
  46. data/lib/wassup/helpers/circleci.rb +75 -0
  47. data/lib/wassup/helpers/github.rb +137 -0
  48. data/lib/wassup/helpers/netlify.rb +70 -0
  49. data/lib/wassup/helpers/shortcut.rb +114 -0
  50. data/lib/wassup/pane.rb +244 -134
  51. data/lib/wassup/pane_builder.rb +60 -1
  52. data/lib/wassup/version.rb +1 -1
  53. data/lib/wassup.rb +5 -0
  54. data/wassup.gemspec +1 -0
  55. metadata +55 -2
@@ -0,0 +1,137 @@
1
+ module Wassup
2
+ module Helpers
3
+ module GitHub
4
+ require 'json'
5
+ require 'rest-client'
6
+
7
+ # https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests
8
+ def self.issues(org:, repo:nil, q: nil)
9
+ q_parts = []
10
+
11
+ if repo.nil?
12
+ q_parts << "org:#{org}"
13
+ else
14
+ q_parts << "repo:#{org}/#{repo}"
15
+ end
16
+
17
+ if q
18
+ q_parts << q
19
+ end
20
+
21
+ q = q_parts.join(' ')
22
+
23
+ items = []
24
+
25
+ resp = RestClient::Request.execute(
26
+ method: :get,
27
+ url: "https://api.github.com/search/issues?q=#{q}",
28
+ user: ENV["WASSUP_GITHUB_USERNAME"],
29
+ password: ENV["WASSUP_GITHUB_ACCESS_TOKEN"],
30
+ headers: { "Accept": "application/vnd.github.v3+json", "Content-Type": "application/json" },
31
+ )
32
+ partial_items = JSON.parse(resp)["items"]
33
+ items += partial_items
34
+
35
+ return items
36
+ end
37
+
38
+ def self.repos(org:)
39
+ resp = RestClient::Request.execute(
40
+ method: :get,
41
+ url: "https://api.github.com/orgs/#{org}/repos",
42
+ user: ENV["WASSUP_GITHUB_USERNAME"],
43
+ password: ENV["WASSUP_GITHUB_ACCESS_TOKEN"]
44
+ )
45
+ return JSON.parse(resp)
46
+ end
47
+
48
+ Repo = Struct.new(:org, :repo)
49
+ def self.pull_requests(org:, repo: nil)
50
+ repos = []
51
+ if repo.nil?
52
+ repos += self.repos(org: org).map do |repo|
53
+ Repo.new(org, repo["name"])
54
+ end
55
+ else
56
+ repos << Repo.new(org, repo)
57
+ end
58
+
59
+ return repos.map do |repo|
60
+ resp = RestClient::Request.execute(
61
+ method: :get,
62
+ url: "https://api.github.com/repos/#{repo.org}/#{repo.repo}/pulls?per_page=100",
63
+ user: ENV["WASSUP_GITHUB_USERNAME"],
64
+ password: ENV["WASSUP_GITHUB_ACCESS_TOKEN"]
65
+ )
66
+
67
+ JSON.parse(resp)
68
+ end.flatten(1)
69
+ end
70
+
71
+ def self.releases(org:, repo:)
72
+ resp = RestClient::Request.execute(
73
+ method: :get,
74
+ url: "https://api.github.com/repos/#{org}/#{repo}/releases",
75
+ user: ENV["WASSUP_GITHUB_USERNAME"],
76
+ password: ENV["WASSUP_GITHUB_ACCESS_TOKEN"]
77
+ )
78
+
79
+ return JSON.parse(resp)
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ module Wassup
86
+ module Helpers
87
+ module GitHub
88
+ module Formatter
89
+ def self.issue(issue, show_repo: false, show_interactions: false)
90
+ self.pr(issue, show_repo: show_repo, show_interactions: show_interactions)
91
+ end
92
+
93
+ def self.pr(pr, show_repo: false, show_interactions: false)
94
+ number = pr["number"]
95
+ title = pr["title"]
96
+ created_at = pr["created_at"]
97
+
98
+ repo_name = ""
99
+ if show_repo
100
+ repo_url_parts = pr["repository_url"].split("/")
101
+ repo_name = "[fg=gray]#{repo_url_parts.last} "
102
+ end
103
+
104
+ interactions = ""
105
+ if show_interactions
106
+ interaction_count = pr["comments"] + pr["reactions"]["total_count"]
107
+ interactions = "[fg=red]#{interaction_count} "
108
+ end
109
+
110
+ number_formatted = '%-7.7s' % "##{number}"
111
+
112
+ date = Time.parse(created_at)
113
+ days = (Time.now - date).to_i / (24 * 60 * 60)
114
+ days_formatted = '%3.3s' % days.to_s
115
+
116
+ display = "[fg=yellow]#{number_formatted}[fg=cyan] #{days_formatted}d ago #{interactions}#{repo_name}[fg=white]#{title}"
117
+
118
+ return display
119
+ end
120
+
121
+ def self.release(release)
122
+ tag_name = release["tag_name"]
123
+ name = release["name"]
124
+ published_at = release["published_at"]
125
+
126
+ date = Time.parse(published_at)
127
+ days = (Time.now - date).to_i / (24 * 60 * 60)
128
+ days_formatted = '%3.3s' % days.to_s
129
+
130
+ display = "[fg=yellow]#{tag_name} [fg=cyan]#{days_formatted} ago [fg=gray]#{name}"
131
+
132
+ return display
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,70 @@
1
+ module Wassup
2
+ module Helpers
3
+ module Netlify
4
+ require 'json'
5
+ require 'rest-client'
6
+
7
+ def self.deploys(site_id:)
8
+ resp = RestClient::Request.execute(
9
+ method: :get,
10
+ url: "https://api.netlify.com/api/v1/sites/#{site_id}/deploys",
11
+ headers: { "Authorization": "Bearer #{ENV['WASSUP_NETLIFY_TOKEN']}", "User-Agent": "Wassup" }
12
+ )
13
+ return JSON.parse(resp)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+
20
+ module Wassup
21
+ module Helpers
22
+ module Netlify
23
+ module Formatter
24
+ def self.deploy(deploy)
25
+ review_id = deploy["review_id"]
26
+ context = deploy["context"]
27
+ state = deploy["state"]
28
+ error_message = deploy["error_message"]
29
+ branch = deploy["branch"]
30
+ commit_ref = deploy["commit_ref"] || "HEAD"
31
+ url = deploy["deploy_url"]
32
+
33
+ if error_message.to_s.downcase.include?("canceled")
34
+ state = "cancelled"
35
+ end
36
+
37
+ color = "green"
38
+ if state == "building"
39
+ color = "yellow"
40
+ elsif state == "enqueued"
41
+ color = "magenta"
42
+ elsif state == "cancelled"
43
+ color = "gray"
44
+ elsif state == "error"
45
+ color = "red"
46
+ end
47
+
48
+ display_context = context.split('-').map(&:capitalize).join(' ')
49
+ display_context = "[fg=#{color}]#{display_context}"
50
+
51
+ if !review_id.nil?
52
+ display_context += " - ##{review_id}"
53
+ end
54
+
55
+ display_context += "[fg=gray]"
56
+ display_context += " (#{state})"
57
+ display_context += "[fg=white]"
58
+
59
+ if !branch.nil? && !commit_ref.nil?
60
+ display_context += "[fg=cyan]: #{branch}@#{commit_ref[0...7]}"
61
+ end
62
+
63
+ display = "#{display_context}"
64
+
65
+ return display
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,114 @@
1
+ module Wassup
2
+ module Helpers
3
+ module Shortcut
4
+ require 'json'
5
+ require 'rest-client'
6
+
7
+ def self.members
8
+ endpoint = "https://api.app.shortcut.com"
9
+ resp = RestClient::Request.execute(
10
+ method: :get,
11
+ url: "#{endpoint}/api/v3/members",
12
+ headers: { "Shortcut-Token": ENV['WASSUP_SHORTCUT_TOKEN'], "Content-Type": "application/json" }
13
+ )
14
+ return JSON.parse(resp)
15
+ end
16
+
17
+ def self.workflows
18
+ endpoint = "https://api.app.shortcut.com"
19
+ resp = RestClient::Request.execute(
20
+ method: :get,
21
+ url: "#{endpoint}/api/v3/workflows",
22
+ headers: { "Shortcut-Token": ENV['WASSUP_SHORTCUT_TOKEN'], "Content-Type": "application/json" }
23
+ )
24
+ return JSON.parse(resp)
25
+ end
26
+
27
+ def self.search_stories(query:, page_size: 25)
28
+ endpoint = "https://api.app.shortcut.com"
29
+
30
+ members = self.members
31
+ workflows = self.workflows
32
+
33
+ stories = []
34
+
35
+ resp = RestClient::Request.execute(
36
+ method: :get,
37
+ url: "#{endpoint}/api/v3/search/stories",
38
+ payload: { page_size: page_size, query: query },
39
+ headers: { "Shortcut-Token": ENV['WASSUP_SHORTCUT_TOKEN'], "Content-Type": "application/json" }
40
+ )
41
+ json = JSON.parse(resp)
42
+ stories += json["data"]
43
+
44
+ next_url = json["next"]
45
+ while !next_url.nil?
46
+ resp = RestClient::Request.execute(
47
+ method: :get,
48
+ url: "#{endpoint}#{next_url}",
49
+ headers: { "Shortcut-Token": ENV['WASSUP_SHORTCUT_TOKEN'], "Content-Type": "application/json" }
50
+ )
51
+ json = JSON.parse(resp)
52
+ stories += json["data"]
53
+ next_url = json["next"]
54
+ end
55
+
56
+ stories = stories.map do |story|
57
+ story["followers"] = story["follower_ids"].map do |owner_id|
58
+ members.find do |member|
59
+ member["id"] == owner_id
60
+ end
61
+ end
62
+
63
+ story["owners"] = story["owner_ids"].map do |owner_id|
64
+ members.find do |member|
65
+ member["id"] == owner_id
66
+ end
67
+ end
68
+
69
+ if (workflow_id = story["workflow_id"]) && (workflow_state_id = story["workflow_state_id"])
70
+ workflow = workflows.find do |workflow|
71
+ workflow["id"] == workflow_id
72
+ end
73
+
74
+ story["workflow"] = workflow
75
+ if workflow
76
+ story["workflow_state"] = workflow["states"].find do |workflow_state|
77
+ workflow_state["id"] == workflow_state_id
78
+ end
79
+ end
80
+ end
81
+
82
+ story
83
+ end
84
+
85
+ return stories
86
+ end
87
+
88
+ end
89
+ end
90
+ end
91
+
92
+ module Wassup
93
+ module Helpers
94
+ module Shortcut
95
+ module Formatter
96
+ def self.story(story)
97
+ id = story["id"]
98
+ name = story["name"]
99
+ state = story["workflow_state"]["name"]
100
+
101
+ mention_name = (story["owners"] || {}).map do |member|
102
+ member["profile"]["mention_name"]
103
+ end.join(", ")
104
+
105
+ id_formatted = '%-7.7s' % "##{id}"
106
+
107
+ display = "[fg=yellow]#{id_formatted} [fg=cyan]#{state} [fg=white]#{mention_name} [fg=gray]#{name}"
108
+
109
+ return display
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end