gb 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,45 @@
1
+ require 'sub_command'
2
+
3
+
4
+ module Gb
5
+
6
+ class Sync < SubCommand
7
+
8
+ self.summary = '更新工作分支代码'
9
+
10
+ self.description = <<-DESC
11
+ 根据yml配置,更新代码.
12
+ DESC
13
+
14
+ def run_in_workspace
15
+
16
+ remote = 'origin'
17
+ workspace_config = self.workspace_config
18
+
19
+ info "current work branch '#{workspace_config.workspace_branch}', remote branch '#{workspace_config.remote_branch}'."
20
+
21
+ self.gb_config.projects.each do |project|
22
+ project_path = File.expand_path(project.name, './')
23
+
24
+ if File.exist?(project_path)
25
+ info "sync project '#{project.name}'..."
26
+ g = Git.open(project_path)
27
+ if workspace_config.workspace_branch != g.current_branch
28
+ error "current branch is not work branch(#{workspace_config.workspace_branch})."
29
+ exit(1)
30
+ end
31
+ g.fetch(remote, :p => true, :t => true)
32
+ g.pull("origin", workspace_config.workspace_branch)
33
+ g.pull("origin", workspace_config.remote_branch)
34
+ puts
35
+
36
+ else
37
+ error "please run 'gb init first."
38
+ break
39
+ end
40
+
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,38 @@
1
+ require 'sub_command'
2
+
3
+
4
+ module Gb
5
+
6
+ class Workspace < SubCommand
7
+
8
+ self.summary = '查看当前工作区信息'
9
+
10
+ self.description = <<-DESC
11
+ 查看当前工作区信息.
12
+ DESC
13
+
14
+ def run_in_workspace
15
+
16
+ remote = 'origin'
17
+ workspace_config = self.workspace_config
18
+
19
+ info "current work branch '#{workspace_config.workspace_branch}'"
20
+ info "track remote branch '#{workspace_config.remote_branch}'."
21
+ puts
22
+
23
+ self.gb_config.projects.each do |project|
24
+ project_path = File.expand_path(project.name, './')
25
+
26
+ if File.exist?(project_path)
27
+ info "Project '#{project.name}'..."
28
+ g = Git.open(project_path)
29
+ info "current branch '#{g.current_branch}'."
30
+ else
31
+ error "please run 'gb init first."
32
+ break
33
+ end
34
+ end
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,73 @@
1
+ module Gb
2
+ class GbConfig
3
+
4
+ attr_reader :projects
5
+ attr_reader :gitlab
6
+ attr_reader :config_path
7
+
8
+ def initialize(config_path, node)
9
+ @config_path = config_path
10
+
11
+ gitlab = node['gitlab']
12
+ @gitlab = GitlabConfig.new(gitlab)
13
+
14
+ @projects = []
15
+ projects = node['projects']
16
+ if !projects.nil?
17
+ projects.each do |project|
18
+ projectConfig = ProjectConfig.new(project)
19
+ @projects << projectConfig
20
+ end
21
+ end
22
+ end
23
+
24
+ def self.load_file(config_path)
25
+ node = YAML.load_file(config_path)
26
+ GbConfig.new(config_path, node)
27
+ end
28
+
29
+ def self.load_yml(yml)
30
+ node = YAML.load(yml)
31
+ GbConfig.new(nil, node)
32
+ end
33
+
34
+ def to_dictionary
35
+ projects = self.projects.map do |project|
36
+ project.to_dictionary
37
+ end
38
+ {"projects"=>projects, "gitlab"=>self.gitlab.to_dictionary}
39
+ end
40
+
41
+ class ProjectConfig
42
+ attr_reader :name
43
+ attr_reader :git
44
+
45
+ def initialize(node)
46
+ @name = node['name']
47
+ @git = node['git']
48
+ end
49
+
50
+ def to_dictionary
51
+ {"name"=>self.name, "git"=>self.git}
52
+ end
53
+
54
+ end
55
+
56
+ class GitlabConfig
57
+ attr_reader :endpoint
58
+ attr_accessor :private_token
59
+
60
+ def initialize(node)
61
+ @endpoint = node['endpoint']
62
+ @private_token = node['private_token']
63
+ end
64
+
65
+ def to_dictionary
66
+ {"endpoint"=>self.endpoint, "private_token"=>private_token}
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+ end
73
+
@@ -0,0 +1,25 @@
1
+
2
+ module Gb
3
+ class WorkSpaceConfig
4
+ attr_reader :remote_branch
5
+ attr_reader :workspace_branch
6
+
7
+ def initialize(remote_branch, workspace_branch)
8
+ @remote_branch = remote_branch
9
+ @workspace_branch = workspace_branch
10
+ end
11
+
12
+ def self.load_file(yaml_filename)
13
+ node = YAML.load_file(yaml_filename)
14
+ remote_branch = node['remote_branch']
15
+ workspace_branch = node['workspace_branch']
16
+ return WorkSpaceConfig.new(remote_branch, workspace_branch)
17
+ end
18
+
19
+ def save(path)
20
+ File.open(path, 'w') do |file|
21
+ Psych.dump({'remote_branch' => @remote_branch, 'workspace_branch' => @workspace_branch}, file)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,120 @@
1
+ require 'git'
2
+
3
+
4
+ module Git
5
+ def self.clone_without_env(repository, name, opts = {})
6
+ opts = Git::Lib.new.clone_without_env(repository, name, opts)
7
+ Base.new(opts)
8
+ end
9
+ end
10
+
11
+ module Patches
12
+ module Git
13
+
14
+ module Base
15
+
16
+ def track(remote, branch)
17
+ self.lib.track(remote, branch)
18
+ end
19
+
20
+ end
21
+ module Lib
22
+ def initialize(*args)
23
+ super
24
+ # @logger = Logger.new(STDOUT)
25
+ end
26
+
27
+ def run_command(git_cmd, &block)
28
+ git_cmd = git_cmd.gsub(/2>&1$/, '')
29
+ return IO.popen(git_cmd, &block) if block_given?
30
+
31
+ `#{git_cmd}`.chomp
32
+ end
33
+
34
+ def track(remote, branch)
35
+ arr_opts = []
36
+ arr_opts << '-u'
37
+ arr_opts << "#{remote}/#{branch}"
38
+ command('branch', arr_opts)
39
+ end
40
+
41
+ def clone_without_env(repository, name, opts = {})
42
+ @path = opts[:path] || '.'
43
+ clone_dir = opts[:path] ? File.join(@path, name) : name
44
+
45
+ arr_opts = []
46
+ arr_opts << '--bare' if opts[:bare]
47
+ arr_opts << '--branch' << opts[:branch] if opts[:branch]
48
+ arr_opts << '--depth' << opts[:depth].to_i if opts[:depth] && opts[:depth].to_i > 0
49
+ arr_opts << '--config' << opts[:gitl_config] if opts[:gitl_config]
50
+ arr_opts << '--origin' << opts[:remote] || opts[:origin] if opts[:remote] || opts[:origin]
51
+ arr_opts << '--recursive' if opts[:recursive]
52
+ arr_opts << "--mirror" if opts[:mirror]
53
+
54
+ arr_opts << '--'
55
+
56
+ arr_opts << repository
57
+ arr_opts << clone_dir
58
+
59
+ command_without_env('clone', arr_opts)
60
+
61
+ (opts[:bare] or opts[:mirror]) ? {:repository => clone_dir} : {:working_directory => clone_dir}
62
+ end
63
+
64
+ def command_without_env(cmd, opts = [], chdir = true, redirect = '', &block)
65
+ global_opts = []
66
+ global_opts << "--git-dir=#{@git_dir}" if !@git_dir.nil?
67
+ global_opts << "--work-tree=#{@git_work_dir}" if !@git_work_dir.nil?
68
+
69
+ opts = [opts].flatten.map {|s| escape(s) }.join(' ')
70
+
71
+ global_opts = global_opts.flatten.map {|s| escape(s) }.join(' ')
72
+
73
+ git_cmd = "#{::Git::Base.config.binary_path} #{global_opts} #{cmd} #{opts} #{redirect} 2>&1"
74
+
75
+ output = nil
76
+
77
+ command_thread = nil;
78
+
79
+ exitstatus = nil
80
+
81
+ command_thread = Thread.new do
82
+ output = run_command(git_cmd, &block)
83
+ exitstatus = $?.exitstatus
84
+ end
85
+ command_thread.join
86
+
87
+ if @logger
88
+ @logger.info(git_cmd)
89
+ @logger.debug(output)
90
+ end
91
+
92
+ if exitstatus > 1 || (exitstatus == 1 && output != '')
93
+ raise Git::GitExecuteError.new(git_cmd + ':' + output.to_s)
94
+ end
95
+
96
+ return output
97
+ end
98
+
99
+ end
100
+
101
+ module Status
102
+ def fetch_untracked
103
+ ignore = @base.lib.ignored_files
104
+
105
+ Dir.chdir(@base.dir.path) do
106
+ Dir.glob('**/*', File::FNM_DOTMATCH) do |file|
107
+ next if @files[file] || File.directory?(file) ||
108
+ ignore.include?(file) || file =~ %r{^.git\/.+} || file =~ %r{^(.*\/)?.gitkeep$}
109
+
110
+ @files[file] = { path: file, untracked: true }
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ Git::Status.prepend(Patches::Git::Status)
119
+ Git::Lib.prepend(Patches::Git::Lib)
120
+ Git::Base.prepend(Patches::Git::Base)
@@ -0,0 +1,26 @@
1
+
2
+
3
+ module Patches
4
+ # Defines methods related to projects.
5
+ # @see https://docs.gitlab.com/ce/api/projects.html
6
+ module Projects
7
+
8
+ # Gets a list of project users.
9
+ #
10
+ # @example
11
+ # Gitlab.project_usesrs(42)
12
+ # Gitlab.project_usesrs('gitlab')
13
+ #
14
+ # @param [Integer, String] project The ID or path of a project.
15
+ # @param [Hash] options A customizable set of options.
16
+ # @option options [Integer] :page The page number.
17
+ # @option options [Integer] :per_page The number of results per page.
18
+ # @return [Array<Gitlab::ObjectifiedHash>]
19
+ def project_usesrs(project, options = {})
20
+ get("/projects/#{url_encode project}/users", query: options)
21
+ end
22
+ end
23
+ end
24
+
25
+
26
+ Gitlab::Client.prepend(Patches::Projects)
@@ -0,0 +1,8 @@
1
+ require 'gb/version'
2
+
3
+
4
+ module Gb
5
+
6
+
7
+
8
+ end
@@ -0,0 +1,3 @@
1
+ module Gb
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,139 @@
1
+ require 'command'
2
+ require 'rubygems'
3
+ require 'config/gb_config'
4
+ require 'colored2'
5
+ require 'gitlab'
6
+ require 'ext/git_ext'
7
+ require 'yaml'
8
+
9
+ module Gb
10
+ class SubCommand < Command
11
+
12
+ self.ignore_in_command_lookup = true
13
+ attr_reader :gb_config
14
+
15
+ def self.options
16
+ [
17
+ ['--config=[Gb.yml]', 'gb配置, 默认为Gb.yml'],
18
+ ].concat(super)
19
+ end
20
+
21
+ def initialize(argv)
22
+ @yml = argv.option('config')
23
+ if @yml.nil?
24
+ @yml = 'Gb.yml'
25
+ end
26
+ super
27
+ end
28
+
29
+ def validate!
30
+ super
31
+ end
32
+
33
+ def run
34
+ workspace_path = "./"
35
+ find_workspace = false;
36
+ begin
37
+ result = nil
38
+ Dir.chdir(workspace_path) do
39
+ result = Dir.glob('.gb', File::FNM_DOTMATCH)
40
+ end
41
+ if result.length > 0
42
+ find_workspace = true
43
+ break
44
+ else
45
+ workspace_path = File.expand_path("../", workspace_path)
46
+ end
47
+ end while workspace_path.length > 0 && workspace_path != "/"
48
+
49
+ if find_workspace
50
+ Dir.chdir(workspace_path) do
51
+ self.run_in_workspace()
52
+ end
53
+ else
54
+ raise Error.new("Current path is not gb workspace. please run 'gb start' first.")
55
+ end
56
+ end
57
+
58
+ def run_in_workspace
59
+
60
+ end
61
+
62
+ def gb_config
63
+ if File.exist?(@yml)
64
+ @gb_config = GbConfig.load_file(@yml)
65
+ else
66
+ help! "gb config not found. please run 'gb create' first."
67
+ end
68
+ @gb_config
69
+ end
70
+
71
+ def workspace_config
72
+ if @workspace_config.nil?
73
+ filename = '.gb'
74
+ # workspace_config_path = File.expand_path(filename, File.dirname(self.gb_config.config_path))
75
+ workspace_config_path = filename
76
+ if !File.exist?(workspace_config_path)
77
+ help! "workspace config not found. please run 'gb start' first."
78
+ end
79
+ @workspace_config = WorkSpaceConfig.load_file(workspace_config_path)
80
+ end
81
+ @workspace_config
82
+ end
83
+
84
+ def save_workspace_config(workspace_config)
85
+ filename = '.gb'
86
+ # workspace_config_path = File.expand_path(filename, File.dirname(self.gb_config.config_path))
87
+ workspace_config_path = filename
88
+ workspace_config.save(workspace_config_path)
89
+ @workspace_config = workspace_config
90
+ end
91
+
92
+ def check_uncommit(g, project_name)
93
+ changed = g.status.changed
94
+ added = g.status.added
95
+ deleted = g.status.deleted
96
+ untracked = g.status.untracked
97
+
98
+ if !changed.empty?
99
+ alert = true
100
+ puts "modified files:".red
101
+ changed.each do |file, status|
102
+ puts (" M: " << file).red
103
+ end
104
+ end
105
+
106
+ if !added.empty?
107
+ alert = true
108
+ puts "added files:".red
109
+ added.each do |file, status|
110
+ puts (" A: " << file).red
111
+ end
112
+ end
113
+
114
+ if !deleted.empty?
115
+ alert = true
116
+ puts "deleted files:".red
117
+ deleted.each do |file, status|
118
+ puts (" D: " << file).red
119
+ end
120
+ end
121
+
122
+ if !untracked.empty?
123
+ alert = true
124
+ puts "untracked files:".red
125
+ untracked.each do |file, status|
126
+ puts (" " << file).red
127
+ end
128
+ end
129
+
130
+ if alert
131
+ puts "exist uncommit files in current branch '#{g.current_branch}' for '#{project_name}'. ignore it? y/n "
132
+ flag = STDIN.gets.chomp
133
+ unless flag.downcase == "y"
134
+ exit
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end