trove 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/LICENSE.txt +1 -1
- data/README.md +13 -4
- data/lib/trove/cli.rb +1 -1
- data/lib/trove/storage/s3.rb +3 -3
- data/lib/trove/version.rb +1 -1
- data/lib/trove.rb +40 -11
- metadata +8 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 969613b215dd90871123cfb6cf1c839280c9a097ab5eb3f8837dffff0d5ad01a
|
4
|
+
data.tar.gz: 28e2959384053285ec39956d50ddb2138fe7277a1c3f9dc777575afddc5368e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0eef9a86d4a4dbb8f54bd547b155eddc8510b68a760e67e4860b8ca8690782d34f224f96506852510ca945a874564a7d279e52acf37f56ac7999cb30992cc4b3
|
7
|
+
data.tar.gz: bac12e3d0ec42be4e8f67384232517bf2ba8f2759ba8d0675f0e23ae0091bd5d96ecbc6d9d092178dd2626c1ed0c9244021a2fb382ae88c061d95a7782926306
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## 0.2.0 (2023-04-11)
|
2
|
+
|
3
|
+
- Improved error messages
|
4
|
+
- Fixed error with missing dependencies
|
5
|
+
- Fixed error with `list` when no files
|
6
|
+
- Dropped support for Ruby < 3
|
7
|
+
|
8
|
+
## 0.1.1 (2020-12-04)
|
9
|
+
|
10
|
+
- Added support for running in subdirectories
|
11
|
+
|
1
12
|
## 0.1.0 (2020-10-30)
|
2
13
|
|
3
14
|
- First release
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -9,7 +9,7 @@ Works great with [XGBoost](https://github.com/ankane/xgboost), [Torch.rb](https:
|
|
9
9
|
Add this line to your application’s Gemfile:
|
10
10
|
|
11
11
|
```ruby
|
12
|
-
gem
|
12
|
+
gem "trove"
|
13
13
|
```
|
14
14
|
|
15
15
|
And run:
|
@@ -82,7 +82,7 @@ If your production servers only need to pull files, only give them `s3:GetObject
|
|
82
82
|
|
83
83
|
Git is great for code, but it’s not ideal for large files like models. Instead, we use an object store like Amazon S3 to store and version them.
|
84
84
|
|
85
|
-
Trove creates
|
85
|
+
Trove creates a `trove` directory for you to use as a workspace. Files in this directory are ignored by Git but can be pushed and pulled from the object store. By default, files are tracked in `.trove.yml` to make it easy to deploy specific versions with code changes.
|
86
86
|
|
87
87
|
## Getting Started
|
88
88
|
|
@@ -132,7 +132,7 @@ remote: Asset precompilation completed (30.00s)
|
|
132
132
|
|
133
133
|
### Docker
|
134
134
|
|
135
|
-
|
135
|
+
Add to your `Dockerfile`:
|
136
136
|
|
137
137
|
```Dockerfile
|
138
138
|
RUN bundle exec trove pull
|
@@ -200,7 +200,7 @@ This makes it easy to perform operations from code, iRuby notebooks, and the Rai
|
|
200
200
|
|
201
201
|
## Automated Training
|
202
202
|
|
203
|
-
By default, Trove tracks files in `.trove.yml`
|
203
|
+
By default, Trove tracks files in `.trove.yml` to make it easy to deploy specific versions with code changes. However, this functionality is entirely optional. Disable it with:
|
204
204
|
|
205
205
|
```yml
|
206
206
|
vcs: false
|
@@ -208,6 +208,15 @@ vcs: false
|
|
208
208
|
|
209
209
|
This is useful if you want to automate training or build more complex workflows.
|
210
210
|
|
211
|
+
## Non-Ruby
|
212
|
+
|
213
|
+
Trove can be used in non-Ruby projects as well.
|
214
|
+
|
215
|
+
```sh
|
216
|
+
gem install trove
|
217
|
+
trove init
|
218
|
+
```
|
219
|
+
|
211
220
|
## History
|
212
221
|
|
213
222
|
View the [changelog](https://github.com/ankane/trove/blob/master/CHANGELOG.md)
|
data/lib/trove/cli.rb
CHANGED
@@ -77,7 +77,7 @@ module Trove
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
column_names = columns.map { |c| c.to_s.sub(/_at\z/, "").upcase }
|
80
|
-
widths = columns.map.with_index { |c, i| [column_names[i].size, data.map { |r| r[c].to_s.size }.max].max }
|
80
|
+
widths = columns.map.with_index { |c, i| [column_names[i].size, data.map { |r| r[c].to_s.size }.max || 0].max }
|
81
81
|
|
82
82
|
output = String.new("")
|
83
83
|
str = widths.map { |w| "%-#{w}s" }.join(" ") + "\n"
|
data/lib/trove/storage/s3.rb
CHANGED
@@ -34,7 +34,7 @@ module Trove
|
|
34
34
|
# delete file if interrupted
|
35
35
|
File.unlink(tmp) if File.exist?(tmp)
|
36
36
|
end
|
37
|
-
rescue Aws::S3::Errors::
|
37
|
+
rescue Aws::S3::Errors::NoSuchKey, Aws::S3::Errors::NotFound
|
38
38
|
raise "File not found"
|
39
39
|
end
|
40
40
|
|
@@ -59,7 +59,7 @@ module Trove
|
|
59
59
|
version: resp.version_id,
|
60
60
|
md5: resp.etag.gsub('"', "")
|
61
61
|
}
|
62
|
-
rescue Aws::S3::Errors::
|
62
|
+
rescue Aws::S3::Errors::NoSuchKey, Aws::S3::Errors::NotFound
|
63
63
|
nil
|
64
64
|
end
|
65
65
|
|
@@ -68,7 +68,7 @@ module Trove
|
|
68
68
|
options[:version_id] = version if version
|
69
69
|
client.delete_object(**options)
|
70
70
|
true
|
71
|
-
rescue Aws::S3::Errors::
|
71
|
+
rescue Aws::S3::Errors::NoSuchKey, Aws::S3::Errors::NotFound
|
72
72
|
false
|
73
73
|
end
|
74
74
|
|
data/lib/trove/version.rb
CHANGED
data/lib/trove.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# stdlib
|
2
2
|
require "digest/md5"
|
3
|
+
require "uri"
|
3
4
|
require "yaml"
|
4
5
|
|
5
6
|
# modules
|
6
|
-
|
7
|
-
|
7
|
+
require_relative "trove/utils"
|
8
|
+
require_relative "trove/version"
|
8
9
|
|
9
10
|
module Trove
|
10
11
|
# storage
|
@@ -30,7 +31,7 @@ module Trove
|
|
30
31
|
# could use upload_file method for multipart uploads over a certain size
|
31
32
|
# but multipart uploads have extra cost and cleanup, so keep it simple for now
|
32
33
|
def push(filename)
|
33
|
-
src =
|
34
|
+
src = resolve_path(filename)
|
34
35
|
raise "File not found" unless File.exist?(src)
|
35
36
|
|
36
37
|
info = storage.info(filename)
|
@@ -89,7 +90,7 @@ module Trove
|
|
89
90
|
private
|
90
91
|
|
91
92
|
def pull_file(filename, version: nil, all: false)
|
92
|
-
dest =
|
93
|
+
dest = resolve_path(filename)
|
93
94
|
|
94
95
|
if !version
|
95
96
|
file = (config["files"] || []).find { |f| f["name"] == filename }
|
@@ -120,15 +121,36 @@ module Trove
|
|
120
121
|
Digest::MD5.file(src).hexdigest != info[:md5]
|
121
122
|
end
|
122
123
|
|
123
|
-
# TODO test file not found
|
124
124
|
def config
|
125
125
|
@config ||= begin
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
126
|
+
config = YAML.load_file(config_path)
|
127
|
+
raise "Empty config" unless config.is_a?(Hash)
|
128
|
+
config
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def config_path
|
133
|
+
@config_path ||= search_tree(".trove.yml")
|
134
|
+
end
|
135
|
+
|
136
|
+
def config_dir
|
137
|
+
File.dirname(config_path)
|
138
|
+
end
|
139
|
+
|
140
|
+
def search_tree(file)
|
141
|
+
path = Dir.pwd
|
142
|
+
# prevent infinite loop
|
143
|
+
20.times do
|
144
|
+
absolute_file = File.join(path, file)
|
145
|
+
return absolute_file if File.exist?(absolute_file)
|
146
|
+
path = File.dirname(path)
|
147
|
+
break if path == "/"
|
131
148
|
end
|
149
|
+
raise "Config not found"
|
150
|
+
end
|
151
|
+
|
152
|
+
def resolve_path(filename)
|
153
|
+
File.join(config_dir, root, filename)
|
132
154
|
end
|
133
155
|
|
134
156
|
def root
|
@@ -137,7 +159,14 @@ module Trove
|
|
137
159
|
|
138
160
|
def storage
|
139
161
|
@storage ||= begin
|
140
|
-
|
162
|
+
raise "Missing storage" unless config["storage"]
|
163
|
+
|
164
|
+
uri =
|
165
|
+
begin
|
166
|
+
URI.parse(config["storage"])
|
167
|
+
rescue URI::InvalidURIError => e
|
168
|
+
raise "Invalid storage"
|
169
|
+
end
|
141
170
|
|
142
171
|
case uri.scheme
|
143
172
|
when "s3"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trove
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-s3
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: rexml
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,49 +39,21 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
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: rake
|
42
|
+
name: thor
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - ">="
|
60
46
|
- !ruby/object:Gem::Version
|
61
47
|
version: '0'
|
62
|
-
type: :
|
48
|
+
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - ">="
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: minitest
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '5'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '5'
|
83
55
|
description:
|
84
|
-
email: andrew@
|
56
|
+
email: andrew@ankane.org
|
85
57
|
executables:
|
86
58
|
- trove
|
87
59
|
extensions: []
|
@@ -108,14 +80,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
80
|
requirements:
|
109
81
|
- - ">="
|
110
82
|
- !ruby/object:Gem::Version
|
111
|
-
version: '
|
83
|
+
version: '3'
|
112
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
85
|
requirements:
|
114
86
|
- - ">="
|
115
87
|
- !ruby/object:Gem::Version
|
116
88
|
version: '0'
|
117
89
|
requirements: []
|
118
|
-
rubygems_version: 3.
|
90
|
+
rubygems_version: 3.4.10
|
119
91
|
signing_key:
|
120
92
|
specification_version: 4
|
121
93
|
summary: Deploy machine learning models in Ruby (and Rails)
|