module Calabash module Android require "awesome_print" require "json" require "fileutils" require "securerandom" # Users preferences persisted across runs: # # ~/.calabash/preferences/preferences.json class Preferences def initialize dot_dir = Calabash::Android::DotDir.directory @path = File.join(dot_dir, "preferences", "preferences.json") end def to_s $stdout.puts "Preferences:" ap read end def inspect to_s end # !@visibility private def usage_tracking preferences = read unless valid_user_tracking_value?(preferences[:usage_tracking]) log_defaults_reset preferences[:usage_tracking] = defaults[:usage_tracking] write(preferences) end preferences[:usage_tracking] end # !@visibility private def usage_tracking=(value) if !valid_user_tracking_value?(value) raise ArgumentError, "Expected '#{value}' to be one of #{VALID_USAGE_TRACKING_VALUES.join(", ")}" end preferences = read preferences[:usage_tracking] = value write(preferences) end # !@visibility private def user_id preferences = read unless valid_user_id?(preferences[:user_id]) preferences[:user_id] = SecureRandom.uuid write(preferences) end preferences[:user_id] end # !@visibility private def user_id=(value) if !valid_user_id?(value) raise ArgumentError, "Expected '#{value}' to not be nil and not an empty string" end preferences = read preferences[:user_id] = value write(preferences) end private # @!visibility private def valid_user_tracking_value?(value) VALID_USAGE_TRACKING_VALUES.include?(value) end # @!visibility private def valid_user_id?(value) !value.nil? && value != "" && value.is_a?(String) end # @!visibility private # # The preferences version VERSION = "1.0" # @!visibility private # # Ordered by permissiveness left to right ascending. # # "system_info" implies that "events" are also allowed. VALID_USAGE_TRACKING_VALUES = ["none", "events", "system_info"] # @!visibility private def version read[:version] end # @!visibility private attr_reader :path # @!visibility private def ensure_preferences_dir dir = File.dirname(@path) unless File.exist?(dir) FileUtils.mkdir_p(dir) end end # @!visibility private def defaults { :version => VERSION, :usage_tracking => "system_info", :user_id => SecureRandom.uuid } end # @!visibility private def write(hash) if hash.nil? raise ArgumentError, "Hash to write cannot be nil" end if !hash.is_a?(Hash) raise ArgumentError, "Expected a Hash argument" end if hash.count == 0 raise ArgumentError, "Hash to write cannot be empty" end string = generate_json(hash) ensure_preferences_dir File.open(path, "w:UTF-8") do |file| file.write(string) end true end # @!visibility private def generate_json(hash) begin JSON.pretty_generate(hash) rescue TypeError, JSON::UnparserError => _ log_defaults_reset # Will always generate valid JSON generate_json(defaults) end end # @!visibility private def read if File.exist?(path) string = File.read(path).force_encoding("UTF-8") parse_json(string) else hash = defaults write(hash) hash end end # @!visibility private def parse_json(string) begin JSON.parse(string, {:symbolize_names => true}) rescue TypeError, JSON::ParserError => _ log_defaults_reset hash = defaults write(hash) hash end end # @!visibility private def log_defaults_reset $stderr.puts( %q{An error occurred while accessing your user preferences. We have reset the preferences to the default settings. If this happens on a regular basis, please create a GitHub issue. Your preferences control various Calabash behaviors. In particular, they tell us how much usage information you are willing to share. If you have previously turned off usage tracking, you will need to disable it again using the command line tools or the irb. We do not recommend that edit the preferences file by hand. }) end end end end