Skip to content

Commit 9ff5bfb

Browse files
committed
Track failures in update.js and change wp-update.js to be a long running script.
1 parent ad13061 commit 9ff5bfb

File tree

6 files changed

+349
-221
lines changed

6 files changed

+349
-221
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
config.json
22
last-action
33
plugins.db
4+
retry.db
45
node_modules

src/hook.js

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
var semver = require( "semver" ),
2+
Step = require( "step" ),
3+
UserError = require( "./user-error" ),
4+
pluginsDb = require( "./pluginsdb" ),
5+
service = require( "./service" ),
6+
retry = require( "./retry" );
7+
8+
function processHook( data, fn ) {
9+
var repo = service.getRepoByHook( data );
10+
11+
if ( !repo ) {
12+
// TODO: log and bail (no retry)
13+
return fn( new Error( "Could not parse hook." ) );
14+
}
15+
16+
Step(
17+
function() {
18+
processVersions( repo, this );
19+
},
20+
21+
function( error ) {
22+
if ( error ) {
23+
return fn( error );
24+
}
25+
26+
processMeta( repo, this );
27+
},
28+
29+
function( error ) {
30+
fn( error );
31+
}
32+
);
33+
}
34+
35+
function processVersions( repo, fn ) {
36+
Step(
37+
// get all tags for the repo
38+
function() {
39+
pluginsDb.getTags( repo.getId(), this.parallel() );
40+
repo.getVersionTags( this.parallel() );
41+
},
42+
43+
// filter to new versions
44+
function( error, processedTags, tags ) {
45+
if ( error ) {
46+
retry.log( "processVersions", repo.getId() );
47+
return fn( error );
48+
}
49+
50+
return tags.filter(function( tag ) {
51+
return !(tag in processedTags);
52+
});
53+
},
54+
55+
// get releases
56+
function( error, tags ) {
57+
if ( error ) {
58+
retry.log( "processVersions", repo.getId() );
59+
return fn( error );
60+
}
61+
62+
if ( !tags.length ) {
63+
return fn( null );
64+
}
65+
66+
this.parallel()( null, tags );
67+
var group = this.group();
68+
tags.forEach(function( tag ) {
69+
repo.getRelease( tag, group() );
70+
});
71+
},
72+
73+
// filter to valid releases
74+
function( error, tags, releases ) {
75+
if ( error ) {
76+
retry.log( "processVersions", repo.getId() );
77+
return fn( error );
78+
}
79+
80+
var releasesCb = this.parallel(),
81+
invalidGroup = this.group();
82+
releasesCb( null, releases.filter(function( release, i ) {
83+
if ( release ) {
84+
return true;
85+
}
86+
87+
// TODO: gracefully handle duplicates in case of retry
88+
// track invalid tags so we don't process them on each update
89+
pluginsDb.addTag( repo.getId(), tags[ i ], invalidGroup() );
90+
return false;
91+
}));
92+
},
93+
94+
// process the releases
95+
function( error, releases ) {
96+
if ( error ) {
97+
retry.log( "processVersions", repo.getId() );
98+
return fn( error );
99+
}
100+
101+
if ( !releases.length ) {
102+
return fn( null );
103+
}
104+
105+
var group = this.group();
106+
releases.forEach(function( release ) {
107+
processRelease( repo, release, group() );
108+
});
109+
},
110+
111+
function( error ) {
112+
fn( error );
113+
}
114+
);
115+
}
116+
117+
function processRelease( repo, release, fn ) {
118+
Step(
119+
// find out who owns this plugin
120+
// if there is no owner, then set the user as the owner
121+
function() {
122+
pluginsDb.getOrSetOwner( release.package.name, repo.userName, this );
123+
},
124+
125+
// verify the user is the owner
126+
function( error, owner ) {
127+
if ( error ) {
128+
retry.log( "processRelease", repo.getId(), release.tag );
129+
return fn( error );
130+
}
131+
132+
// the plugin is owned by someone else
133+
if ( owner !== repo.userName ) {
134+
// TODO: report error to user
135+
return fn( new UserError( "Plugin " + release.package.name + " is owned by " + owner + "." ) );
136+
}
137+
138+
return owner;
139+
},
140+
141+
// track the new release
142+
function( error, owner ) {
143+
pluginsDb.addRelease( repo.getId(), release, this );
144+
},
145+
146+
// finished processing release
147+
function( error ) {
148+
if ( error ) {
149+
retry.log( "processRelease", repo.getId(), release.tag );
150+
return fn( error );
151+
}
152+
153+
console.log( "Added " + release.package.name + " " + release.package.version + " to plugins DB" );
154+
fn( null, release );
155+
}
156+
);
157+
}
158+
159+
function processMeta( repo, fn ) {
160+
Step(
161+
function() {
162+
repo.getPackageJson( null, this );
163+
},
164+
165+
function( error, package ) {
166+
if ( error ) {
167+
retry.log( "processMeta", repo.getId() );
168+
return fn( error );
169+
}
170+
171+
if ( !package || !package.name ) {
172+
return fn( null );
173+
}
174+
175+
pluginsDb.updatePlugin( package.name, repo.userName, {
176+
watchers: repo.watchers,
177+
forks: repo.forks
178+
}, this );
179+
},
180+
181+
function( error ) {
182+
if ( error ) {
183+
retry.log( "processMeta", repo.getId() );
184+
return fn( error );
185+
}
186+
187+
fn( null );
188+
}
189+
);
190+
}
191+
192+
module.exports = {
193+
processHook: processHook,
194+
processVersions: processVersions,
195+
processRelease: processRelease,
196+
processMeta: processMeta
197+
};

src/retry.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
var sqlite = require( "sqlite3" );
2+
3+
var db;
4+
5+
function connect( fn ) {
6+
db = new sqlite.Database( "retry.db", fn );
7+
}
8+
9+
function auto( fn ) {
10+
return function() {
11+
var that = this,
12+
args = arguments;
13+
14+
if ( db ) {
15+
return fn.apply( that, args );
16+
}
17+
18+
connect(function( error ) {
19+
if ( error ) {
20+
return fn( error );
21+
}
22+
23+
fn.apply( that, args );
24+
});
25+
};
26+
}
27+
28+
module.exports = {
29+
log: auto(function( method ) {
30+
var str, fn,
31+
args = [].slice.call( arguments, 1 );
32+
33+
if ( typeof args[ args.length - 1 ] === "function" ) {
34+
fn = args.pop();
35+
}
36+
37+
str = JSON.stringify({
38+
method: method,
39+
args: args
40+
});
41+
42+
db.run( "INSERT OR IGNORE INTO retry( retry ) VALUES( ? )",
43+
[ str ], fn );
44+
}),
45+
46+
_reset: function( fn ) {
47+
var fs = require( "fs" ),
48+
Step = require( "step" );
49+
50+
Step(
51+
function() {
52+
fs.unlink( "retry.db", this );
53+
},
54+
55+
function( error ) {
56+
if ( !error || error.code === "ENOENT" ) {
57+
return connect( this );
58+
}
59+
60+
fn( error );
61+
},
62+
63+
function( error ) {
64+
if ( error ) {
65+
return fn( error );
66+
}
67+
68+
db.run( "CREATE TABLE retry (" +
69+
"retry TEXT PRIMARY KEY, " +
70+
"timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP" +
71+
")", this );
72+
},
73+
74+
function( error ) {
75+
fn( error );
76+
}
77+
);
78+
}
79+
};

src/setup.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ var Step = require( "step" ),
22
rimraf = require( "rimraf" ),
33
pluginsDb = require( "./pluginsdb" ),
44
wordpress = require( "./wordpress" ),
5+
retry = require( "./retry" ),
56
config = require( "./config" );
67

78
Step(
89
function() {
910
pluginsDb._reset( this.parallel() );
1011
wordpress._reset( this.parallel() );
12+
retry._reset( this.parallel() );
1113
rimraf( config.repoDir, this.parallel() );
1214
rimraf( "last-action", this.parallel() );
1315
},

0 commit comments

Comments
 (0)