Skip to content
This repository was archived by the owner on Jul 15, 2025. It is now read-only.

Commit e18a95e

Browse files
author
Philippe Lafoucrière
committed
Merge branch '0.2.6'
2 parents 77dbe94 + 0bf1ec0 commit e18a95e

File tree

13 files changed

+196
-51
lines changed

13 files changed

+196
-51
lines changed

.goxc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AppName": "gemnasium",
33
"BuildConstraints": "linux darwin windows",
44
"ConfigVersion": "0.9",
5-
"PackageVersion": "0.2.5"
5+
"PackageVersion": "0.2.6"
66
}

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ language: go
33
go:
44
- 1.2
55
- 1.3
6+
- 1.4
67
- tip

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
0.2.6 / 2015-02-21
2+
3+
* "liveeval" command now returns 1 if runtime status is red
4+
* Better error logging: error message from API is now displayed
5+
* Autoupdate command is now split into `run` and `apply`. The command `gemnasium autoupdate` is now `gemnasium autoupdate run`. `apply` will fetch the best set of dependencies from gemnasium (after `run` returned a success).
6+
17
0.2.5 / 2014-08-05
28

39
* Fix dependency files push (gemnasium df push)

README.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Gemnasium toolbelt is a CLI for the Gemnasium API.
66

7-
## How to install it ?
7+
## How to install it?
88

99
### On Mac OS X
1010

@@ -16,10 +16,25 @@ And then
1616

1717
brew install gemnasium-toolbelt
1818

19-
If you don't want to use Homebrew, check out the Binaries section bellow.
20-
Or you can build it yourself by running:
19+
### Ubuntu and Debian
2120

22-
go build -o gemnasium
21+
#### Configure Gemnasium repository
22+
23+
sudo sh -c 'echo "deb http://apt.gemnasium.com stable main" > /etc/apt/sources.list.d/gemnasium.list'
24+
25+
#### Trust Gemnasium GPG key
26+
27+
sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com E5CEAB0AC5F1CA2A
28+
29+
#### Update package list
30+
31+
sudo apt-get update
32+
33+
#### Install Gemnasium toolbelt
34+
35+
sudo apt-get install gemnasium-toolbelt
36+
37+
The ```gemnasium``` command will be available in ```/usr/bin/gemnasium```
2338

2439
### From source
2540

@@ -31,15 +46,15 @@ Or you can build it yourself by running:
3146

3247
Binaries are available in the [releases](https://github.com/gemnasium/toolbelt/releases) page.
3348

34-
## How to use it ?
49+
## How to use it?
3550

3651
### Authentication
3752

3853
Gemnasium Toolbelt stores your Gemnasium API key into your .netrc file.
3954

4055
To be logged in to Gemnasium, you need to run `gemnasium auth login` and enter your Gemnasium credentials.
4156

42-
Alternatively, you can pass directly your API token to all commands with the option `--token` or the env var GEMNASIUM_TOKEN
57+
Alternatively, you can pass directly your API token to all commands with the option `--token` or the env var ```GEMNASIUM_TOKEN```.
4358
Your API token is available in your settings page (https://gemnasium.com/settings).
4459

4560
### Create a new project
@@ -52,11 +67,19 @@ To create a new project on Gemnasium, you need to `cd` into your project directo
5267

5368
If your project is already on Gemnasium, you need to `cd` into your project directory and run
5469

55-
gemnasium projects configure
70+
gemnasium configure [project_slug]
5671

5772
You will need your project's Slug (available in your project page settings).
5873
A sample configuration file is available here: https://github.com/gemnasium/toolbelt/blob/master/config/gemnasium.yml.example
5974

75+
### Push dependency files
76+
77+
For projects not automatically synced with Github or Gitlab, you may want to push your files directly to Gemnasium.
78+
The corresponding project will updated soon after the files have been received. To push your files
79+
80+
gemnasium dependency_files push -f=Gemfile,Gemfile.lock
81+
82+
6083
### Live Evaluation
6184

6285
If you want to evaluate your project without pushing files or pulling info from Gemnasium, you may use the ```eval``` command:
@@ -119,7 +142,7 @@ To obtain the list of env vars used and set:
119142

120143
gemnasium env
121144

122-
### Need further help ?
145+
### Need further help?
123146

124147
A full commands documentation is available by running
125148

autoupdate/auto_update.go

Lines changed: 76 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,59 @@ type UpdateSetResult struct {
5454

5555
var ErrProjectRevisionEmpty error = fmt.Errorf("The current revision (%s) is unknown on Gemnasium, please push your dependency files before running autoupdate.\nSee `gemnasium df help push`.\n", utils.GetCurrentRevision())
5656

57+
// Apply the best dependency files that have been found so far
58+
func Apply(projectSlug string, testSuite []string) error {
59+
err := checkProject(projectSlug)
60+
if err != nil {
61+
return err
62+
}
63+
64+
dfiles, err := fetchDependencyFiles(projectSlug)
65+
if err != nil {
66+
return err
67+
}
68+
69+
err = updateDepFiles(dfiles)
70+
if err != nil {
71+
fmt.Printf("Error while restoring files: %s\n", err)
72+
return err
73+
}
74+
// No need to try the update, it will fail
75+
76+
return nil
77+
}
78+
79+
// Fetch the best dependency files that have been found so far
80+
func fetchDependencyFiles(projectSlug string) (dfiles []models.DependencyFile, err error) {
81+
revision, err := getRevision()
82+
if err != nil {
83+
return nil, err
84+
}
85+
86+
opts := &gemnasium.APIRequestOptions{
87+
Method: "GET",
88+
URI: fmt.Sprintf("/projects/%s/revisions/%s/auto_update_steps/best", projectSlug, revision),
89+
Result: &dfiles,
90+
}
91+
err = gemnasium.APIRequest(opts)
92+
return dfiles, err
93+
}
94+
95+
// Update dependency files with given one (best dependency files)
96+
// REFACTOR: this is very similar to restoreDepFiles
97+
func updateDepFiles(dfiles []models.DependencyFile) error {
98+
fmt.Printf("%d file(s) to be updated.\n", len(dfiles))
99+
for _, df := range dfiles {
100+
fmt.Printf("Updating file %s: ", df.Path)
101+
err := ioutil.WriteFile(df.Path, df.Content, 0644)
102+
if err != nil {
103+
return err
104+
}
105+
fmt.Printf("done\n")
106+
}
107+
return nil
108+
}
109+
57110
// Download and loop over update sets, apply changes, run test suite, and finally notify gemnasium
58111
func Run(projectSlug string, testSuite []string) error {
59112
err := checkProject(projectSlug)
@@ -68,7 +121,6 @@ func Run(projectSlug string, testSuite []string) error {
68121
return errors.New("Arg [testSuite] can't be empty")
69122
}
70123

71-
fmt.Printf("Executing test script: ")
72124
out, err := executeTestSuite(testSuite)
73125
if err != nil {
74126
fmt.Println("Aborting, initial test suite run is failing:")
@@ -149,23 +201,19 @@ func Run(projectSlug string, testSuite []string) error {
149201
}
150202

151203
func fetchUpdateSet(projectSlug string) (*UpdateSet, error) {
152-
revision := utils.GetCurrentRevision()
153-
if revision == "" {
154-
return nil, errors.New("Can't determine current revision, please use REVISION env var to specify it")
204+
revision, err := getRevision()
205+
if err != nil {
206+
return nil, err
155207
}
208+
156209
var updateSet *UpdateSet
157210
opts := &gemnasium.APIRequestOptions{
158211
Method: "POST",
159-
URI: fmt.Sprintf("/projects/%s/branches/%s/update_sets/next", projectSlug, utils.GetCurrentBranch()),
160-
Body: &map[string]string{"revision": revision},
212+
URI: fmt.Sprintf("/projects/%s/revisions/%s/auto_update_steps/next", projectSlug, revision),
161213
Result: &updateSet,
162214
}
163-
err := gemnasium.APIRequest(opts)
164-
if err != nil {
165-
return nil, err
166-
}
167-
168-
return updateSet, nil
215+
err = gemnasium.APIRequest(opts)
216+
return updateSet, err
169217
}
170218

171219
// Patch files if needed, and update packages
@@ -208,12 +256,17 @@ func pushUpdateSetResult(rs *UpdateSetResult) error {
208256
return errors.New("Missing updateSet ID and/or State args")
209257
}
210258

259+
revision, err := getRevision()
260+
if err != nil {
261+
return err
262+
}
263+
211264
opts := &gemnasium.APIRequestOptions{
212265
Method: "PATCH",
213-
URI: fmt.Sprintf("/projects/%s/branches/%s/update_sets/%d", rs.ProjectSlug, utils.GetCurrentBranch(), rs.UpdateSetID),
266+
URI: fmt.Sprintf("/projects/%s/revisions/%s/auto_update_steps/%d", rs.ProjectSlug, revision, rs.UpdateSetID),
214267
Body: rs,
215268
}
216-
err := gemnasium.APIRequest(opts)
269+
err = gemnasium.APIRequest(opts)
217270
if err != nil {
218271
return err
219272
}
@@ -246,7 +299,7 @@ func executeTestSuite(ts []string) ([]byte, error) {
246299
defer close(done)
247300
var out []byte
248301
var err error
249-
fmt.Printf("Executing test script")
302+
fmt.Printf("Executing test script: ")
250303
start := time.Now()
251304
go func() {
252305
result, err := exec.Command(ts[0], ts[1:]...).Output()
@@ -282,3 +335,11 @@ func checkProject(slug string) error {
282335
}
283336
return nil
284337
}
338+
339+
func getRevision() (string, error) {
340+
revision := utils.GetCurrentRevision()
341+
if revision == "" {
342+
return revision, errors.New("Can't determine current revision, please use REVISION env var to specify it")
343+
}
344+
return revision, nil
345+
}

commands/app.go

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,20 @@ func App() (*cli.App, error) {
186186
{
187187
Name: "autoupdate",
188188
ShortName: "au",
189-
Usage: "Auto-update will test updates in your project, and notify Gemnasium of the result",
190-
Flags: []cli.Flag{
191-
cli.StringFlag{
192-
Name: "project, p",
193-
Usage: "Project slug (identifier on Gemnasium)",
194-
},
195-
},
196-
Description: `Auto-Update will fetch update sets from Gemnasium and run your test suite against them.
189+
Usage: "Auto-update the dependency files of the project",
190+
Before: auth.AttemptLogin,
191+
Subcommands: []cli.Command{
192+
{
193+
Name: "run",
194+
ShortName: "r",
195+
Usage: "Run the auto-update",
196+
Flags: []cli.Flag{
197+
cli.StringFlag{
198+
Name: "project, p",
199+
Usage: "Project slug (identifier on Gemnasium)",
200+
},
201+
},
202+
Description: `Auto-Update will fetch update sets from Gemnasium and run your test suite against them.
197203
The test suite can be passed as arguments, or through the env var GEMNASIUM_TESTSUITE.
198204
199205
Arguments:
@@ -215,7 +221,22 @@ func App() (*cli.App, error) {
215221
- cat script.sh | gemnasium autoupdate -p=your_project_slug
216222
- gemnasium autoupdate my_project_slug bundle exec rake
217223
`,
218-
Action: AutoUpdate,
224+
Action: AutoUpdateRun,
225+
},
226+
{
227+
Name: "apply",
228+
ShortName: "a",
229+
Usage: "Apply the best update",
230+
Flags: []cli.Flag{
231+
cli.StringFlag{
232+
Name: "project, p",
233+
Usage: "Project slug (identifier on Gemnasium)",
234+
},
235+
},
236+
Description: `Update the dependency files to match the best update that has been found so far.`,
237+
Action: AutoUpdateApply,
238+
},
239+
},
219240
},
220241
{
221242
Name: "env",

commands/auto-update.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,26 @@ import (
88
"github.com/gemnasium/toolbelt/utils"
99
)
1010

11-
var auFunc = func(projectSlug string, args []string) error {
11+
var auRunFunc = func(projectSlug string, args []string) error {
1212
return autoupdate.Run(projectSlug, args)
1313
}
1414

15-
func AutoUpdate(ctx *cli.Context) {
15+
var auApplyFunc = func(projectSlug string, args []string) error {
16+
return autoupdate.Apply(projectSlug, args)
17+
}
18+
19+
func AutoUpdateRun(ctx *cli.Context) {
20+
auth.AttemptLogin(ctx)
21+
project, err := models.GetProject(ctx.String("project"))
22+
utils.ExitIfErr(err)
23+
err = auRunFunc(project.Slug, ctx.Args())
24+
utils.ExitIfErr(err)
25+
}
26+
27+
func AutoUpdateApply(ctx *cli.Context) {
1628
auth.AttemptLogin(ctx)
1729
project, err := models.GetProject(ctx.String("project"))
1830
utils.ExitIfErr(err)
19-
err = auFunc(project.Slug, ctx.Args())
31+
err = auApplyFunc(project.Slug, ctx.Args())
2032
utils.ExitIfErr(err)
2133
}

commands/auto-update_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import (
77
"github.com/gemnasium/toolbelt/config"
88
)
99

10-
func TestAutoUpdate(t *testing.T) {
10+
func TestAutoUpdateRun(t *testing.T) {
1111
config.APIKey = "abcdef123"
1212
config.ProjectSlug = "projectSlug"
1313

1414
var project string
15-
auFunc = func(slug string, args []string) error {
15+
auRunFunc = func(slug string, args []string) error {
1616
project = slug
1717
return nil
1818
}
@@ -22,23 +22,23 @@ func TestAutoUpdate(t *testing.T) {
2222
}
2323

2424
// Call autoupdate command
25-
os.Args = []string{"gemnasium", "autoupdate"}
25+
os.Args = []string{"gemnasium", "autoupdate", "run"}
2626
app.Run(os.Args)
2727
if project != "projectSlug" {
2828
t.Errorf("Should have called autoupdate func\n")
2929
}
3030

3131
// With alias
3232
project = ""
33-
os.Args = []string{"gemnasium", "au"}
33+
os.Args = []string{"gemnasium", "au", "r"}
3434
app.Run(os.Args)
3535
if project != "projectSlug" {
3636
t.Errorf("Should have called autoupdate func\n")
3737
}
3838

3939
// with Flag
4040
project = ""
41-
os.Args = []string{"gemnasium", "au", "-p=slug"}
41+
os.Args = []string{"gemnasium", "au", "r", "-p=slug"}
4242
app.Run(os.Args)
4343
if project != "slug" {
4444
t.Errorf("Should have called autoupdate func\n")

config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ var (
1818
)
1919

2020
const (
21-
VERSION = "0.2.5"
21+
VERSION = "0.2.6"
2222
CONFIG_FILE_PATH = ".gemnasium.yml"
2323

2424
// Don't forget to update DisplayEnvVars func bellow when updating vars

debian/changelog

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
gemnasium-toolbelt (0.2.6-1) stable; urgency=low
2+
3+
* Added go 1.4.1 to test matrix
4+
* "liveeval" command now returns 1 if runtime status is red
5+
* Better error logging: error message from API is now displayed
6+
* Autoupdate command is now split into `run` and `apply`. The command `gemnasium autoupdate` is now `gemnasium autoupdate run`. `apply` will fetch the best set of dependencies from gemnasium (after `run` returned a success).
7+
8+
-- Gemnasium <[email protected]> Thu, 12 Feb 2015 11:36:18 +0100
9+
110
gemnasium-toolbelt (0.2.5-2) stable; urgency=low
211

312
* Allows for i386 packages.

0 commit comments

Comments
 (0)