bruw 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ module Bruw
6
+ module Commands
7
+ class Git < Thor
8
+ desc "open REMOTE", "Open current repository in browser"
9
+ long_desc <<-LONGDESC
10
+ Open current repository in browser
11
+
12
+ Default remote is Origin
13
+ LONGDESC
14
+ def open(remote = "origin")
15
+ raise StandardError, "Not in git repository" unless Bruw::Git.git?
16
+
17
+ path = Bruw::Git.find_path(remote)
18
+
19
+ current_branch = `git branch --show-current`
20
+ `open https://github.com/#{path}/tree/#{current_branch}`
21
+ rescue StandardError => e
22
+ puts e.message.colorize(:red)
23
+ end
24
+
25
+ desc "remotes", "Get all current git remotes"
26
+ long_desc <<-LONGDESC
27
+ Get all current git remotes
28
+ LONGDESC
29
+ def remotes
30
+ puts Bruw::Git.remotes
31
+ rescue StandardError => e
32
+ puts e.message.colorize(:red)
33
+ end
34
+
35
+ desc "add-remotes", "Add several remote at once"
36
+ long_desc <<-LONGDESC
37
+ Add several remote at once
38
+ LONGDESC
39
+ option :pattern, required: false, banner: "Specify repo name pattern to match", aliases: "-p", type: :string
40
+ option :without, required: false, banner: "Specify repo name pattern that must not match", aliases: "-w", type: :string
41
+ option :all, required: false, banner: "Disable selection and add all repos", aliases: "-a", type: :boolean, default: false
42
+ def add_remotes(owner = "OpenSourcePolitics")
43
+ unless Bruw::Git.cmd_exists?("gh")
44
+ raise StandardError, "Please install Github CLI for using this command
45
+
46
+ You can install it using brew
47
+
48
+ `brew install gh` or upgrade `brew upgrade gh`
49
+
50
+ This command needs at least v1.7.0 for command repo list (https://github.com/cli/cli/releases/tag/v1.7.0)
51
+ Official repository : https://github.com/cli/cli"
52
+ end
53
+ prompt = TTY::Prompt.new
54
+
55
+ remotes = Bruw::Git.repos(owner, options[:pattern], options[:without])
56
+
57
+ remotes = prompt.multi_select("Select the git remote you want to add", remotes) unless options[:all]
58
+
59
+ remotes.each do |remote|
60
+ `git remote add #{remote} git@github.com:#{owner}/#{remote}.git`
61
+ end
62
+ rescue StandardError => e
63
+ puts e.message.colorize(:red)
64
+ end
65
+
66
+ desc "branch REMOTE BRANCH", "Create branch and removes existing one"
67
+ long_desc <<-LONGDESC
68
+ This command allows to create locally the specified git branch for the given remote
69
+
70
+ It fetch the git remote and then DESTROY the existing branch
71
+ LONGDESC
72
+ def branch(remote, branch)
73
+ raise StandardError, "You have uncommitted work, please commit or stash work before" if Bruw::Git.local_changes?
74
+ raise StandardError, "Not in git repository" unless Bruw::Git.git?
75
+
76
+ Bruw::Git.fetch(remote)
77
+ puts Bruw::Git.branch(remote, branch)
78
+ rescue StandardError => e
79
+ puts e.message.colorize(:red)
80
+ end
81
+
82
+ desc "add-remote REPOSITORY", "Add new remote linked to github repository"
83
+ long_desc <<-LONGDESC
84
+ Add new remote linked to github repository
85
+ LONGDESC
86
+ option :owner, required: false, banner: "Owner of the specified remote", aliases: "-o", type: :string, default: "OpenSourcePolitics"
87
+ def add_remote(repository)
88
+ prompt = TTY::Prompt.new
89
+ path = "#{options[:owner]}/#{repository}"
90
+ return unless prompt.yes?("Adding remote #{repository} linked to repository : https://github.com/#{path}")
91
+
92
+ `git remote add #{repository} git@github.com:#{path}.git`
93
+ puts "Remote #{repository.colorize(:green)} successfully created"
94
+ rescue StandardError => e
95
+ puts e.message.colorize(:red)
96
+ end
97
+
98
+ desc "prune [PATTERN]", "Prune all git remotes"
99
+ long_desc <<-LONGDESC
100
+ This command will remove all git remotes except origin
101
+
102
+ Params:
103
+
104
+ PATTERN - String :: Allows to find remote where name begins by the PATTERN specified :: DEFAULT 'decidim-'
105
+ LONGDESC
106
+ option :interactive, required: false, banner: "Run in interactive mode", aliases: "-i", type: :boolean
107
+ def prune(pattern = "decidim-")
108
+ prompt = TTY::Prompt.new
109
+
110
+ remotes = Bruw::Git.remotes(pattern)
111
+
112
+ raise StandardError, "No git remotes to remove" unless remotes.count.positive?
113
+
114
+ if options[:interactive]
115
+ remotes = prompt.multi_select("Select the git remote to remove", remotes)
116
+ else
117
+ puts "Found remotes :"
118
+ puts remotes
119
+ end
120
+
121
+ raise StandardError, "bruw decidim prune canceled" unless prompt.yes?("Do you really want to prune #{remotes.count.to_s.colorize(:green)} remotes ?")
122
+
123
+ Bruw::Git.prune_remotes(remotes)
124
+ puts "Remotes successfully removed !".colorize(:green)
125
+ rescue StandardError => e
126
+ puts e.message.colorize(:red)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bruw
4
+ class Decidim
5
+ def self.version
6
+ raise StandardError, "Not in Decidim project" unless decidim_app?
7
+
8
+ current_version
9
+ end
10
+
11
+ # curl allows to curl a specific file in the target repository
12
+ # Params:
13
+ # settings : Hash
14
+ # owner : String - Repository owner
15
+ # repo : String - Repository name
16
+ # version : String - Specific Decidim version
17
+ # path : String - Target file relative path
18
+ def self.curl(settings = {})
19
+ base_url = github_repo_base(settings[:owner], settings[:repo], settings[:version])
20
+ uri = "#{base_url}/#{settings[:path]}"
21
+ content = curl_response parse_uri(uri)
22
+ raise StandardError, "No content for specified path : \n> #{uri}" if content.nil? || content.empty?
23
+
24
+ content
25
+ end
26
+
27
+ def self.parse_uri(uri)
28
+ URI.parse uri
29
+ end
30
+
31
+ def self.decidim_app?
32
+ !current_version.nil? && !current_version.empty?
33
+ end
34
+
35
+ def self.osp_app?
36
+ !Dir.exist?("decidim-core") && !Dir.exist?("decidim-admin") && !Dir.exist?("decidim-initiatives")
37
+ end
38
+
39
+ def self.github_repo_base(owner, repo, version)
40
+ owner = "decidim" if owner.nil? || owner.empty?
41
+ repo = "decidim" if repo.nil? || repo.empty?
42
+ version = "v#{current_version}" if version.nil? || version.empty?
43
+
44
+ "https://raw.githubusercontent.com/#{owner}/#{repo}/#{version}"
45
+ end
46
+
47
+ def self.current_version
48
+ lines = File.open("Gemfile.lock")
49
+ decidim_version = ""
50
+ lines.each do |line|
51
+ next unless /decidim \((?!=).+/i =~ line
52
+
53
+ idx = line.strip.chars.index("(")
54
+
55
+ decidim_version = line.strip[idx + 1..line.strip.size - 2] unless idx.nil?
56
+ end
57
+
58
+ decidim_version
59
+ end
60
+
61
+ def self.curl_response(uri)
62
+ response = Net::HTTP.get_response(uri)
63
+ response&.body if response.is_a?(Net::HTTPOK) && response.respond_to?(:body)
64
+ end
65
+ end
66
+ end
data/lib/bruw/git.rb ADDED
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bruw
4
+ class Git
5
+ # Returns a list of repos that match specified patterns pattern
6
+ def self.repos(owner, pattern = "", without = "")
7
+ cmd = "gh repo list #{owner}"
8
+ cmd = "#{cmd} | grep #{pattern}" unless pattern.nil? || pattern.empty?
9
+ cmd = "#{cmd} | grep -v #{without}" unless without.nil? || without.empty?
10
+
11
+ repos = `#{cmd}`.gsub!(/\s+/, " ").split
12
+
13
+ repos = repos.select do |repo|
14
+ repo.start_with?(owner)
15
+ end
16
+
17
+ repos.map do |repo|
18
+ repo.split("/")[1]
19
+ end
20
+ end
21
+
22
+ def self.remotes(pattern = "")
23
+ return `git remote` if pattern.empty?
24
+
25
+ `git remote | grep ^#{pattern}`.split
26
+ end
27
+
28
+ def self.find_path(remote)
29
+ path = `git remote -v | grep #{remote} | cut -d' ' -f1 | head -n1`.split
30
+ path[1].match?("https") ? path[1].split(":")[1].split("com/")[1].split(".")[0] : path[1].split(":")[1].split(".")[0]
31
+ end
32
+
33
+ def self.branch(remote, branch)
34
+ `git branch -D #{branch}` if branch_exists?(branch)
35
+ `git checkout #{remote}/#{branch} && git switch -c #{branch}`
36
+ end
37
+
38
+ def self.fetch(remote)
39
+ `git fetch #{remote}`
40
+ end
41
+
42
+ def self.prune_remotes(remotes)
43
+ raise StandardError, "An error occured, please check git remotes" if remotes.nil? || !remotes.respond_to?(:each)
44
+ raise StandardError, "No git remotes to prune" if remotes.empty?
45
+
46
+ remotes.each do |remote|
47
+ puts "Removing #{remote.colorize(:green)}..."
48
+ `git remote remove #{remote}`
49
+ end
50
+ end
51
+
52
+ def self.cmd_exists?(cmd)
53
+ !`which #{cmd}`.empty?
54
+ end
55
+
56
+ def self.git?
57
+ Dir.exist?(".git")
58
+ end
59
+
60
+ def self.branch_exists?(branch)
61
+ !`git branch --list #{branch}`.empty?
62
+ end
63
+
64
+ def self.local_changes?
65
+ !`git status`.match(/Changes not staged for commit:/).nil?
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bruw
4
+ VERSION = "0.1.1"
5
+ end
data/lib/bruw.rb ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "colorize"
4
+ require "net/http"
5
+ require "byebug"
6
+ require "thor"
7
+ require "tty-prompt"
8
+
9
+ require "bruw/version"
10
+ require "bruw/base"
11
+ require "bruw/decidim"
12
+ require "bruw/commands/decidim"
13
+ require "bruw/git"
14
+ require "bruw/commands/git"
15
+
16
+ module Bruw
17
+ class Error < StandardError; end
18
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bruw
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - quentinchampenois
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-11-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tty-prompt
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
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Bruw is a CLI designed to simplify daily tasks
70
+ email:
71
+ - 26109239+Quentinchampenois@users.noreply.github.com
72
+ executables:
73
+ - bruw
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".github/workflows/tests.yml"
78
+ - ".gitignore"
79
+ - ".rspec"
80
+ - ".rubocop.yml"
81
+ - ".ruby-version"
82
+ - ".travis.yml"
83
+ - CODE_OF_CONDUCT.md
84
+ - Gemfile
85
+ - Gemfile.lock
86
+ - LICENSE.txt
87
+ - Makefile
88
+ - README.md
89
+ - Rakefile
90
+ - bin/console
91
+ - bin/setup
92
+ - bruw.gemspec
93
+ - docs/how_to_add_subcommand.md
94
+ - docs/ideas.md
95
+ - docs/testing.md
96
+ - exe/bruw
97
+ - lib/bruw.rb
98
+ - lib/bruw/base.rb
99
+ - lib/bruw/cli.rb
100
+ - lib/bruw/commands/decidim.rb
101
+ - lib/bruw/commands/git.rb
102
+ - lib/bruw/decidim.rb
103
+ - lib/bruw/git.rb
104
+ - lib/bruw/version.rb
105
+ homepage: https://github.com/quentinchampenois/bruw
106
+ licenses:
107
+ - MIT
108
+ metadata:
109
+ homepage_uri: https://github.com/quentinchampenois/bruw
110
+ source_code_uri: https://github.com/quentinchampenois/bruw
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: 2.3.0
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubygems_version: 3.1.2
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Simple CLI for daily tasks
130
+ test_files: []