diff --git a/.localeapp/log.yml b/.localeapp/log.yml
index b1866c16..1c42b9c4 100644
--- a/.localeapp/log.yml
+++ b/.localeapp/log.yml
@@ -1,3 +1,3 @@
---
-:polled_at: 1358204368
-:updated_at: 1358204368
+:polled_at: 1361792606
+:updated_at: 1361792606
diff --git a/.travis.yml b/.travis.yml
index f67d57ef..a220d0f9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,6 +16,7 @@ env:
script: "script/ci"
after_script:
+ - "ENV=production bundle exec rakep"
- "test $TEST_SUITE = \"ember\" && travis-artifacts upload --target-path assets/$TRAVIS_BRANCH --path public/scripts:scripts --path public/styles:styles"
matrix:
diff --git a/README.md b/README.md
index bec3363a..eac08eba 100644
--- a/README.md
+++ b/README.md
@@ -28,10 +28,30 @@ This will run against API run locally.
### Running the spec suite
-To run the test suite, you must first start the app (see above).
+First, start the app (see above).
bundle exec foreman start
-Then run rspec against the spec/ directory
+To run the Ruby specs, run rspec against the spec/ directory:
bundle exec rspec spec/
+
+To run the Jasmine specs, open the spec page: [localhost:5000/spec.html](http://localhost:5000/spec.html)
+
+### i18n
+
+Localization for travis-web is managed via [localeapp](http://localeapp.com).
+If you are interested in improving the existing localizations or adding
+a new locale, please contact us on irc (#travis) and we will set you up.
+
+Please do **not** edit the YAML files directly.
+
+Localization data can be synced with the following rake task:
+
+ bundle exec localeapp:update
+
+This will publish any new keys in en.yml, as well as any missing keys
+from your handlebars templates and pull down the latest localizations.
+
+*note*: You will need to have the localeapp api key exported to
+LOCALEAPP_API_KEY
diff --git a/assets/scripts/app/auth.coffee b/assets/scripts/app/auth.coffee
index f99bd68f..b7e29e16 100644
--- a/assets/scripts/app/auth.coffee
+++ b/assets/scripts/app/auth.coffee
@@ -13,6 +13,8 @@
Travis.setLocale Travis.default_locale
@set('state', 'signed-out')
@set('user', undefined)
+ Travis.__container__.lookup('controller:currentUser').set('content', null)
+ Travis.__container__.lookup('router:main').send('afterSignOut')
signIn: ->
@set('state', 'signing-in')
@@ -51,12 +53,13 @@
@storeData(data, Travis.storage) unless @userDataFrom(Travis.storage)
user = @loadUser(data.user)
# TODO: we should not use __container__ directly, how to do it better?
+ # A good answer seems to do auth in context of controller.
Travis.__container__.lookup('controller:currentUser').set('content', user)
@set('state', 'signed-in')
Travis.setLocale(data.user.locale || Travis.default_locale)
Travis.trigger('user:signed_in', data.user)
- #@get('app.router').send('afterSignIn', @readAfterSignInPath())
+ Travis.__container__.lookup('router:main').send('afterSignIn', @readAfterSignInPath())
storeData: (data, storage) ->
storage.setItem('travis.token', data.token)
diff --git a/assets/scripts/app/controllers/builds.coffee b/assets/scripts/app/controllers/builds.coffee
index c06b8d04..ffe4f3d7 100644
--- a/assets/scripts/app/controllers/builds.coffee
+++ b/assets/scripts/app/controllers/builds.coffee
@@ -2,6 +2,15 @@ Travis.BuildsController = Em.ArrayController.extend
# sortAscending: false
needs: ['repo']
- repoBinding: 'controllers.repo'
- buildsBinding: 'repo.builds'
+ repoBinding: 'controllers.repo.repo'
+ buildsBinding: 'controllers.repo.builds'
tabBinding: 'controllers.repo.tab'
+
+ showMore: ->
+ id = @get('repo.id')
+ number = @get('builds.lastObject.number')
+ @get('builds').load Travis.Build.olderThanNumber(id, number, @get('tab'))
+
+ displayShowMoreButton: (->
+ @get('tab') != 'branches'
+ ).property('tab')
diff --git a/assets/scripts/app/controllers/repo.coffee b/assets/scripts/app/controllers/repo.coffee
index 0c9fb60c..556dd5dc 100644
--- a/assets/scripts/app/controllers/repo.coffee
+++ b/assets/scripts/app/controllers/repo.coffee
@@ -86,4 +86,4 @@ Travis.RepoController = Travis.Controller.extend
urlGithub: (->
Travis.Urls.githubRepo(@get('repo.slug'))
- ).property('repo.slug'),
+ ).property('repo.slug')
diff --git a/assets/scripts/app/controllers/sidebar.coffee b/assets/scripts/app/controllers/sidebar.coffee
index 8dd299ae..390ffdad 100644
--- a/assets/scripts/app/controllers/sidebar.coffee
+++ b/assets/scripts/app/controllers/sidebar.coffee
@@ -18,6 +18,9 @@ Travis.reopen
name: queue.display
@set 'content', queues
+ showAll: (queue) ->
+ queue.showAll()
+
WorkersController: Em.ArrayController.extend
init: ->
@_super.apply this, arguments
diff --git a/assets/scripts/app/models/build.coffee b/assets/scripts/app/models/build.coffee
index e383d51c..3ea6994c 100644
--- a/assets/scripts/app/models/build.coffee
+++ b/assets/scripts/app/models/build.coffee
@@ -10,7 +10,7 @@ require 'travis/model'
branch: DS.attr('string')
message: DS.attr('string')
_duration: DS.attr('number')
- _config: DS.attr('string')
+ _config: DS.attr('object')
startedAt: DS.attr('string')
finishedAt: DS.attr('string')
@@ -75,6 +75,11 @@ require 'travis/model'
branches: (options) ->
@find repository_id: options.repoId, branches: true
- olderThanNumber: (id, build_number) ->
+ olderThanNumber: (id, build_number, type) ->
+ console.log type
# TODO fix this api and use some kind of pagination scheme
- @find(url: "/builds", repository_id: id, after_number: build_number)
+ options = { repository_id: id, after_number: build_number }
+ if type?
+ options.event_type = type.replace(/s$/, '') # poor man's singularize
+
+ @find(options)
diff --git a/assets/scripts/app/models/job.coffee b/assets/scripts/app/models/job.coffee
index bd6e9cfc..e92f3329 100644
--- a/assets/scripts/app/models/job.coffee
+++ b/assets/scripts/app/models/job.coffee
@@ -19,6 +19,13 @@ require 'travis/model'
commit: DS.belongsTo('Travis.Commit')
commits: DS.belongsTo('Travis.Commit')
+ # this is a fake relationship just to get rid
+ # of ember data's bug: https://github.com/emberjs/data/issues/758
+ # TODO: remove when this issue is fixed
+ fakeBuild: DS.belongsTo('Travis.Build')
+
+ _config: DS.attr('object')
+
log: ( ->
Travis.Log.create(job: this)
).property()
@@ -32,8 +39,8 @@ require 'travis/model'
).property('repoSlug', 'repoId')
config: (->
- Travis.Helpers.compact(@get('data.config'))
- ).property('data.config')
+ Travis.Helpers.compact(@get('_config'))
+ ).property('_config')
isFinished: (->
@get('state') in ['passed', 'failed', 'errored', 'canceled']
diff --git a/assets/scripts/app/models/repo.coffee b/assets/scripts/app/models/repo.coffee
index 7dbedb50..332063b1 100644
--- a/assets/scripts/app/models/repo.coffee
+++ b/assets/scripts/app/models/repo.coffee
@@ -22,12 +22,7 @@ require 'travis/model'
).property('lastBuildId', 'lastBuildNumber')
allBuilds: (->
- allBuilds = DS.RecordArray.create
- type: Travis.Build
- content: Ember.A([])
- store: @get('store')
- @get('store').registerRecordArray(allBuilds, Travis.Build);
- allBuilds
+ Travis.Build.find()
).property()
builds: (->
@@ -42,7 +37,7 @@ require 'travis/model'
array.load(builds)
id = @get('id')
- array.observe(@get('allBuilds'), (build) -> build.get('repo.id') == id && !build.get('isPullRequest') )
+ array.observe(@get('allBuilds'), (build) -> build.get('isLoaded') && build.get('eventType') && build.get('repo.id') == id && !build.get('isPullRequest') )
array
).property()
@@ -58,7 +53,7 @@ require 'travis/model'
array.load(builds)
id = @get('id')
- array.observe(@get('allBuilds'), (build) -> @get('repositoryId') == id && build.get('isPullRequest') )
+ array.observe(@get('allBuilds'), (build) -> build.get('isLoaded') && build.get('eventType') && build.get('repo.id') == id && build.get('isPullRequest') )
array
).property()
diff --git a/assets/scripts/app/routes.coffee b/assets/scripts/app/routes.coffee
index 026159aa..b83091c8 100644
--- a/assets/scripts/app/routes.coffee
+++ b/assets/scripts/app/routes.coffee
@@ -1,4 +1,5 @@
require 'travis/location'
+require 'travis/line_number_parser'
Ember.Router.reopen
location: (if testMode? then Ember.HashLocation.create() else Travis.Location.create())
@@ -7,6 +8,36 @@ Ember.Router.reopen
url = url.replace(/#.*?$/, '')
@_super(url)
+# TODO: don't reopen Ember.Route to add events, there should be
+# a better way (like "parent" resource for everything inside map)
+Ember.Route.reopen
+ events:
+ afterSignIn: (path) ->
+ @routeTo(path)
+
+ afterSignOut: ->
+ @routeTo('/')
+
+ routeTo: (path) ->
+ return unless path
+ @router.handleURL(path)
+ @router.location.setURL(path)
+
+ signedIn: ->
+ @controllerFor('currentUser').get('content')
+
+ redirect: ->
+ if @get('needsAuth')
+ @authorize(@router.location.getURL())
+ else
+ @_super.apply this, arguments
+ Travis.autoSignIn() unless @signedIn()
+
+ authorize: (path) ->
+ if !@signedIn()
+ Travis.storeAfterSignInPath(path)
+ @transitionTo('auth')
+
Travis.Router.map ->
@resource 'index', path: '/', ->
@route 'current', path: '/'
@@ -19,6 +50,7 @@ Travis.Router.map ->
@resource 'branches', path: '/branches'
@route 'stats', path: '/stats'
+ @route 'auth', path: '/auth'
@resource 'profile', path: '/profile', ->
@route 'index', path: '/'
@@ -34,18 +66,18 @@ Travis.IndexCurrentRoute = Ember.Route.extend
setupController: ->
@container.lookup('controller:repo').activate('index')
-Travis.AbstractBuidsRoute = Ember.Route.extend
+Travis.AbstractBuildsRoute = Ember.Route.extend
renderTemplate: ->
@render 'builds', outlet: 'pane', into: 'repo'
setupController: ->
@container.lookup('controller:repo').activate(@get('contentType'))
-Travis.BuildsRoute = Travis.AbstractBuidsRoute.extend(contentType: 'builds')
-Travis.PullRequestsRoute = Travis.AbstractBuidsRoute.extend(contentType: 'pull_requests')
-Travis.BranchesRoute = Travis.AbstractBuidsRoute.extend(contentType: 'branches')
+Travis.BuildsRoute = Travis.AbstractBuildsRoute.extend(contentType: 'builds')
+Travis.PullRequestsRoute = Travis.AbstractBuildsRoute.extend(contentType: 'pull_requests')
+Travis.BranchesRoute = Travis.AbstractBuildsRoute.extend(contentType: 'branches')
-Travis.BuildRoute = Ember.Route.extend
+Travis.BuildRoute = Ember.Route.extend Travis.LineNumberParser,
renderTemplate: ->
@render 'build', outlet: 'pane', into: 'repo'
@@ -57,11 +89,14 @@ Travis.BuildRoute = Ember.Route.extend
setupController: (controller, model) ->
model = Travis.Build.find(model) if model && !model.get
+ if lineNumber = @fetchLineNumber()
+ controller.set('lineNumber', lineNumber)
+
repo = @container.lookup('controller:repo')
repo.set('build', model)
repo.activate('build')
-Travis.JobRoute = Ember.Route.extend
+Travis.JobRoute = Ember.Route.extend Travis.LineNumberParser,
renderTemplate: ->
@render 'job', outlet: 'pane', into: 'repo'
@@ -73,6 +108,9 @@ Travis.JobRoute = Ember.Route.extend
setupController: (controller, model) ->
model = Travis.Job.find(model) if model && !model.get
+ if lineNumber = @fetchLineNumber()
+ controller.set('lineNumber', lineNumber)
+
repo = @container.lookup('controller:repo')
console.log model.toString()
repo.set('job', model)
@@ -143,6 +181,8 @@ Travis.StatsRoute = Ember.Route.extend
@container.lookup('controller:application').connectLayout('simple')
Travis.ProfileRoute = Ember.Route.extend
+ needsAuth: true
+
setupController: ->
@container.lookup('controller:application').connectLayout('profile')
@container.lookup('controller:accounts').set('content', Travis.Account.find())
@@ -160,7 +200,7 @@ Travis.ProfileIndexRoute = Ember.Route.extend
@container.lookup('controller:profile').activate 'hooks'
renderTemplate: ->
- @render 'hooks', outlet: 'pane', into: 'profile'
+ @render 'hooks', outlet: 'pane', into: 'profile', controller: 'profile'
Travis.AccountRoute = Ember.Route.extend
setupController: (controller, account) ->
@@ -208,3 +248,13 @@ Travis.AccountProfileRoute = Ember.Route.extend
renderTemplate: ->
@render 'user', outlet: 'pane', into: 'profile'
+
+Travis.AuthRoute = Ember.Route.extend
+ renderTemplate: ->
+ $('body').attr('id', 'auth')
+
+ @render 'top', outlet: 'top'
+ @render 'auth.signin'
+
+ setupController: ->
+ @container.lookup('controller:application').connectLayout('simple')
diff --git a/assets/scripts/app/store.coffee b/assets/scripts/app/store.coffee
index ba2e6994..cf8f8d5c 100644
--- a/assets/scripts/app/store.coffee
+++ b/assets/scripts/app/store.coffee
@@ -52,7 +52,6 @@ Travis.Store = DS.Store.extend
!!@typeMapFor(type).idToCid[id]
receive: (event, data) ->
- #console.log event, data
[name, type] = event.split(':')
mappings = @adapter.get('mappings')
@@ -142,8 +141,6 @@ Travis.Store = DS.Store.extend
result = @merge(type, hash, true)
if result && result.clientId
@addLoadedData(type, result.clientId, hash)
- # TODO: it will be probably needed to uncomment and fix this
- #@_updateAssociations(type, type.singularName(), hash)
result
@@ -161,14 +158,3 @@ Travis.Store = DS.Store.extend
root = type.pluralName()
@adapter.sideload(store, type, json, root)
@loadMany(type, json[root])
-
- _updateAssociations: (type, name, data) ->
- Em.get(type, 'associationsByName').forEach (key, meta) =>
- if meta.kind == 'belongsTo'
- id = data["#{key}_id"]
- if clientId = @typeMapFor(meta.type).idToCid[id]
- if parent = this.findByClientId(meta.type, clientId, id)
- dataProxy = parent.get('data')
- if ids = dataProxy.get("#{name}_ids")
- ids.pushObject(data.id) unless data.id in ids
- parent.send('didChangeData');
diff --git a/assets/scripts/app/store/rest_adapter.coffee b/assets/scripts/app/store/rest_adapter.coffee
index eb422316..d8a402f4 100644
--- a/assets/scripts/app/store/rest_adapter.coffee
+++ b/assets/scripts/app/store/rest_adapter.coffee
@@ -7,6 +7,22 @@ DS.JSONTransforms['object'] = {
}
Travis.Serializer = DS.RESTSerializer.extend
+ # The next 3 methods specify the behavior of adding records to dirty sets
+ # (ie. which records will be treated as dirty on the next commit). We don't
+ # allow to change most of the records on the client, so for anything except
+ # the User, we ignore dirtyiness.
+ dirtyRecordsForAttributeChange: (dirtySet, record) ->
+ if record.constructor == Travis.User
+ @_super.apply this, arguments
+
+ dirtyRecordsForBelongsToChange: (dirtySet, record) ->
+ if record.constructor == Travis.User
+ @_super.apply this, arguments
+
+ dirtyRecordsForHasManyChange: (dirtySet, record) ->
+ if record.constructor == Travis.User
+ @_super.apply this, arguments
+
merge: (record, serialized) ->
data = record.get('data')
@@ -42,9 +58,6 @@ Travis.Serializer = DS.RESTSerializer.extend
record.notifyPropertyChange(name)
, this)
- # TODO: add test that ensures that this line is called
- # it should check if record goes into loaded.saved
- # state after being in materializing
record.notifyPropertyChange('data')
Travis.RestAdapter = DS.RESTAdapter.extend
@@ -106,6 +119,7 @@ Travis.RestAdapter.map 'Travis.Repo', {
Travis.RestAdapter.map 'Travis.Job', {
repoId: { key: 'repository_id' }
repo: { key: 'repository_id' }
+ _config: { key: 'config' }
}
Travis.RestAdapter.map 'Travis.User', {
diff --git a/assets/scripts/app/templates/builds/list.hbs b/assets/scripts/app/templates/builds/list.hbs
index 4fdb23a7..b2ff50d8 100644
--- a/assets/scripts/app/templates/builds/list.hbs
+++ b/assets/scripts/app/templates/builds/list.hbs
@@ -59,9 +59,11 @@
{{/each}}
-
- {{view view.ShowMoreButton}}
-
+ {{#if displayShowMoreButton}}
+
+ {{view view.ShowMoreButton}}
+
+ {{/if}}
{{else}}
Loading
{{/if}}
diff --git a/assets/scripts/app/templates/queues/list.hbs b/assets/scripts/app/templates/queues/list.hbs
index 574f0418..2b19a905 100644
--- a/assets/scripts/app/templates/queues/list.hbs
+++ b/assets/scripts/app/templates/queues/list.hbs
@@ -20,7 +20,7 @@
{{#if queue.isMore}}
-
+
{{queue.leftLength}} more jobs - show all
{{/if}}
diff --git a/assets/scripts/app/templates/repos/show.hbs b/assets/scripts/app/templates/repos/show.hbs
index 186e20a7..28468564 100644
--- a/assets/scripts/app/templates/repos/show.hbs
+++ b/assets/scripts/app/templates/repos/show.hbs
@@ -10,7 +10,6 @@
{{description}}
- {{view Travis.RepoShowStatsView}}
{{view Travis.RepoShowTabsView}}
{{view Travis.RepoShowToolsView}}
{{/with}}
diff --git a/assets/scripts/app/templates/repos/show/stats.hbs b/assets/scripts/app/templates/repos/show/stats.hbs
deleted file mode 100644
index dfbb633e..00000000
--- a/assets/scripts/app/templates/repos/show/stats.hbs
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
diff --git a/assets/scripts/app/views.coffee b/assets/scripts/app/views.coffee
index 7dce5884..3a732e8e 100644
--- a/assets/scripts/app/views.coffee
+++ b/assets/scripts/app/views.coffee
@@ -2,9 +2,9 @@ require 'ext/ember/namespace'
@Travis.reopen
View: Em.View.extend
- popup: ->
+ popup: (name) ->
@popupCloseAll()
- name = if event.target then event.target.name else event
+ name = event?.target?.name || name
$("##{name}").toggleClass('display')
popupClose: ->
$(event.target).closest('.popup').removeClass('display')
diff --git a/assets/scripts/app/views/build.coffee b/assets/scripts/app/views/build.coffee
index f5e810de..12749afc 100644
--- a/assets/scripts/app/views/build.coffee
+++ b/assets/scripts/app/views/build.coffee
@@ -7,11 +7,6 @@ Travis.reopen
@get('controller.tab') == 'pull_requests'
).property('controller.tab')
- showMore: ->
- id = @get('controller.repo.id')
- number = @get('builds.lastObject.number')
- @get('builds').load Travis.Build.olderThanNumber(id, number)
-
ShowMoreButton: Em.View.extend
tagName: 'button'
classNameBindings: ['isLoading']
@@ -26,7 +21,7 @@ Travis.reopen
).property('isLoading')
click: ->
- @get('parentView').showMore()
+ @get('controller').showMore()
BuildsItemView: Travis.View.extend
tagName: 'tr'
@@ -54,5 +49,5 @@ Travis.reopen
loadingBinding: 'controller.loading'
color: (->
- Travis.Helpers.colorForState(@get('build.state'))
- ).property('build.state')
+ Travis.Helpers.colorForState(@get('controller.build.state'))
+ ).property('controller.build.state')
diff --git a/assets/scripts/app/views/log.coffee b/assets/scripts/app/views/log.coffee
index 6cc13c99..304034a8 100644
--- a/assets/scripts/app/views/log.coffee
+++ b/assets/scripts/app/views/log.coffee
@@ -20,6 +20,7 @@ Travis.reopen
console.log 'log view: did insert'
@_super.apply this, arguments
@createEngine()
+ @lineNumberDidChange()
willDestroyElement: ->
console.log 'log view: will destroy'
@@ -67,7 +68,7 @@ Travis.reopen
Travis.Urls.plainTextLog(id) if id = @get('log.job.id')
).property('job.log.id')
- toggleTailing: (event) ->
+ toggleTailing: ->
Travis.tailing.toggle()
event.preventDefault()
@@ -75,7 +76,7 @@ Travis.reopen
$('#log').on 'mouseenter', 'a', ->
$(this).attr('href', '#L' + ($(this.parentNode).prevAll('p').length + 1))
- click: (event) ->
+ click: ->
if (href = $(event.target).attr('href')) && matches = href?.match(/#L(\d+)$/)
@lineNumberClicked(matches[1])
event.stopPropagation()
@@ -101,7 +102,7 @@ Log.Scroll.prototype = $.extend new Log.Listener,
@tryScroll() if @number
tryScroll: ->
- if element = $("#log p:nth-child(#{@number})")
+ if (element = $("#log p:nth-child(#{@number})")) && element.length
$('#main').scrollTop(0)
$('html, body').scrollTop(element.offset()?.top) # weird, html works in chrome, body in firefox
@highlight(element)
diff --git a/assets/scripts/app/views/profile.coffee b/assets/scripts/app/views/profile.coffee
index 14585a83..234fbde5 100644
--- a/assets/scripts/app/views/profile.coffee
+++ b/assets/scripts/app/views/profile.coffee
@@ -60,6 +60,7 @@ Travis.reopen
{ key: 'pl', name: 'Polski' }
{ key: 'pt-BR', name: 'Português brasileiro' }
{ key: 'ru', name: 'Русский' }
+ { key: 'de', name: 'Deutsch' }
]
).property()
diff --git a/assets/scripts/app/views/repo/show.coffee b/assets/scripts/app/views/repo/show.coffee
index 1c118e87..b44d91cb 100644
--- a/assets/scripts/app/views/repo/show.coffee
+++ b/assets/scripts/app/views/repo/show.coffee
@@ -12,19 +12,6 @@ Travis.reopen
@get('repos.isLoaded') && @get('repos.length') == 0
).property('repos.isLoaded', 'repos.length')
- RepoShowStatsView: Travis.View.extend
- templateName: 'repos/show/stats'
- repoBinding: 'parentView.repo'
- statsBinding: 'repo.stats'
-
- urlGithubWatchers: (->
- Travis.Urls.githubWatchers(@get('repo.slug'))
- ).property('repo.slug'),
-
- urlGithubNetwork: (->
- Travis.Urls.githubNetwork(@get('repo.slug'))
- ).property('repo.slug'),
-
ReposEmptyView: Travis.View.extend
template: ''
@@ -131,11 +118,10 @@ Travis.reopen
regenerateKey: ->
@popupCloseAll()
- self = this
- @get('repo').regenerateKey
- success: ->
- self.popup('regeneration-success')
+ (@get('repo.content') || @get('repo')).regenerateKey
+ success: =>
+ @popup('regeneration-success')
error: ->
Travis.app.router.flashController.loadFlashes([{ error: 'Travis encountered an error while trying to regenerate the key, please try again.'}])
diff --git a/assets/scripts/app/views/sidebar.coffee b/assets/scripts/app/views/sidebar.coffee
index 12d1a1ea..3c7bbc9b 100644
--- a/assets/scripts/app/views/sidebar.coffee
+++ b/assets/scripts/app/views/sidebar.coffee
@@ -26,10 +26,6 @@
@_super.apply this, arguments
@set 'controller', @get('controller').container.lookup('controller:queues')
- showAll: ->
- queue = event.context
- queue.showAll()
-
RunningJobsView: Em.View.extend
templateName: 'jobs/running'
elementId: 'running-jobs'
diff --git a/assets/scripts/lib/travis/ajax.coffee b/assets/scripts/lib/travis/ajax.coffee
index e7561db7..a9e4175b 100644
--- a/assets/scripts/lib/travis/ajax.coffee
+++ b/assets/scripts/lib/travis/ajax.coffee
@@ -34,13 +34,13 @@ Travis.ajax = Em.Object.create
success = options.success || (->)
options.success = (data) =>
Travis.app.router.flashController.loadFlashes(data.flash) if Travis.app?.router && data.flash
- delete data.flash
+ delete data.flash if data?
success.apply(this, arguments)
error = options.error || (->)
options.error = (data) =>
Travis.app.router.flashController.pushObject(data.flash) if data.flash
- delete data.flash
+ delete data.flash if data?
error.apply(this, arguments)
$.ajax($.extend(options, Travis.ajax.DEFAULT_OPTIONS))
diff --git a/assets/scripts/lib/travis/line_number_parser.coffee b/assets/scripts/lib/travis/line_number_parser.coffee
new file mode 100644
index 00000000..d77020fe
--- /dev/null
+++ b/assets/scripts/lib/travis/line_number_parser.coffee
@@ -0,0 +1,5 @@
+Travis.LineNumberParser = Ember.Mixin.create
+ fetchLineNumber: ->
+ url = @container.lookup('router:main').get('url')
+ if match = url.match(/#L(\d+)$/)
+ match[1]
diff --git a/assets/scripts/spec/unit/incomplete_spec.coffee b/assets/scripts/spec/unit/incomplete_spec.coffee
index 9957e587..fdbcdfce 100644
--- a/assets/scripts/spec/unit/incomplete_spec.coffee
+++ b/assets/scripts/spec/unit/incomplete_spec.coffee
@@ -18,7 +18,9 @@ describe 'Travis.Model - incomplete', ->
niceBar: DS.belongsTo('Travis.Bar')
veryNiceBar: DS.belongsTo('Travis.Bar')
- Travis.Bar = Travis.Model.extend()
+ Travis.Bar = Travis.Model.extend
+ name: DS.attr('string')
+ foos: DS.hasMany('Travis.Foo')
adapterClass = Travis.RestAdapter.extend()
adapterClass.map 'Travis.Foo',
@@ -33,6 +35,22 @@ describe 'Travis.Model - incomplete', ->
delete Travis.Bar
store.destroy()
+ it 'allows to merge many times', ->
+ store.load(Travis.Bar, { id: '1', foo_ids: ['1', '2'] }, { id: '1' })
+ store.load(Travis.Foo, { id: '1', bar_id: '1' }, { id: '1' })
+ store.load(Travis.Foo, { id: '2', bar_id: '1' }, { id: '2' })
+
+ record = store.find(Travis.Bar, 1)
+ store.find(Travis.Foo, 1)
+ store.find(Travis.Foo, 2)
+
+ record.get('foos')
+ store.loadIncomplete(Travis.Bar, id: 1, name: 'foo')
+ store.loadIncomplete(Travis.Bar, id: 1, name: 'bar')
+
+ expect( record.get('foos.length') ).toEqual(2)
+ expect( record.get('name') ).toEqual('bar')
+
describe 'with incomplete record with loaded associations', ->
beforeEach ->
attrs = {
diff --git a/assets/scripts/travis.coffee b/assets/scripts/travis.coffee
index e32ac8be..e46a68ac 100644
--- a/assets/scripts/travis.coffee
+++ b/assets/scripts/travis.coffee
@@ -1,6 +1,9 @@
require 'ext/jquery'
require 'ext/ember/namespace'
+window.bootstrapTravis = ->
+ Travis.advanceReadiness()
+
# TODO: how can I put it in Travis namespace and use immediately?
Storage = Em.Object.extend
init: ->
@@ -43,7 +46,6 @@ window.Travis = Em.Application.extend(Ember.Evented,
signOut: ->
@get('auth').signOut()
- #@get('router').send('afterSignOut')
receive: ->
@store.receive.apply(@store, arguments)
@@ -69,7 +71,6 @@ window.Travis = Em.Application.extend(Ember.Evented,
location.href = location.href.replace('#!/', '') if location.hash.slice(0, 2) == '#!'
I18n.fallbacks = true
@setLocale 'locale', @get('defaultLocale')
- @autoSignIn() unless @get('signedIn')
).create()
Travis.deferReadiness()
diff --git a/locales/de.yml b/locales/de.yml
new file mode 100644
index 00000000..b4b87895
--- /dev/null
+++ b/locales/de.yml
@@ -0,0 +1,161 @@
+de:
+ build:
+ duration: Dauer
+ finished_at: Fertig
+ job: Aufgabe
+ builds:
+ allowed_failures: Erlaubte Fehlschläge
+ author: Autor
+ branch:
+ build_matrix: Build-Matrix
+ commit:
+ commiter:
+ committer:
+ compare: Vergleich
+ config: Konfiguration
+ duration: Dauer
+ finished_at: Fertig
+ message: Nachricht
+ messages:
+ sponsored_by: Dieser Testablauf lief auf einem Arbeiter-Rechner gesponsert von
+ name:
+ pr:
+ started_at: Läuft
+ state: Status
+ datetime:
+ distance_in_words:
+ hours_exact:
+ one: ! '%{count} Stunde'
+ other: ! '%{count} Stunden'
+ minutes_exact:
+ one: ! '%{count} Minute'
+ other: ! '%{count} Minuten'
+ seconds_exact:
+ one: ! '%{count} Sekunde'
+ other: ! '%{count} Sekunden'
+ errors:
+ messages:
+ already_confirmed: wurde bereits bestätigt
+ not_found: nicht gefunden
+ not_locked: war nicht gesperrt
+ home:
+ name: Startseite
+ jobs:
+ allowed_failures: Erlaubte Fehlschläge
+ author: Autor
+ branch:
+ build_matrix: Build-Matrix
+ commit:
+ committer:
+ compare: Vergleich
+ config: Konfiguration
+ duration: Dauer
+ finished_at: Fertig
+ message: Nachricht
+ messages:
+ sponsored_by: Dieser Testablauf lief auf einem Arbeiter-Rechner gesponsert von
+ sponsored_by: Gesponsert von
+ started_at: Läuft
+ state: Status
+ layouts:
+ about:
+ alpha: Dieses Zeugs ist Alpha!
+ join: Komm dazu und helfe!
+ mailing_list: Mailingliste
+ messages:
+ alpha: Bitte empfinde das nicht als stabilen Dienst. Wir sind immer noch weit davon entfernt! Mehr Informationen hier.
+ repository:
+ twitter:
+ application:
+ fork_me: Auf GitHub forken
+ my_repositories: Meine Repositories
+ recent: Aktuell
+ search: Suche
+ sponsers: Sponsoren
+ sponsors_link: Schaue alle unsere tollen Sponsoren an →
+ mobile:
+ author: Autor
+ build:
+ build_matrix: Build-Matrix
+ commit:
+ committer:
+ compare: Vergleich
+ config: Konfiguration
+ duration: Dauer
+ finished_at: Fertig
+ job: Aufgabe
+ log: Log
+ top:
+ accounts: Accounts
+ admin: Admin
+ blog: Blog
+ docs: Dokumentation
+ github_login: Mit GitHub anmelden
+ home: Startseite
+ profile: Profil
+ sign_out: Abmelden
+ signing_in: Anmelden...
+ stats: Statistik
+ locales:
+ ca:
+ de: Deutsch
+ en: English
+ es: Español
+ fr: Français
+ ja: 日本語
+ nb: Norsk Bokmål
+ nl: Nederlands
+ pl: Polski
+ pt-BR: português brasileiro
+ ru: Русский
+ no_job: Es gibt keine Aufgaben
+ profiles:
+ show:
+ email: E-Mail
+ github:
+ locale: Sprache
+ message:
+ config: Wie du eigene Build-Optionen konfigurieren kannst
+ your_repos: Lege die Schalter unten um, um den Travis Dienst-Hook für deine Projekte zu aktivieren, dann pushe zu GitHub.
\n Um gegen mehrere Rubine zu testen, sehe
+ messages:
+ notice: Bitte lese dir unser Getting Started-Handbuch durch, um loszulegen.\\n Es dauert nur ein paar Minuten.
+ token:
+ update:
+ update_locale: Update
+ your_locale: Deine Sprache
+ your_repos: Deine Repositories
+ queue: Warteschlange
+ repositories:
+ asciidoc:
+ branch:
+ commit:
+ duration: Dauer
+ finished_at: Fertig
+ image_url: Bild-URL
+ markdown:
+ message: Nachricht
+ rdoc:
+ started_at: Läuft
+ tabs:
+ branches: Branch-Zusammenfassung
+ build:
+ build_history: Build-Geschichte
+ current: Aktuell
+ job: Aufgabe
+ pull_requests:
+ test:
+ textile:
+ repository:
+ duration: Dauer
+ statistics:
+ index:
+ build_count: Build-Anzahl
+ count: Anzahl
+ last_month: letzter Monat
+ repo_growth: Repository-Zuwachs
+ total_builds: Alle Builds
+ total_projects: Alle Projekte/Repositories
+ user:
+ failure: Fehlschlag
+ signed_out: Abgemeldet
+ workers: Arbeiter
diff --git a/locales/en.yml b/locales/en.yml
index fedaeefd..d5ef97fd 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -9,6 +9,7 @@ en:
branch: Branch
build_matrix: Build Matrix
commit: Commit
+ commiter: commiter
committer: Committer
compare: Compare
config: Config
@@ -97,6 +98,7 @@ en:
stats: Stats
locales:
ca:
+ de: Deutsch
en: English
es: Español
fr: Français
diff --git a/locales/es.yml b/locales/es.yml
index 632834bc..ecd7d82c 100644
--- a/locales/es.yml
+++ b/locales/es.yml
@@ -9,6 +9,7 @@ es:
branch: Rama
build_matrix: Matriz de Builds
commit: Commit
+ commiter:
committer: Committer
compare: Comparar
config: Configuración
@@ -97,6 +98,7 @@ es:
stats: Estadísticas
locales:
ca:
+ de: Deutsch
en: English
es: Español
fr: Français
diff --git a/locales/fr.yml b/locales/fr.yml
index 574daf2b..9f7df4a6 100644
--- a/locales/fr.yml
+++ b/locales/fr.yml
@@ -9,6 +9,7 @@ fr:
branch: Branche
build_matrix: Table des versions
commit: Commit
+ commiter:
committer: Committeur
compare: Comparer
config: Config
@@ -97,6 +98,7 @@ fr:
stats: Statistiques
locales:
ca:
+ de: Deutsch
en: English
es: Español
fr: Français
diff --git a/locales/ja.yml b/locales/ja.yml
index 1357242d..43e589bf 100644
--- a/locales/ja.yml
+++ b/locales/ja.yml
@@ -9,6 +9,7 @@ ja:
branch: ブランチ
build_matrix: 失敗許容範囲外
commit: コミット
+ commiter:
committer: コミット者
compare: 比較
config: 設定
@@ -91,6 +92,7 @@ ja:
stats: 統計
locales:
ca:
+ de: Deutsch
en: English
es: Español
fr: Français
diff --git a/locales/nb.yml b/locales/nb.yml
index f6f84518..8ad41830 100644
--- a/locales/nb.yml
+++ b/locales/nb.yml
@@ -9,6 +9,7 @@ nb:
branch: Gren
build_matrix: Jobbmatrise
commit: Innsending
+ commiter:
committer: Innsender
compare: Sammenlign
config: Oppsett
@@ -97,6 +98,7 @@ nb:
stats: Statistikk
locales:
ca:
+ de: Deutsch
en: English
es: Español
fr: Français
diff --git a/locales/nl.yml b/locales/nl.yml
index 6df3524b..81c263b3 100644
--- a/locales/nl.yml
+++ b/locales/nl.yml
@@ -9,6 +9,7 @@ nl:
branch: Tak
build_matrix: Bouw matrix
commit: Commit
+ commiter:
committer: Committer
compare: Vergelijk
config: Configuratie
@@ -97,6 +98,7 @@ nl:
stats: Statistieken
locales:
ca:
+ de: Deutsch
en: English
es: Español
fr: Français
diff --git a/locales/pl.yml b/locales/pl.yml
index 2e5578c2..2df987d1 100644
--- a/locales/pl.yml
+++ b/locales/pl.yml
@@ -9,6 +9,7 @@ pl:
branch: Gałąź
build_matrix: Macierz Buildów
commit: Commit
+ commiter:
committer: Komitujący
compare: Porównanie
config: Konfiguracja
@@ -100,6 +101,7 @@ pl:
stats: Statystki
locales:
ca: Čeština
+ de: Deutsch
en: English
es: Español
fr: Français
diff --git a/locales/pt-BR.yml b/locales/pt-BR.yml
index 1809fd01..2e2a1b0f 100644
--- a/locales/pt-BR.yml
+++ b/locales/pt-BR.yml
@@ -9,6 +9,7 @@ pt-BR:
branch: Branch
build_matrix: Matriz de Build
commit: Commit
+ commiter:
committer: Committer
compare: Comparar
config: Config
@@ -97,6 +98,7 @@ pt-BR:
stats: Estatísticas
locales:
ca:
+ de: Deutsch
en: English
es: Español
fr: Français
diff --git a/locales/ru.yml b/locales/ru.yml
index d9187c7b..a05549a2 100644
--- a/locales/ru.yml
+++ b/locales/ru.yml
@@ -9,6 +9,7 @@ ru:
branch: Ветка
build_matrix: Матрица
commit: Коммит
+ commiter:
committer: Коммитер
compare: Дифф
config: Конфигурация
@@ -18,7 +19,7 @@ ru:
messages:
sponsored_by: Эта серия тестов была запущена на машине, спонсируемой
name: Билд
- pr:
+ pr: PR
started_at: Начало
state: состояние
datetime:
@@ -103,6 +104,7 @@ ru:
stats: Статистика
locales:
ca:
+ de: Deutsch
en: English
es: Español
fr: Français
@@ -162,6 +164,6 @@ ru:
total_builds: Всего билдов
total_projects: Всего проектов/репозиториев
user:
- failure:
- signed_out:
+ failure: сбой
+ signed_out: Вышел
workers: Машины
diff --git a/public/index.html b/public/index.html
index 4bf319be..614e591f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -16,7 +16,7 @@