takelage 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +159 -0
- data/bin/tau +5 -0
- data/lib/Thorfile +1 -0
- data/lib/takelage/bit/cli.rb +18 -0
- data/lib/takelage/bit/clipboard/cli.rb +68 -0
- data/lib/takelage/bit/clipboard/module.rb +174 -0
- data/lib/takelage/bit/scope/cli.rb +58 -0
- data/lib/takelage/bit/scope/module.rb +81 -0
- data/lib/takelage/completion/cli.rb +21 -0
- data/lib/takelage/default.yml +30 -0
- data/lib/takelage/docker/cli.rb +16 -0
- data/lib/takelage/docker/container/check/cli.rb +40 -0
- data/lib/takelage/docker/container/check/module.rb +44 -0
- data/lib/takelage/docker/container/cli.rb +127 -0
- data/lib/takelage/docker/container/module.rb +168 -0
- data/lib/takelage/docker/image/cli.rb +41 -0
- data/lib/takelage/docker/image/module.rb +33 -0
- data/lib/takelage/docker/image/tag/check/cli.rb +47 -0
- data/lib/takelage/docker/image/tag/check/module.rb +56 -0
- data/lib/takelage/docker/image/tag/cli.rb +16 -0
- data/lib/takelage/docker/image/tag/latest/cli.rb +49 -0
- data/lib/takelage/docker/image/tag/latest/module.rb +31 -0
- data/lib/takelage/docker/image/tag/list/cli.rb +46 -0
- data/lib/takelage/docker/image/tag/list/module.rb +44 -0
- data/lib/takelage/docker/socket/cli.rb +61 -0
- data/lib/takelage/docker/socket/module.rb +137 -0
- data/lib/takelage/git/check/cli.rb +46 -0
- data/lib/takelage/git/check/module.rb +64 -0
- data/lib/takelage/git/cli.rb +10 -0
- data/lib/takelage/info/cli.rb +10 -0
- data/lib/takelage/info/project/cli.rb +47 -0
- data/lib/takelage/lib/config.rb +80 -0
- data/lib/takelage/lib/logging.rb +30 -0
- data/lib/takelage/lib/project.rb +57 -0
- data/lib/takelage/lib/subcmd.rb +13 -0
- data/lib/takelage/lib/system.rb +107 -0
- data/lib/takelage/self/cli.rb +40 -0
- data/lib/takelage/self/config/cli.rb +70 -0
- data/lib/takelage/self/module.rb +26 -0
- data/lib/takelage/version +1 -0
- data/lib/takelage.rb +198 -0
- metadata +185 -0
data/README.md
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
# takelage-cli
|
2
|
+
|
3
|
+
*takelage-cli* is a command line interface
|
4
|
+
to facilitate the takelage devops workflow.
|
5
|
+
The takelage devops workflow helps devops engineers
|
6
|
+
build, test and deploy os images.
|
7
|
+
|
8
|
+
The *takelage-cli* executable *tau* is a
|
9
|
+
[ruby](https://www.ruby-lang.org/)
|
10
|
+
command line script using the
|
11
|
+
[thor](http://whatisthor.com/) toolkit.
|
12
|
+
|
13
|
+
## Ecosystem
|
14
|
+
|
15
|
+
The takelage devops framework consists of these projects:
|
16
|
+
|
17
|
+
| App | Description |
|
18
|
+
| --- | ----------- |
|
19
|
+
| *[takelage-cli](https://github.com/geospin-takelage/takelage-cli)* | The takelage command line interface |
|
20
|
+
| *[takelage-dev](https://github.com/geospin-takelage/takelage-dev)* | The takelage development environment |
|
21
|
+
| **[takelage-bit](https://github.com/geospin-takelage/takelage-bit)** | The takelage [bit](https://github.com/teambit/bit) server |
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
*tau* is part of *takelage-dev*'s docker image
|
26
|
+
but you typically want to install it on the host system as well.
|
27
|
+
Install the takelage gem and its dependencies
|
28
|
+
through the [gem](https://github.com/rubygems/rubygems)
|
29
|
+
command line tool:
|
30
|
+
|
31
|
+
```bash
|
32
|
+
gem install takelage thor fylla logger
|
33
|
+
```
|
34
|
+
|
35
|
+
## Commands
|
36
|
+
|
37
|
+
*takelage-cli* uses [cucumber](https://github.com/cucumber/cucumber)
|
38
|
+
to system test its features.
|
39
|
+
You are encouraged to read the cucumber feature files
|
40
|
+
for the *tau* commands
|
41
|
+
to get an idea of how the commands work.
|
42
|
+
You can list the *tau* commands by running
|
43
|
+
*tau [self list](features/takelage/self/self.list.feature)*
|
44
|
+
or *tau list*:
|
45
|
+
|
46
|
+
Command | Description
|
47
|
+
------- | -----------
|
48
|
+
tau config | # Alias for tau [self config active](features/takelage/self/self.config.active.feature)
|
49
|
+
tau copy [DIR] [SCOPE] | # Alias for tau [bit clipboard copy](features/takelage/bit/bit.clipboard.copy.feature)
|
50
|
+
tau list | # Alias for tau [self list](features/takelage/self/self.list.feature)
|
51
|
+
tau login | # Alias for tau [docker container login](features/takelage/docker/docker.container.login.feature)
|
52
|
+
tau nuke | # Alias for tau [docker container nuke](features/takelage/docker/docker.container.nuke.feature)
|
53
|
+
tau paste [COMPONENT] [DIR] | # Alias for tau [bit clipboard paste](features/takelage/bit/bit.clipboard.paste.feature)
|
54
|
+
tau project | # Alias for tau [info project active](features/takelage/info/info.project.active.feature)
|
55
|
+
tau pull | # Alias for tau [bit clipboard pull](features/takelage/bit/bit.clipboard.pull.feature)
|
56
|
+
tau purge | # Alias for tau [docker container purge](features/takelage/docker/docker.container.purge.feature)
|
57
|
+
tau push | # Alias for tau [bit clipboard push](features/takelage/bit/bit.clipboard.push.feature)
|
58
|
+
tau update | # Alias for tau [docker image update](features/takelage/docker/docker.image.update.feature)
|
59
|
+
tau version | # Alias for tau [self version](features/takelage/self/self.version.feature)
|
60
|
+
tau [bit clipboard copy](features/takelage/bit/bit.clipboard.copy.feature) [DIR] [SCOPE] | # Copy new [DIR] to [SCOPE]
|
61
|
+
tau [bit clipboard paste](features/takelage/bit/bit.clipboard.paste.feature) [COMPONENT] [DIR] | # Paste bit [COMPONENT] into [DIR]
|
62
|
+
tau [bit clipboard pull](features/takelage/bit/bit.clipboard.pull.feature) | # Pull all updates for bit components from bit remote scopes
|
63
|
+
tau [bit clipboard push](features/takelage/bit/bit.clipboard.push.feature) | # Push all updates of bit components to bit remote scopes
|
64
|
+
tau [bit scope add](features/takelage/bit/bit.scope.add.feature) [SCOPE] | # Add a bit [SCOPE]
|
65
|
+
tau [bit scope list](features/takelage/bit/bit.scope.list.feature) | # List bit remote scopes
|
66
|
+
tau [bit scope new](features/takelage/bit/bit.scope.new.feature) [SCOPE] | # Init a new bit [SCOPE]
|
67
|
+
tau [completion bash](features/takelage/completion/completion.bash.feature) | # Print bash completion code
|
68
|
+
tau [docker container check existing](features/takelage/docker/docker.container.check.existing.feature) [CONTAINER] | # Check if docker [CONTAINER] is existing
|
69
|
+
tau [docker container check orphaned](features/takelage/docker/docker.container.check.orphaned.feature) [CONTAINER] | # Check if docker [CONTAINER] is orphaned
|
70
|
+
tau [docker container command](features/takelage/docker/docker.container.command.feature) [CMD] | # Run [CMD] in a docker container
|
71
|
+
tau [docker container daemon](features/takelage/docker/docker.container.daemon.feature) | # Run docker container in daemon mode
|
72
|
+
tau [docker container login](features/takelage/docker/docker.container.login.feature) | # Log in to latest local docker container
|
73
|
+
tau [docker container nuke](features/takelage/docker/docker.container.nuke.feature) | # Remove all docker containers
|
74
|
+
tau [docker container purge](features/takelage/docker/docker.container.purge.feature) | # Remove orphaned docker containers
|
75
|
+
tau [docker image tag check local](features/takelage/docker/docker.image.tag.check.local.feature) [TAG] | # Check if local docker image [TAG] exists
|
76
|
+
tau [docker image tag check remote](features/takelage/docker/docker.image.tag.check.remote.feature) [TAG] | # Check if remote docker image [TAG] exists
|
77
|
+
tau [docker image tag latest local](features/takelage/docker/docker.image.tag.latest.local.feature) | # Print latest local docker image tag
|
78
|
+
tau [docker image tag latest remote](features/takelage/docker/docker.image.tag.latest.remote.feature) | # Print latest remote docker image tag
|
79
|
+
tau [docker image tag list local](features/takelage/docker/docker.image.tag.list.local.feature) | # Print local docker image tags
|
80
|
+
tau [docker image tag list remote](features/takelage/docker/docker.image.tag.list.remote.feature) | # Print remote docker image tags
|
81
|
+
tau [docker image update](features/takelage/docker/docker.image.update.feature) | # Get latest remote docker container
|
82
|
+
tau [docker socket start](features/takelage/docker/docker.socket.start.feature) | # Start sockets for docker container
|
83
|
+
tau [docker socket stop](features/takelage/docker/docker.socket.stop.feature) | # Stop sockets for docker container
|
84
|
+
tau [git check clean](features/takelage/git/git.check.clean.feature) | # Check if the git workspace is clean
|
85
|
+
tau [git check master](features/takelage/git/git.check.master.feature) | # Check if we are on the git master branch
|
86
|
+
tau [git check workspace](features/takelage/git/git.check.workspace.feature) | # Check if a git workspace exists
|
87
|
+
tau [info project active](features/takelage/info/info.project.active.feature) | # Print active project info
|
88
|
+
tau [info project private](features/takelage/info/info.project.private.feature) | # Print private project info
|
89
|
+
tau [info project main](features/takelage/info/info.project.main.feature) | # Print main project info
|
90
|
+
tau [self config active](features/takelage/self/self.config.active.feature) | # Print active takelage configuration
|
91
|
+
tau [self config default](features/takelage/self/self.config.default.feature) | # Print takelage default configuration
|
92
|
+
tau [self config home](features/takelage/self/self.config.home.feature) | # Print takelage home config file configuration
|
93
|
+
tau [self config project](features/takelage/self/self.config.project.feature) | # Print takelage project config file configuration
|
94
|
+
tau [self list](features/takelage/self/self.list.feature) | # List all commands
|
95
|
+
tau [self version](features/takelage/self/self.version.feature) | # Print tau semantic version number
|
96
|
+
|
97
|
+
## Configuration
|
98
|
+
|
99
|
+
### Configuration Files
|
100
|
+
|
101
|
+
*takelage-cli* uses three different YAML configuration files
|
102
|
+
which have different precedences.
|
103
|
+
They are merged to an active configuration during runtime
|
104
|
+
which can be inspected with
|
105
|
+
*tau [self config active](features/takelage/self/self.config.active.feature)*
|
106
|
+
or *tau config*.
|
107
|
+
|
108
|
+
| Filename | Precedence | Description |
|
109
|
+
| -------- | ---------- | ----------- |
|
110
|
+
| *default.yml* | lowest | Shipped with *takelage-cli*. Sets defaults where applicable. |
|
111
|
+
| *~/.takelage.yml* | normal | User-wide configuration file in your home directory. This is your normal custom configuration file. |
|
112
|
+
| *takelage.yml* | highest | Project-specific configuration file next to your main Rakefile. Some projects need special configuration. |
|
113
|
+
|
114
|
+
### Configuration Examples
|
115
|
+
|
116
|
+
- You should the following configuration items in your *~/.takelage.yml*:
|
117
|
+
```yaml
|
118
|
+
---
|
119
|
+
bit_remote: 'ssh://bit@bit.example.com:2222:/bit'
|
120
|
+
bit_ssh: 'ssh -p 2222 bit@bit.example.com'
|
121
|
+
docker_image: 'takelage'
|
122
|
+
docker_repo: 'hub.example.com'
|
123
|
+
docker_tagsurl: 'https://hub.example.com/v2/repositories/library/takelage/tags'
|
124
|
+
```
|
125
|
+
|
126
|
+
- If you want to pin a specific docker tag for one of your projects
|
127
|
+
then create an *takelage.yml* file with:
|
128
|
+
```yaml
|
129
|
+
---
|
130
|
+
docker_tag: '1.2.3'
|
131
|
+
```
|
132
|
+
|
133
|
+
- The cucumber tests make use of an *~/.takelage.yml*
|
134
|
+
to overwrite defaults like:
|
135
|
+
```yaml
|
136
|
+
---
|
137
|
+
docker_image: takelage-mock
|
138
|
+
```
|
139
|
+
|
140
|
+
### Project Files
|
141
|
+
|
142
|
+
*tau* reads two different YAML project files
|
143
|
+
which have different precedences.
|
144
|
+
They are merged to an active configuration during runtime
|
145
|
+
which can be inspected with
|
146
|
+
*tau [info project active](features/takelage/info/info.project.active.feature)*
|
147
|
+
or *tau project*.
|
148
|
+
|
149
|
+
| Default filename | Config key | Precedence | Description |
|
150
|
+
| -------- | ---------- | ---------- | ----------- |
|
151
|
+
| *project.yml* | info_project_main | normal | Main project file. |
|
152
|
+
| *ansible/group_vars/private/project.yml* | info_project_private | highest | Private project file. Should be in *.gitignore*. |
|
153
|
+
|
154
|
+
### Bash Completion
|
155
|
+
|
156
|
+
Add this to your bash configuration file like *~/.bash_profile* or *~/.bashrc*:
|
157
|
+
```bash
|
158
|
+
source <(tau completion bash)
|
159
|
+
```
|
data/bin/tau
ADDED
data/lib/Thorfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'takelage'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Takelage
|
4
|
+
|
5
|
+
# takelage bit
|
6
|
+
class Bit < SubCommandBase
|
7
|
+
|
8
|
+
include LoggingModule
|
9
|
+
include SystemModule
|
10
|
+
include ConfigModule
|
11
|
+
|
12
|
+
desc 'clipboard [COMMAND]', 'Manage bit clipboard'
|
13
|
+
subcommand 'clipboard', BitClipboard
|
14
|
+
|
15
|
+
desc 'scope [COMMAND]', 'Manage bit scopes'
|
16
|
+
subcommand 'scope', BitScope
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Takelage
|
4
|
+
|
5
|
+
# takelage bit
|
6
|
+
class BitClipboard < SubCommandBase
|
7
|
+
|
8
|
+
include LoggingModule
|
9
|
+
include ConfigModule
|
10
|
+
include SystemModule
|
11
|
+
include GitCheckModule
|
12
|
+
include BitClipboardModule
|
13
|
+
|
14
|
+
#
|
15
|
+
# bit copy
|
16
|
+
#
|
17
|
+
desc 'copy [DIR] [SCOPE]', 'Copy new [DIR] to [SCOPE]'
|
18
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
19
|
+
Copy a directory as a bit component to a bit remote scope
|
20
|
+
This command will add a directory as a bit component and tag it.
|
21
|
+
The id of the component will be created from the directory name.
|
22
|
+
The directory needs to contain a README.bit file
|
23
|
+
or else a new README.bit file will be created.
|
24
|
+
The README.bit will be the main file of the component which must not be deleted.
|
25
|
+
The tagged bit component will be exported to a bit remote scope.
|
26
|
+
LONGDESC
|
27
|
+
# Copy a file or directory as a bit component to a bit remote scope.
|
28
|
+
def copy(dir_or_file, scope)
|
29
|
+
bit_clipboard_copy dir_or_file, scope
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# bit paste
|
34
|
+
#
|
35
|
+
desc 'paste [COMPONENT] [DIR]', 'Paste bit [COMPONENT] into [DIR]'
|
36
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
37
|
+
Paste a bit component into a directory
|
38
|
+
LONGDESC
|
39
|
+
# Paste a bit component into a directory.
|
40
|
+
def paste(cid, dir)
|
41
|
+
bit_clipboard_paste cid, dir
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# bit pull
|
46
|
+
#
|
47
|
+
desc 'pull', 'Pull all updates for bit components from bit remote scopes'
|
48
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
49
|
+
Pull all updates for bit components from bit remote scopes
|
50
|
+
LONGDESC
|
51
|
+
# Pull all updates for bit components from bit remote scopes.
|
52
|
+
def pull
|
53
|
+
bit_clipboard_pull
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# bit push
|
58
|
+
#
|
59
|
+
desc 'push', 'Push all updates of bit components to bit remote scopes'
|
60
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
61
|
+
Push all updates of bit components to bit remote scopes
|
62
|
+
LONGDESC
|
63
|
+
# Push all updates of bit components to bit remote scopes.
|
64
|
+
def push
|
65
|
+
bit_clipboard_push
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# takelage bit clipboard module
|
2
|
+
module BitClipboardModule
|
3
|
+
|
4
|
+
# Backend method for bit copy.
|
5
|
+
def bit_clipboard_copy(dir, scope)
|
6
|
+
log.debug "Running bit copy \"#{dir}\" to \"#{scope}\""
|
7
|
+
|
8
|
+
if git_check_workspace
|
9
|
+
unless git_check_master
|
10
|
+
log.error 'Not on git master branch'
|
11
|
+
return
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if File.directory? dir
|
16
|
+
|
17
|
+
# remove trailing slash
|
18
|
+
dir = dir.chomp('/')
|
19
|
+
|
20
|
+
log.debug "Adding the directory \"#{dir}\" as a tagged bit component"
|
21
|
+
|
22
|
+
# check if bit remote scope is added to local workspace
|
23
|
+
cmd_bit_list_remotes = config.active['bit_list_remotes']
|
24
|
+
stdout_str, stderr_str, status = run_and_check cmd_bit_list_remotes
|
25
|
+
unless /.*\s+#{scope}\s+.*/m.match? stdout_str
|
26
|
+
log.error "No bit remote scope \"#{scope}\" found in local bit workspace"
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
# check if a README.bit file exists in a subdirectory
|
31
|
+
Dir.glob("#{dir}/**/README.bit").each do |file|
|
32
|
+
unless file == "#{dir}/README.bit"
|
33
|
+
log.error "Nested README.bit file detected"
|
34
|
+
return
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# touch README.bit if necessary
|
39
|
+
readme_bit = "#{dir}/README.bit"
|
40
|
+
unless File.file? readme_bit
|
41
|
+
log.warn "Creating \"README.bit\" in \"#{dir}\""
|
42
|
+
File.open(readme_bit, 'w') {}
|
43
|
+
end
|
44
|
+
|
45
|
+
# generate component id from directory name
|
46
|
+
id = _id(File.basename(dir))
|
47
|
+
|
48
|
+
# get bit add dir command from active config
|
49
|
+
cmd_bit_add_dir = config.active['bit_add_dir'] % {id: id, dir: dir}
|
50
|
+
run cmd_bit_add_dir
|
51
|
+
|
52
|
+
# get bit tag dir command from active config
|
53
|
+
cmd_bit_tag_id = config.active['bit_tag_id'] % {id: id}
|
54
|
+
run cmd_bit_tag_id
|
55
|
+
else
|
56
|
+
log.error "The directory \"#{dir}\" does not exist"
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
# export component to bit remote scope
|
61
|
+
cmd_bit_export_to_scope = config.active['bit_export_to_scope'] % {scope: scope}
|
62
|
+
run cmd_bit_export_to_scope
|
63
|
+
|
64
|
+
# remove node_modules directory
|
65
|
+
_rm_node_modules
|
66
|
+
|
67
|
+
log.info "Copied directory \"#{dir}\" " +
|
68
|
+
"as bit component \"#{id}\" " +
|
69
|
+
"to bit remote scope \"#{scope}\""
|
70
|
+
end
|
71
|
+
|
72
|
+
# Backend method for bit paste.
|
73
|
+
def bit_clipboard_paste(cid, dir)
|
74
|
+
log.debug "Running bit paste \"#{cid}\" to \"#{dir}\""
|
75
|
+
|
76
|
+
if git_check_workspace
|
77
|
+
unless git_check_master
|
78
|
+
log.error 'Not on git master branch'
|
79
|
+
return
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# paste bit component into directory
|
84
|
+
cmd_bit_import_cid = config.active['bit_import_cid'] % {cid: cid, dir: dir}
|
85
|
+
run cmd_bit_import_cid
|
86
|
+
|
87
|
+
# remove node_modules directory
|
88
|
+
_rm_node_modules
|
89
|
+
|
90
|
+
FileUtils.remove_entry_secure("#{dir}/index.bit", force: true)
|
91
|
+
|
92
|
+
log.info "Pasted bit component \"#{cid}\"" +
|
93
|
+
"to directory \"#{dir}\""
|
94
|
+
end
|
95
|
+
|
96
|
+
# Backend method for bit pull.
|
97
|
+
def bit_clipboard_pull
|
98
|
+
log.debug "Running bit pull"
|
99
|
+
|
100
|
+
if git_check_workspace
|
101
|
+
unless git_check_master
|
102
|
+
log.error 'Not on git master branch'
|
103
|
+
return
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# import components into workspace
|
108
|
+
cmd_bit_import_all = config.active['bit_import_all']
|
109
|
+
run cmd_bit_import_all
|
110
|
+
|
111
|
+
# checkout components and merge them
|
112
|
+
cmd_bit_checkout_all = config.active['bit_checkout_all']
|
113
|
+
run cmd_bit_checkout_all
|
114
|
+
|
115
|
+
# remove node_modules directory
|
116
|
+
_rm_node_modules
|
117
|
+
|
118
|
+
log.info "Pulled bit components"
|
119
|
+
end
|
120
|
+
|
121
|
+
# Backend method for bit push
|
122
|
+
def bit_clipboard_push
|
123
|
+
log.debug "Running bit push"
|
124
|
+
|
125
|
+
if git_check_workspace
|
126
|
+
unless git_check_master
|
127
|
+
log.error 'Not on git master branch'
|
128
|
+
return
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# tag all components
|
133
|
+
cmd_bit_tag_all = config.active['bit_tag_all']
|
134
|
+
run cmd_bit_tag_all
|
135
|
+
|
136
|
+
# export components
|
137
|
+
cmd_bit_export_all = config.active['bit_export_all']
|
138
|
+
run cmd_bit_export_all
|
139
|
+
|
140
|
+
# remove node_modules directory
|
141
|
+
_rm_node_modules
|
142
|
+
|
143
|
+
log.info "Pushed bit components"
|
144
|
+
end
|
145
|
+
|
146
|
+
# Generate bit component ID.
|
147
|
+
def _id(name)
|
148
|
+
id = ''
|
149
|
+
|
150
|
+
# bit restrictions:
|
151
|
+
# component names can only contain alphanumeric,
|
152
|
+
# lowercase characters, and the following ["-", "_", "$", "!", "/"]
|
153
|
+
|
154
|
+
# convert directory name to lowercase characters
|
155
|
+
dir_downcase = name.downcase
|
156
|
+
|
157
|
+
# construct array of allowed characters
|
158
|
+
allowed_chars = [*('a'..'z'), *('0'..'9'), '-', '_', '$', '!', '/']
|
159
|
+
|
160
|
+
# iterate over directory or file name
|
161
|
+
# and replace invalid characters with underscore
|
162
|
+
dir_downcase.split('').each do |char|
|
163
|
+
id += (allowed_chars.include? char) ? char : '_'
|
164
|
+
end
|
165
|
+
|
166
|
+
log.debug "Generated bit id \"#{id}\" from \"#{name}\""
|
167
|
+
id
|
168
|
+
end
|
169
|
+
|
170
|
+
# Remove node_modules directory.
|
171
|
+
def _rm_node_modules
|
172
|
+
FileUtils.remove_entry_secure('node_modules', force: true)
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Takelage
|
2
|
+
|
3
|
+
# takelage bit scope
|
4
|
+
class BitScope < SubCommandBase
|
5
|
+
|
6
|
+
include LoggingModule
|
7
|
+
include SystemModule
|
8
|
+
include ConfigModule
|
9
|
+
include GitCheckModule
|
10
|
+
include BitScopeModule
|
11
|
+
|
12
|
+
#
|
13
|
+
# bit scope add
|
14
|
+
#
|
15
|
+
desc 'add [SCOPE]', 'Add a bit [SCOPE]'
|
16
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
17
|
+
Add bit remote scope
|
18
|
+
This command will add a bit remote scope to a local bit workspace.
|
19
|
+
The scope must exist on the bit remote server.
|
20
|
+
LONGDESC
|
21
|
+
# Add bit remote scope.
|
22
|
+
def add(scope)
|
23
|
+
exit false unless configured? %w(bit_ssh bit_remote)
|
24
|
+
bit_scope_add scope
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# bit scope new
|
29
|
+
#
|
30
|
+
desc 'new [SCOPE]', 'Init a new bit [SCOPE]'
|
31
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
32
|
+
Create new bit remote scope
|
33
|
+
This command will create a new directory on the remote bit server.
|
34
|
+
Then it will run "bit init --bare" in the newly created directory.
|
35
|
+
See the bit documentation: http://docs.bit.dev/docs/bit-server
|
36
|
+
LONGDESC
|
37
|
+
# Create new bit remote scope.
|
38
|
+
def new(scope)
|
39
|
+
exit false unless configured? %w(bit_ssh bit_remote)
|
40
|
+
bit_scope_new scope
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# bit scope list
|
45
|
+
#
|
46
|
+
desc 'list', 'List bit remote scopes'
|
47
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
48
|
+
List bit remote scopes
|
49
|
+
This command will list bit remote scopes.
|
50
|
+
LONGDESC
|
51
|
+
# List bit remote scopes.
|
52
|
+
def list
|
53
|
+
exit false unless configured? %w(bit_ssh bit_remote)
|
54
|
+
scopes = bit_scope_list
|
55
|
+
say scopes unless scopes.to_s.strip.empty?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# takelage bit scope module
|
2
|
+
module BitScopeModule
|
3
|
+
|
4
|
+
# Backend method for bit scope add.
|
5
|
+
def bit_scope_add(scope)
|
6
|
+
log.debug "Adding bit remote scope \"#{scope}\" to local workspace"
|
7
|
+
|
8
|
+
if git_check_workspace
|
9
|
+
unless git_check_master
|
10
|
+
log.error 'Not on git master branch'
|
11
|
+
return
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# check if bit remote scope exists
|
16
|
+
scope_list = bit_scope_list
|
17
|
+
log.debug scope_list
|
18
|
+
unless scope_list.include? scope
|
19
|
+
log.error "The bit remote bit scope \"#{scope}\" doesn't exist"
|
20
|
+
exit false
|
21
|
+
end
|
22
|
+
|
23
|
+
# get bit remote from active config
|
24
|
+
bit_remote = config.active['bit_remote']
|
25
|
+
|
26
|
+
# prepare scope add command
|
27
|
+
cmd_bit_scope_add = "bit remote add #{bit_remote}/#{scope}"
|
28
|
+
run cmd_bit_scope_add
|
29
|
+
|
30
|
+
log.info "Added bit remote scope \"#{scope}\" to local bit workspace"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Backend method for bit scope list.
|
34
|
+
# @return [String] list of bit scopes
|
35
|
+
def bit_scope_list
|
36
|
+
log.debug "Listing bit remote scopes"
|
37
|
+
|
38
|
+
# get ssh command from active config
|
39
|
+
cmd_bit_ssh = config.active['bit_ssh']
|
40
|
+
|
41
|
+
# prepare scope list command
|
42
|
+
root = config.active['bit_scope_root']
|
43
|
+
cmd_bit_scope_list = config.active['bit_scope_list'] % {root: root}
|
44
|
+
|
45
|
+
# run ssh command with scope list command
|
46
|
+
scope_list, stderr, status = run_and_check "#{cmd_bit_ssh} '#{cmd_bit_scope_list}'"
|
47
|
+
|
48
|
+
# remove bit remote root directory from results
|
49
|
+
scope_list.gsub!(/#{root}\/*/, '')
|
50
|
+
|
51
|
+
# remove /scope.json from results
|
52
|
+
scope_list.gsub!(/\/scope.json/, '')
|
53
|
+
|
54
|
+
scope_list
|
55
|
+
end
|
56
|
+
|
57
|
+
# Backend method for bit scope new.
|
58
|
+
# @return [Int] status of new command
|
59
|
+
def bit_scope_new(scope)
|
60
|
+
log.debug "Creating new bit remote scope \"#{scope}\""
|
61
|
+
|
62
|
+
# check if bit remote scope already exists
|
63
|
+
scope_list = bit_scope_list
|
64
|
+
if scope_list.include? scope
|
65
|
+
log.error "The remote bit scope \"#{scope}\" already exists"
|
66
|
+
exit false
|
67
|
+
end
|
68
|
+
|
69
|
+
# get ssh command from active config
|
70
|
+
cmd_bit_ssh = config.active['bit_ssh']
|
71
|
+
|
72
|
+
# prepare scope list command
|
73
|
+
root = config.active['bit_scope_root']
|
74
|
+
cmd_bit_scope_new = config.active['bit_scope_new'] % {scope: scope, root: root}
|
75
|
+
|
76
|
+
# run ssh command with scope new command
|
77
|
+
run "#{cmd_bit_ssh} '#{cmd_bit_scope_new}'"
|
78
|
+
|
79
|
+
log.info "Created new bit remote scope \"#{scope}\""
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Takelage
|
2
|
+
|
3
|
+
# takelage completion
|
4
|
+
class Completion < SubCommandBase
|
5
|
+
|
6
|
+
include LoggingModule
|
7
|
+
|
8
|
+
desc 'bash', 'Print bash completion code'
|
9
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
10
|
+
Print bash completion code
|
11
|
+
This command will print bash code which can be parsed to enable auto-completion for the takelage cli.
|
12
|
+
Put the following line in your shell start script like ~/.bashrc or ~/.bash_profile:
|
13
|
+
|
14
|
+
source <(takelage completion bash)
|
15
|
+
LONGDESC
|
16
|
+
# Print bash completion code.
|
17
|
+
def bash
|
18
|
+
say Takelage::CLI.new.bash_fylla
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
---
|
2
|
+
bit_add_dir: 'bit add --skip-update --id %{id} --main %{dir}/README.bit %{dir}'
|
3
|
+
bit_checkout_all: 'bit checkout --ignore-package-json --skip-update -i --all latest'
|
4
|
+
bit_export_to_scope: 'bit export --skip-update %{scope}'
|
5
|
+
bit_export_all: 'bit export --skip-update'
|
6
|
+
bit_import_cid: 'bit import --ignore-package-json --skip-update -p %{dir} %{cid}'
|
7
|
+
bit_import_all: 'bit import --skip-update --ignore-package-json -m manual'
|
8
|
+
bit_list_remotes: 'bit remote --skip-update'
|
9
|
+
bit_scope_root: '/bit'
|
10
|
+
bit_scope_list: 'find %{root} -name scope.json'
|
11
|
+
bit_scope_new: 'mkdir -p %{root}/%{scope} && cd %{root}/%{scope} && bit init -b'
|
12
|
+
bit_scope_remove: 'rm -fr %{root}/%{scope}'
|
13
|
+
bit_tag_id: 'bit tag --skip-update --skip-tests %{id}'
|
14
|
+
bit_tag_all: 'bit tag --all'
|
15
|
+
docker_socket_agent_port: 20000
|
16
|
+
docker_socket_agent_ssh_port: 20001
|
17
|
+
docker_socket_agent_extra_port: 20002
|
18
|
+
docker_socket_agent_browser_port: 20003
|
19
|
+
docker_socket_ps: 'sudo ps a -o pid,command'
|
20
|
+
docker_socket_gpgconf: 'gpgconf --list-dirs'
|
21
|
+
docker_socket_kill: 'sudo kill -SIGTERM %{pid}'
|
22
|
+
docker_socket_start: 'sudo socat TCP-LISTEN:%{port},bind=%{host},reuseaddr,fork UNIX-CLIENT:%{path}'
|
23
|
+
docker_tag: 'latest'
|
24
|
+
info_project_main: 'project.yml'
|
25
|
+
info_project_private: 'private/project.yml'
|
26
|
+
#bit_remote: 'ssh://bit@bit.example.com:2222:/bit'
|
27
|
+
#bit_ssh: 'ssh -p 2222 bit@bit.example.com'
|
28
|
+
#docker_image: 'takelage'
|
29
|
+
#docker_repo: 'hub.docker.com'
|
30
|
+
#docker_tagsurl: 'https://hub.docker.com/v2/repositories/library/takelage/tags'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Takelage
|
2
|
+
|
3
|
+
# takelage docker
|
4
|
+
class Docker < SubCommandBase
|
5
|
+
|
6
|
+
desc 'container [COMMAND]', 'Handle docker container'
|
7
|
+
subcommand 'container', DockerContainer
|
8
|
+
|
9
|
+
desc 'image [COMMAND]', 'Handle docker images'
|
10
|
+
subcommand 'image', DockerImage
|
11
|
+
|
12
|
+
desc 'socket [COMMAND]', 'Handle sockets for docker containers'
|
13
|
+
subcommand 'socket', DockerSocket
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Takelage
|
2
|
+
|
3
|
+
# takelage docker container check
|
4
|
+
class DockerContainerCheck < SubCommandBase
|
5
|
+
|
6
|
+
include LoggingModule
|
7
|
+
include SystemModule
|
8
|
+
include ConfigModule
|
9
|
+
include DockerContainerCheckModule
|
10
|
+
|
11
|
+
#
|
12
|
+
# docker container check existing
|
13
|
+
#
|
14
|
+
desc 'existing [CONTAINER]', 'Check if docker [CONTAINER] is existing'
|
15
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
16
|
+
Check if docker container is existing
|
17
|
+
This check looks for a container with a given name.
|
18
|
+
If such a container is existing the result is true else false.
|
19
|
+
LONGDESC
|
20
|
+
# Check if docker container is existing.
|
21
|
+
def existing(container)
|
22
|
+
exit docker_container_check_existing container
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# docker container check orphaned
|
27
|
+
#
|
28
|
+
desc 'orphaned [CONTAINER]', 'Check if docker [CONTAINER] is orphaned'
|
29
|
+
long_desc <<-LONGDESC.gsub("\n", "\x5")
|
30
|
+
Check if docker container is orphaned
|
31
|
+
This check looks for a process which is started
|
32
|
+
when you log in to an takelage docker container.
|
33
|
+
If such a process is found the result is true else false.
|
34
|
+
LONGDESC
|
35
|
+
# Check if docker container is orphaned.
|
36
|
+
def orphaned(container)
|
37
|
+
exit docker_container_check_orphaned container
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|