aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuc Donnet2018-02-19 11:04:29 +0100
committerLuc Donnet2018-02-19 11:04:29 +0100
commit7b17deff51545358009cb417cbb9d796565e7540 (patch)
treea43a5586ad39d838dd607e600dbc15ff18a58ab3 /lib
parent89428163fc93a7e09ebb0ca47939f8558afeb5eb (diff)
parent5f6008d165df4499319a2121a71842657d6ac3c9 (diff)
downloadchouette-core-7b17deff51545358009cb417cbb9d796565e7540.tar.bz2
Merge branch 'master' into 0000-docker
Diffstat (limited to 'lib')
-rw-r--r--lib/af83/decorator.rb131
-rw-r--r--lib/af83/decorator/enhanced_decorator.rb159
-rw-r--r--lib/af83/decorator/link.rb156
-rw-r--r--lib/line_periods.rb35
-rw-r--r--lib/link.rb6
-rw-r--r--lib/range_ext.rb18
-rw-r--r--lib/stif/codifligne_line_id.rb19
-rw-r--r--lib/stif/dashboard.rb6
-rw-r--r--lib/stif/my_workbench_scopes.rb3
-rw-r--r--lib/stif/netex_file.rb93
-rw-r--r--lib/stif/permission_translator.rb16
-rw-r--r--lib/stif/reflex_synchronization.rb1
-rw-r--r--lib/tasks/ci.rake16
-rw-r--r--lib/tasks/compliance_check_sets.rb11
-rw-r--r--lib/tasks/erd.rake4
-rw-r--r--lib/tasks/imports.rake7
-rw-r--r--lib/tasks/referential.rake43
17 files changed, 667 insertions, 57 deletions
diff --git a/lib/af83/decorator.rb b/lib/af83/decorator.rb
new file mode 100644
index 000000000..71cf1170d
--- /dev/null
+++ b/lib/af83/decorator.rb
@@ -0,0 +1,131 @@
+class AF83::Decorator < ModelDecorator
+ include AF83::Decorator::EnhancedDecorator
+ extend AF83::Decorator::EnhancedDecorator::ClassMethods
+
+ class << self
+ def decorates klass
+ instance_decorator.decorates klass
+ end
+
+ def instance_decorator
+ @instance_decorator ||= begin
+ klass = Class.new(AF83::Decorator::InstanceDecorator)
+ klass.delegate_all
+ klass
+ end
+ end
+
+ def with_instance_decorator
+ @_with_instance_decorator = true
+ yield instance_decorator
+ @_with_instance_decorator = false
+ end
+
+ def decorate object, options = {}
+ if object.is_a?(ActiveRecord::Base)
+ return instance_decorator.decorate object, options
+ else
+ self.new object, options.update(with: instance_decorator)
+ end
+ end
+
+ def define_instance_method method_name, &block
+ instance_decorator.send(:define_method, method_name, &block)
+ end
+
+ # Defines a class method on the decorated object's class. These
+ # can be called like `object.class.my_method`.
+ def define_instance_class_method method_name, &block
+ instance_decorator.send(:define_singleton_method, method_name, &block)
+ end
+
+ def set_scope_with_instance_decorator value=nil, &block
+ set_scope_without_instance_decorator value, &block
+ instance_decorator.set_scope value, &block
+ end
+
+ alias_method_chain :set_scope, :instance_decorator
+ end
+
+ class ActionLinks
+ attr_reader :options
+
+ delegate :each, :map, :size, :first, :last, :any?, :select, to: :resolve
+
+ def initialize opts
+ @options = opts.deep_dup
+ end
+
+ def for_group group
+ returning_a_copy do
+ @options[:groups] = [group] if group.present?
+ end
+ end
+
+ def for_groups groups
+ returning_a_copy do
+ @options[:groups] = groups if groups.present?
+ end
+ end
+
+ def primary
+ for_group :primary
+ end
+
+ def secondary
+ for_group :secondary
+ end
+
+ def resolve
+ out = @options[:links].map{|l| l.bind_to_context(@options[:context], @options[:action])}.select{|l| l.enabled?}
+ if @options[:groups].present?
+ out = out.select do |l|
+ @options[:groups].any? do |g|
+ l.in_group_for_action?(g)
+ end
+ end
+ end
+ out
+ end
+ alias_method :to_ary, :resolve
+
+ def grouped_by *groups
+ add_footer = groups.include?(:footer)
+ groups -= [:footer]
+ out = HashWithIndifferentAccess[*groups.map{|g| [g, []]}.flatten(1)]
+ out[:other] = []
+ if add_footer
+ out[:footer] = []
+ groups << :footer
+ end
+
+ each do |l|
+ found = false
+ groups.each do |g|
+ if l.in_group_for_action?(g)
+ out[g] << l
+ found = true
+ next
+ end
+ end
+ out[:other] << l unless found
+ end
+ out
+ end
+
+ private
+ def returning_a_copy &block
+ out = ActionLinks.new options
+ out.instance_eval &block
+ out
+ end
+ end
+
+ class IncompleteLinkDefinition < RuntimeError
+ end
+
+ class InstanceDecorator < Draper::Decorator
+ include AF83::Decorator::EnhancedDecorator
+ extend AF83::Decorator::EnhancedDecorator::ClassMethods
+ end
+end
diff --git a/lib/af83/decorator/enhanced_decorator.rb b/lib/af83/decorator/enhanced_decorator.rb
new file mode 100644
index 000000000..fff8bb8b3
--- /dev/null
+++ b/lib/af83/decorator/enhanced_decorator.rb
@@ -0,0 +1,159 @@
+module AF83::Decorator::EnhancedDecorator
+ module ClassMethods
+ def action_link args={}
+ raise "You are using `action_link` inside a with_instance_decorator block, but not on the instance decorator itself.\n Use `instance_decorator.action_link` or move outside of the block, as this may lead to an unforeseen behaviour." if @_with_instance_decorator
+ args[:if] = @_condition if args[:if].nil?
+
+ options, link_options = parse_options args
+
+ link = AF83::Decorator::Link.new(link_options)
+ instance_exec(link, &options[:before_block]) if options[:before_block]
+ yield link if block_given?
+ raise AF83::Decorator::IncompleteLinkDefinition.new(link.errors) unless link.complete?
+
+ weight = options[:weight] || 1
+ @_action_links ||= []
+ @_action_links[weight] ||= []
+ @_action_links[weight] << link
+ end
+
+ ### Here we define some shortcuts that match dthe default behaviours
+ def create_action_link args={}, &block
+ opts = {
+ on: :index,
+ primary: :index,
+ policy: :create,
+ before_block: -> (l){
+ l.content { h.t('actions.add') }
+ l.href { [:new, scope, object.klass.model_name.singular] }
+ }
+ }
+ action_link opts.update(args), &block
+ end
+
+ def show_action_link args={}, &block
+ opts = {
+ on: :index,
+ primary: :index,
+ before_block: -> (l){
+ l.content { h.t('actions.show') }
+ l.href { [scope, object] }
+ }
+ }
+ action_link opts.update(args), &block
+ end
+
+ def edit_action_link args={}, &block
+ opts = {
+ primary: %i(show index),
+ policy: :edit,
+ before_block: -> (l){
+ l.content { h.t('actions.edit') }
+ l.href { [:edit, scope, object] }
+ }
+ }
+ action_link opts.update(args), &block
+ end
+
+ def destroy_action_link args={}, &block
+ opts = {
+ policy: :destroy,
+ footer: true,
+ secondary: :show,
+ before_block: -> (l){
+ l.content { h.destroy_link_content }
+ l.href { [scope, object] }
+ l.method :delete
+ l.data {{ confirm: h.t('actions.destroy_confirm') }}
+ }
+ }
+ action_link opts.update(args), &block
+ end
+
+ def set_scope value=nil, &block
+ @scope = value || block
+ end
+
+ def scope
+ @scope
+ end
+
+ def t key
+ eval "-> (l){ h.t('#{key}') }"
+ end
+
+ def with_condition condition, &block
+ @_condition = condition
+ instance_eval &block
+ @_condition = nil
+ end
+
+ def action_links action
+ (@_action_links || []).flatten.compact.select{|l| l.for_action?(action)}
+ end
+
+ def parse_options args
+ options = {}
+ %i(weight primary secondary footer on action actions policy feature if groups group before_block).each do |k|
+ options[k] = args.delete(k) if args.has_key?(k)
+ end
+ link_options = args.dup
+
+ actions = options.delete :actions
+ actions ||= options.delete :on
+ actions ||= [options.delete(:action)]
+ actions = [actions] unless actions.is_a?(Array)
+ link_options[:_actions] = actions.compact
+
+ link_options[:_groups] = options.delete(:groups)
+ link_options[:_groups] ||= {}
+ if single_group = options.delete(:group)
+ if(single_group.is_a?(Symbol) || single_group.is_a?(String))
+ link_options[:_groups][single_group] = true
+ else
+ link_options[:_groups].update single_group
+ end
+ end
+ link_options[:_groups][:primary] ||= options.delete :primary
+ link_options[:_groups][:secondary] ||= options.delete :secondary
+ link_options[:_groups][:footer] ||= options.delete :footer
+
+ link_options[:_if] = options.delete(:if)
+ link_options[:_policy] = options.delete(:policy)
+ link_options[:_feature] = options.delete(:feature)
+ [options, link_options]
+ end
+ end
+
+ def action_links action=:index, opts={}
+ @action = action&.to_sym
+ links = AF83::Decorator::ActionLinks.new links: self.class.action_links(action), context: self, action: action
+ group = opts[:group]
+ links = links.for_group opts[:group]
+ links
+ end
+
+ def primary_links action=:index
+ action_links(action, group: :primary)
+ end
+
+ def secondary_links action=:index
+ action_links(action, group: :secondary)
+ end
+
+ def check_policy policy
+ _object = policy.to_s == "create" ? object.klass : object
+ method = "#{policy}?"
+ h.policy(_object).send(method)
+ end
+
+ def check_feature feature
+ h.has_feature? feature
+ end
+
+ def scope
+ scope = self.class.scope
+ scope = instance_exec &scope if scope.is_a? Proc
+ scope
+ end
+end
diff --git a/lib/af83/decorator/link.rb b/lib/af83/decorator/link.rb
new file mode 100644
index 000000000..ee09f80dc
--- /dev/null
+++ b/lib/af83/decorator/link.rb
@@ -0,0 +1,156 @@
+class AF83::Decorator::Link
+ REQUIRED_ATTRIBUTES = %i(href content)
+
+ attr_reader :context
+ attr_reader :action
+
+ def initialize options={}
+ @options = {}
+ options.each do |k, v|
+ send "#{k}", v
+ end
+ end
+
+ def bind_to_context context, action
+ @context = context
+ @action = action
+ self
+ end
+
+ def method *args
+ link_method *args
+ end
+
+ def class *args
+ link_class args
+ end
+
+ def method_missing name, *args, &block
+ if block_given?
+ @options[name] = block
+ elsif args.size == 0
+ out = @options[name]
+ out = context.instance_exec(self, &out) if out.is_a?(Proc)
+ out = out.flatten.compact if name.to_s == "href" && out.is_a?(Array)
+ out
+ else
+ # we can use l.foo("bar") or l.foo = "bar"
+ if name.to_s =~ /\=$/
+ _name = name.to_s.gsub(/=$/, '')
+ return send(_name, *args, &block)
+ end
+ @options[name] = args.first
+ end
+ end
+
+ def options
+ @options.symbolize_keys
+ end
+
+ def complete?
+ @missing_attributes = REQUIRED_ATTRIBUTES.select{|a| !@options[a].present?}
+ @missing_attributes.empty?
+ end
+
+ def enabled_actions
+ @options[:_actions].map(&:to_s) || []
+ end
+
+ def for_action? action=nil
+ action ||= @action
+ enabled_actions.empty? || enabled_actions.include?(action.to_s)
+ end
+
+ def actions_for_group group
+ val = @options[:_groups][group]
+ val.is_a?(Array) ? val.map(&:to_s) : val
+ end
+
+ def in_group_for_action? group
+ vals = actions_for_group(group)
+ if vals.is_a?(Array)
+ return vals.include?(@action.to_s)
+ elsif vals.is_a?(String) || vals.is_a?(Symbol)
+ vals.to_s == @action.to_s
+ else
+ !!vals
+ end
+ end
+
+ def primary?
+ in_group_for_action? :primary
+ end
+
+ def secondary?
+ in_group_for_action? :secondary
+ end
+
+ def enabled?
+ enabled = false
+ if @options[:_if].nil?
+ enabled = true
+ elsif @options[:_if].is_a?(Proc)
+ enabled = context.instance_exec(&@options[:_if])
+ else
+ enabled = !!@options[:_if]
+ end
+
+ enabled = enabled && check_policy(@options[:_policy]) if @options[:_policy].present?
+ enabled = enabled && check_feature(@options[:_feature]) if @options[:_feature].present?
+ enabled
+ end
+
+ def check_policy(policy)
+ @context.check_policy policy
+ end
+
+ def check_feature(feature)
+ @context.check_feature feature
+ end
+
+ def errors
+ "Missing attributes: #{@missing_attributes.to_sentence}"
+ end
+
+ def add_class val
+ @options[:link_class] ||= []
+ @options[:link_class] << val
+ @options[:link_class].flatten!
+ end
+
+ def extra_class
+ (options[:link_class] || []).join(' ')
+ end
+
+ def html_options
+ out = {}
+ options.each do |k, v|
+ out[k] = self.send(k) unless k == :content || k == :href || k.to_s =~ /^_/
+ end
+ out[:method] = link_method
+ out[:class] = extra_class
+ out.delete(:link_class)
+ out.delete(:link_method)
+ out[:class] += " disabled" if disabled
+ out[:class].strip!
+ out[:disabled] = !!disabled
+ out
+ end
+
+ def to_html
+ if block_given?
+ link = AF83::Decorator::Link.new(@options).bind_to_context(context, @action)
+ yield link
+ return link.to_html
+ end
+ if type&.to_sym == :button
+ HTMLElement.new(
+ :button,
+ content,
+ html_options
+ ).to_html
+ else
+ context.h.link_to content, href, html_options
+ end
+ end
+end
diff --git a/lib/line_periods.rb b/lib/line_periods.rb
new file mode 100644
index 000000000..c176a7a08
--- /dev/null
+++ b/lib/line_periods.rb
@@ -0,0 +1,35 @@
+class LinePeriods
+
+ def initialize
+ @periods_by_line = Hash.new { |h,k| h[k] = [] }
+ end
+
+ def add(line_id, period)
+ @periods_by_line[line_id] << period
+ end
+
+ def each(&block)
+ @periods_by_line.each do |line_id, periods|
+ yield line_id, periods
+ end
+ end
+
+ def periods(line_id)
+ @periods_by_line[line_id]
+ end
+
+ def self.from_metadatas(metadatas)
+ line_periods = new
+
+ metadatas.each do |metadata|
+ metadata.line_ids.each do |line_id|
+ metadata.periodes.each do |period|
+ line_periods.add(line_id, period)
+ end
+ end
+ end
+
+ line_periods
+ end
+
+end
diff --git a/lib/link.rb b/lib/link.rb
index 7683a808f..33995c2f7 100644
--- a/lib/link.rb
+++ b/lib/link.rb
@@ -1,10 +1,12 @@
class Link
- attr_reader :content, :href, :method, :data
+ attr_reader :content, :href, :method, :data, :extra_class, :disabled
- def initialize(content: nil, href:, method: nil, data: nil)
+ def initialize(content: nil, href:, method: nil, data: nil, extra_class: nil, disabled: false)
@content = content
@href = href
@method = method
@data = data
+ @extra_class = extra_class
+ @disabled = disabled
end
end
diff --git a/lib/range_ext.rb b/lib/range_ext.rb
index f1df5e70d..e7e0e903f 100644
--- a/lib/range_ext.rb
+++ b/lib/range_ext.rb
@@ -1,8 +1,24 @@
class Range
def intersection(other)
- return nil if (self.max < other.min or other.max < self.min)
+ return nil unless intersect?(other)
[self.min, other.min].max..[self.max, other.max].min
end
alias_method :&, :intersection
+
+ def intersect?(other)
+ self.max > other.min and other.max > self.min
+ end
+
+ def remove(other)
+ return self if (self.max < other.min or other.max < self.min)
+
+ [].tap do |remaining|
+ remaining << (self.min..other.min-1) if self.min < other.min
+ remaining << (other.max+1..self.max) if other.max < self.max
+ remaining.compact!
+ end
+ end
+ alias_method :-, :remove
+
end
diff --git a/lib/stif/codifligne_line_id.rb b/lib/stif/codifligne_line_id.rb
new file mode 100644
index 000000000..8c1bcc54b
--- /dev/null
+++ b/lib/stif/codifligne_line_id.rb
@@ -0,0 +1,19 @@
+module STIF
+ module CodifligneLineId extend self
+
+ LINE_OBJECT_ID_SEPERATOR = ':'
+
+ def lines_set_from_functional_scope(functional_scope)
+ Set.new(
+ functional_scope
+ .map{ |line| extract_codif_line_id line })
+ end
+
+
+ private
+
+ def extract_codif_line_id line_name
+ line_name.split(LINE_OBJECT_ID_SEPERATOR).last
+ end
+ end
+end
diff --git a/lib/stif/dashboard.rb b/lib/stif/dashboard.rb
index b6b6b8284..46c635091 100644
--- a/lib/stif/dashboard.rb
+++ b/lib/stif/dashboard.rb
@@ -4,12 +4,16 @@ module Stif
@workbench ||= current_organisation.workbenches.find_by(name: "Gestion de l'offre")
end
+ def workgroup
+ workbench.workgroup
+ end
+
def referentials
@referentials ||= self.workbench.all_referentials
end
def calendars
- @calendars ||= Calendar.where('organisation_id = ? OR shared = ?', current_organisation.id, true)
+ @calendars ||= Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id, true, workgroup.id)
end
end
end
diff --git a/lib/stif/my_workbench_scopes.rb b/lib/stif/my_workbench_scopes.rb
index 89c4e659c..04bc93089 100644
--- a/lib/stif/my_workbench_scopes.rb
+++ b/lib/stif/my_workbench_scopes.rb
@@ -2,12 +2,13 @@ module Stif
class MyWorkbenchScopes
attr_accessor :workbench
+
def initialize(workbench)
@workbench = workbench
end
def line_scope(initial_scope)
- ids = self.parse_functional_scope
+ ids = parse_functional_scope
ids ? initial_scope.where(objectid: ids) : initial_scope
end
diff --git a/lib/stif/netex_file.rb b/lib/stif/netex_file.rb
index a977c1ad3..db0801bbe 100644
--- a/lib/stif/netex_file.rb
+++ b/lib/stif/netex_file.rb
@@ -2,8 +2,9 @@ module STIF
class NetexFile
CALENDAR_FILE_NAME = 'calendriers.xml'
- LINE_FILE_FORMAT = /^offre_.*\.xml$/
- XML_NAME_SPACE = "http://www.netex.org.uk/netex"
+ LINE_FILE_FORMAT = %r{\A offre_ (?<line_object_id> .*?) _ .* \. xml \z}x
+ XML_NAME_SPACE = "http://www.netex.org.uk/netex"
+
def initialize(file_name)
@file_name = file_name
@@ -13,58 +14,72 @@ module STIF
frames = Hash.new { |h,k| h[k] = NetexFile::Frame.new(k) }
Zip::File.open(@file_name) do |zipfile|
zipfile.each do |entry|
- next unless entry.ftype == :file
-
- entry_dir_name, entry_file_name = File.split(entry.name)
- case entry_file_name
- when CALENDAR_FILE_NAME
- entry.get_input_stream do |stream|
- frames[entry_dir_name].parse_calendars(stream.read)
- end
- when LINE_FILE_FORMAT
- frames[entry_dir_name].add_offer_file(entry_file_name)
- end
+ add_frame(to_frames: frames, from_entry: entry) if entry.ftype == :file
end
end
frames.values
end
- end
- class NetexFile::Frame
+ private
- attr_accessor :name
+ def add_frame(to_frames:, from_entry:)
+ entry_dir_name, entry_file_name = File.split(from_entry.name)
- def initialize(name)
- @name = name
- end
+ if CALENDAR_FILE_NAME === entry_file_name
+ from_entry.get_input_stream do |stream|
+ to_frames[entry_dir_name].parse_calendars(stream.read)
+ end
+ return
+ end
- def parse_calendars(calendars)
- # <netex:ValidBetween>
- # <netex:FromDate>2017-03-01</netex:FromDate>
- # <netex:ToDate>2017-03-31</netex:ToDate>
- # </netex:ValidBetween>
- xml = Nokogiri::XML(calendars)
- xml.xpath("//netex:ValidBetween", "netex" => NetexFile::XML_NAME_SPACE).each do |valid_between|
- from_date = valid_between.xpath("netex:FromDate").try :text
- to_date = valid_between.xpath("netex:ToDate").try :text
- periods << Range.new(Date.parse(from_date), Date.parse(to_date))
+ line_file_match = LINE_FILE_FORMAT.match( entry_file_name )
+ if line_file_match
+ to_frames[entry_dir_name].add_offer_file( line_file_match['line_object_id'])
end
end
- def add_offer_file(file_name)
- if file_name =~ /^offre_([^_]*)_/
- line_refs << $1
+
+ class Frame
+
+ class << self
+ def get_short_id file_name
+ base_name = File.basename(file_name)
+ STIF::NetexFile::LINE_FILE_FORMAT.match(base_name).try(:[], 'line_object_id')
+ end
end
- end
- def periods
- @periods ||= []
- end
+ attr_accessor :name
- def line_refs
- @line_refs ||= []
- end
+ def initialize(name)
+ @name = name
+ end
+
+ def parse_calendars(calendars)
+ # <netex:ValidBetween>
+ # <netex:FromDate>2017-03-01</netex:FromDate>
+ # <netex:ToDate>2017-03-31</netex:ToDate>
+ # </netex:ValidBetween>
+ xml = Nokogiri::XML(calendars)
+ xml.xpath("//netex:ValidBetween", "netex" => NetexFile::XML_NAME_SPACE).each do |valid_between|
+ from_date = valid_between.xpath("netex:FromDate").try :text
+ to_date = valid_between.xpath("netex:ToDate").try :text
+ periods << Range.new(Date.parse(from_date), Date.parse(to_date))
+ end
+ end
+
+ def add_offer_file(line_object_id)
+ line_refs << line_object_id
+ end
+ def periods
+ @periods ||= []
+ end
+
+ def line_refs
+ @line_refs ||= []
+ end
+
+ end
end
end
diff --git a/lib/stif/permission_translator.rb b/lib/stif/permission_translator.rb
index 2d267bc7b..9e0feb9b8 100644
--- a/lib/stif/permission_translator.rb
+++ b/lib/stif/permission_translator.rb
@@ -1,11 +1,11 @@
module Stif
module PermissionTranslator extend self
- def translate(sso_extra_permissions)
- sso_extra_permissions
- .sort
+ def translate(sso_extra_permissions, organisation=nil)
+ permissions = sso_extra_permissions.sort
.flat_map(&method(:extra_permission_translation))
- .uniq
+ permissions += extra_organisation_permissions(organisation)
+ permissions.uniq
end
private
@@ -21,6 +21,7 @@ module Stif
calendars
footnotes
imports
+ merges
journey_patterns
referentials
routes
@@ -49,5 +50,12 @@ module Stif
"boiv:edit-offer" => all_destructive_permissions + %w{sessions.create},
}
end
+
+ def extra_organisation_permissions organisation
+ if organisation&.name&.downcase == "stif"
+ return %w{calendars.share stop_area_referentials.synchronize line_referentials.synchronize}
+ end
+ []
+ end
end
end
diff --git a/lib/stif/reflex_synchronization.rb b/lib/stif/reflex_synchronization.rb
index 39a92bd1f..7570e4c49 100644
--- a/lib/stif/reflex_synchronization.rb
+++ b/lib/stif/reflex_synchronization.rb
@@ -151,6 +151,7 @@ module Stif
def create_or_update_stop_area entry
stop = Chouette::StopArea.find_or_create_by(objectid: entry['id'], stop_area_referential: self.defaut_referential )
+ stop.kind = :commercial
stop.deleted_at = nil
{
:comment => 'Description',
diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake
index 3e73b7a3b..89f9aa9c8 100644
--- a/lib/tasks/ci.rake
+++ b/lib/tasks/ci.rake
@@ -3,7 +3,7 @@ namespace :ci do
task :setup do
cp "config/database/jenkins.yml", "config/database.yml"
sh "RAILS_ENV=test rake db:drop db:create db:migrate"
- sh "yarn --production --no-progress install"
+ sh "yarn --no-progress install"
end
def git_branch
@@ -31,18 +31,22 @@ namespace :ci do
sh "bundle exec bundle-audit check --update"
end
- task :spec => ["ci:assets","spec"]
-
task :assets do
sh "RAILS_ENV=test bundle exec rake assets:precompile"
end
- task :jest => "ci:assets" do
- sh "node_modules/.bin/jest"
+ task :i18n_js_export do
+ sh "RAILS_ENV=test bundle exec rake i18n:js:export"
+ end
+
+ task :jest do
+ sh "node_modules/.bin/jest" unless ENV["CHOUETTE_JEST_DISABLED"]
end
desc "Deploy after CI"
task :deploy do
+ return if ENV["CHOUETTE_DEPLOY_DISABLED"]
+
if deploy_env
sh "cap #{deploy_env} deploy:migrations"
else
@@ -58,4 +62,4 @@ namespace :ci do
end
desc "Run continuous integration tasks (spec, ...)"
-task :ci => ["ci:setup", "ci:spec", "ci:jest", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"]
+task :ci => ["ci:setup", "ci:assets", "ci:i18n_js_export", "spec", "ci:jest", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"]
diff --git a/lib/tasks/compliance_check_sets.rb b/lib/tasks/compliance_check_sets.rb
new file mode 100644
index 000000000..c53c7f9ed
--- /dev/null
+++ b/lib/tasks/compliance_check_sets.rb
@@ -0,0 +1,11 @@
+namespace :compliance_check_sets do
+ desc "Notify parent check sets when children finish"
+ task notify_parent: :environment do
+ ParentNotifier.new(ComplianceCheckSet).notify_when_finished
+ end
+
+ desc "Mark old unfinished check sets as 'aborted'"
+ task abort_old: :environment do
+ ComplianceCheckSet.abort_old
+ end
+end
diff --git a/lib/tasks/erd.rake b/lib/tasks/erd.rake
index e2665374e..96bb7fe37 100644
--- a/lib/tasks/erd.rake
+++ b/lib/tasks/erd.rake
@@ -2,12 +2,12 @@ namespace :generate do
desc "Create model diagrams for Chouette"
task :model_diagram => :environment do
- sh "bundle exec rake erd only='Organisation,Referential,User,Workbench' filename='organisation' title='Organisation'"
+ sh "bundle exec rake erd only='Organisation,Referential,User,Workbench,Workgroup' filename='organisation' title='Organisation'"
sh "bundle exec rake erd only='Calendar,Referential,ReferentialMetadata,Chouette::Line,Chouette::Route,Chouette::JourneyPattern,Chouette::VehicleJourney,Chouette::VehicleJourneyAtStop,Chouette::TimeTable,Chouette::TimeTableDate,Chouette::TimeTablePeriod,Chouette::Footnote,Chouette::Network,Chouette::Company,Chouette::StopPoint,Chouette::StopArea' filename='offer_datas' title='Offer Datas'"
sh "bundle exec rake erd only='Organisation,StopAreaReferential,StopAreaReferentialSync,StopAreaReferentialSyncMessage,StopAreaReferentialMembership,LineReferential,LineReferentialSync,LineReferentialSyncMessage,LineReferentialMembership' filename='referentiels_externes' title='Référentiels externes'"
sh "bundle exec rake erd only='NetexImport,Import,WorkbenchImport,ImportResource,ImportMessage' filename='import' title='Import'"
sh "bundle exec rake erd only='ComplianceControlSet,ComplianceControlBlock,ComplianceControl,ComplianceCheckSet,ComplianceCheckBlock,ComplianceCheck,ComplianceCheckResource,ComplianceCheckMessage' filename='validation' title='Validation'"
- sh "bundle exec rake erd only='Organisation,Workbench,ReferentialSuite,Referential' filename='merge' title='Merge'"
+ sh "bundle exec rake erd only='Organisation,Workgroup,Workbench,ReferentialSuite,Referential' filename='merge' title='Merge'"
#sh "bundle exec rake erd only='VehicleJourney,VehicleJourneyExport' filename='export' title='Export'"
#sh "bundle exec rake erd only='' filename='integration' title='Integration'"
#sh "bundle exec rake erd only='' filename='publication' title='Publication'"
diff --git a/lib/tasks/imports.rake b/lib/tasks/imports.rake
index 6bc84acc8..02e32fd3d 100644
--- a/lib/tasks/imports.rake
+++ b/lib/tasks/imports.rake
@@ -1,6 +1,11 @@
namespace :import do
desc "Notify parent imports when children finish"
task notify_parent: :environment do
- ParentImportNotifier.notify_when_finished
+ ParentNotifier.new(Import).notify_when_finished
+ end
+
+ desc "Mark old unfinished Netex imports as 'aborted'"
+ task netex_abort_old: :environment do
+ NetexImport.abort_old
end
end
diff --git a/lib/tasks/referential.rake b/lib/tasks/referential.rake
index 7bab6e040..d53157312 100644
--- a/lib/tasks/referential.rake
+++ b/lib/tasks/referential.rake
@@ -67,4 +67,47 @@ namespace :referential do
referential.update(ready: true)
end
end
+
+ def update_checksums_for_referential referential
+ thing = %w(\\ | / —)
+ Referential.force_register_models_with_checksum if Rails.env.development? && Referential.models_with_checksum.empty?
+ puts "\n \e[33m***\e[0m Referential #{referential.name}"
+ referential.switch do
+ Referential.models_with_checksum.each do |klass|
+ i = 0
+ j = 0
+ prev_size = 1
+ head = "Updating checksums for #{klass.name}: "
+ print head
+ print "⎯"*(80-head.size)
+ print " "
+ count = klass.count
+ klass.find_each do |o|
+ o.update_checksum!
+ if j%10 == 0
+ out = "#{"\b"*prev_size}\e[33m#{thing[i]}\e[0m (#{j}/#{count})"
+ prev_size = out.size - prev_size - 9
+ print out
+ i = (i+1) % thing.size
+ end
+ j += 1
+ end
+ print "#{"\b"*prev_size}\e[32m✓\e[0m (#{count}/#{count})\n"
+ end
+ end
+ end
+
+ desc 'Update all the checksums in the given referential'
+ task :update_checksums_in_referential, [:slug] => :environment do |t, args|
+ referential = Referential.find_by_slug(args[:slug])
+ update_checksums_for_referential referential
+ end
+
+ desc 'Update all the checksums in the given organisation'
+ task :update_checksums_in_organisation, [:organisation_id] => :environment do |t, args|
+ thing = %w(\\ | / —)
+ Organisation.find(args[:organisation_id]).referentials.find_each do |referential|
+ update_checksums_for_referential referential
+ end
+ end
end