gb 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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