-
Notifications
You must be signed in to change notification settings - Fork 466
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for scheme environment variables #326
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,23 @@ | ||
# This configuration was generated by `rubocop --auto-gen-config` | ||
# on 2015-03-06 13:49:50 +0100 using RuboCop version 0.28.0. | ||
# This configuration was generated by | ||
# `rubocop --auto-gen-config` | ||
# on 2015-10-25 15:59:02 -0700 using RuboCop version 0.34.2. | ||
# The point is for the user to remove these configuration records | ||
# one by one as the offenses are removed from the code base. | ||
# Note that changes in the inspected code, or installation of new | ||
# versions of RuboCop, may require this file to be generated again. | ||
|
||
# Offense count: 499 | ||
# Offense count: 804 | ||
# Configuration parameters: AllowURI, URISchemes. | ||
Metrics/LineLength: | ||
Max: 186 | ||
|
||
# Offense count: 66 | ||
# Configuration parameters: CountComments. | ||
Metrics/MethodLength: | ||
Max: 46 | ||
|
||
# Offense count: 2 | ||
# Configuration parameters: CountKeywordArgs. | ||
Metrics/ParameterLists: | ||
Max: 7 | ||
|
||
# Offense count: 9 | ||
Metrics/PerceivedComplexity: | ||
Max: 16 | ||
|
||
# Offense count: 94 | ||
# Cop supports --auto-correct. | ||
# Configuration parameters: EnforcedStyle, SupportedStyles. | ||
Style/DotPosition: | ||
Enabled: false | ||
|
||
# Offense count: 1 | ||
Style/DoubleNegation: | ||
Enabled: false |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
require 'xcodeproj/scheme/xml_element_wrapper' | ||
|
||
module Xcodeproj | ||
class XCScheme | ||
VARIABLES_NODE = 'EnvironmentVariables' | ||
VARIABLE_NODE = 'EnvironmentVariable' | ||
|
||
# This class wraps the EnvironmentVariables node of a .xcscheme XML file. This | ||
# is just a container of EnvironmentVariable objects. It can either appear on a | ||
# LaunchAction or TestAction scheme group. | ||
# | ||
class EnvironmentVariables < XMLElementWrapper | ||
# @param [nil,REXML::Element,Array<EnvironmentVariable>,Array<Hash{Symbol => String,Bool}>] node_or_variables | ||
# The 'EnvironmentVariables' XML node, or list of environment variables, that this object represents. | ||
# - If nil, an empty 'EnvironmentVariables' XML node will be created | ||
# - If an REXML::Element, it must be named 'EnvironmentVariables' | ||
# - If an Array of objects or Hashes, they'll each be passed to {#assign_variable} | ||
# | ||
def initialize(node_or_variables = nil) | ||
create_xml_element_with_fallback(node_or_variables, VARIABLES_NODE) do | ||
@all_variables = [] | ||
node_or_variables.each { |var| assign_variable(var) } unless node_or_variables.nil? | ||
end | ||
end | ||
|
||
# @return [Array<EnvironmentVariable>] | ||
# The key value pairs currently set in @xml_element | ||
# | ||
def all_variables | ||
@all_variables ||= @xml_element.get_elements(VARIABLE_NODE).map { |variable| EnvironmentVariable.new(variable) } | ||
end | ||
|
||
# Adds a given variable to the set of environment variables, or replaces it if that key already exists | ||
# | ||
# @param [EnvironmentVariable,Hash{Symbol => String,Bool}] variable | ||
# The variable to add or update, backed by an EnvironmentVariable node. | ||
# - If an EnvironmentVariable, the previous reference will still be valid | ||
# - If a Hash, must conform to {EnvironmentVariable#initialize} requirements | ||
# @return [Array<EnvironmentVariable>] | ||
# The new set of environment variables after addition | ||
# | ||
def assign_variable(variable) | ||
env_var = variable.is_a?(EnvironmentVariable) ? variable : EnvironmentVariable.new(variable) | ||
all_variables.each { |existing_var| remove_variable(existing_var) if existing_var.key == env_var.key } | ||
@xml_element.add_element(env_var.xml_element) | ||
@all_variables << env_var | ||
end | ||
|
||
# Removes a specified variable (by string or object) from the set of environment variables | ||
# | ||
# @param [EnvironmentVariable,String] variable | ||
# The variable to remove | ||
# @return [Array<EnvironmentVariable>] | ||
# The new set of environment variables after removal | ||
# | ||
def remove_variable(variable) | ||
env_var = variable.is_a?(EnvironmentVariable) ? variable : all_variables.find { |var| var.key == variable } | ||
raise "Unexpected parameter type: #{env_var.class}" unless env_var.is_a?(EnvironmentVariable) | ||
@xml_element.delete_element(env_var.xml_element) | ||
@all_variables -= [env_var] | ||
end | ||
|
||
# @param [String] key | ||
# The key to lookup | ||
# @return [EnvironmentVariable] variable | ||
# Returns the matching environment variable for a specified key | ||
# | ||
def [](key) | ||
all_variables.find { |var| var.key == key } | ||
end | ||
|
||
# Assigns a value for a specified key | ||
# | ||
# @param [String] key | ||
# The key to update in the environment variables | ||
# @param [String] value | ||
# The value to lookup | ||
# @return [EnvironmentVariable] variable | ||
# The newly updated environment variable | ||
# | ||
def []=(key, value) | ||
assign_variable(:key => key, :value => value) | ||
self[key] | ||
end | ||
|
||
# @return [Array<Hash{Symbol => String,Bool}>] | ||
# The current environment variables represented as an array | ||
# | ||
def to_a | ||
all_variables.map(&:to_h) | ||
end | ||
end | ||
|
||
# This class wraps the EnvironmentVariable node of a .xcscheme XML file. | ||
# Environment variables are accessible via the NSDictionary returned from | ||
# [[NSProcessInfo processInfo] environment] in your app code. | ||
# | ||
class EnvironmentVariable < XMLElementWrapper | ||
# @param [nil,REXML::Element,Hash{Symbol => String,Bool}] node_or_variable | ||
# - If nil, it will create a default XML node to use | ||
# - If a REXML::Element, should be a <EnvironmentVariable> XML node to wrap | ||
# - If a Hash, must contain keys :key and :value (Strings) and optionally :enabled (Boolean) | ||
# | ||
def initialize(node_or_variable) | ||
create_xml_element_with_fallback(node_or_variable, VARIABLE_NODE) do | ||
raise "Must pass a Hash with 'key' and 'value'!" unless node_or_variable.is_a?(Hash) && | ||
node_or_variable.key?(:key) && node_or_variable.key?(:value) | ||
|
||
@xml_element.attributes['key'] = node_or_variable[:key] | ||
@xml_element.attributes['value'] = node_or_variable[:value] | ||
|
||
if node_or_variable.key?(:enabled) | ||
@xml_element.attributes['isEnabled'] = bool_to_string(node_or_variable[:enabled]) | ||
else | ||
@xml_element.attributes['isEnabled'] = bool_to_string(true) | ||
end | ||
end | ||
end | ||
|
||
# Returns the EnvironmentValue's key | ||
# @return [String] | ||
# | ||
def key | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add YARD doc There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done (and for all below) |
||
@xml_element.attributes['key'] | ||
end | ||
|
||
# Sets the EnvironmentValue's key | ||
# @param [String] key | ||
# | ||
def key=(key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add YARD doc |
||
@xml_element.attributes['key'] = key | ||
end | ||
|
||
# Returns the EnvironmentValue's value | ||
# @return [String] | ||
# | ||
def value | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add YARD doc |
||
@xml_element.attributes['value'] | ||
end | ||
|
||
# Sets the EnvironmentValue's value | ||
# @param [String] value | ||
# | ||
def value=(value) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add YARD doc |
||
@xml_element.attributes['value'] = value | ||
end | ||
|
||
# Returns the EnvironmentValue's enabled state | ||
# @return [Bool] | ||
# | ||
def enabled | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add YARD doc |
||
string_to_bool(@xml_element.attributes['isEnabled']) | ||
end | ||
|
||
# Sets the EnvironmentValue's enabled state | ||
# @param [Bool] enabled | ||
# | ||
def enabled=(enabled) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add YARD doc |
||
@xml_element.attributes['isEnabled'] = bool_to_string(enabled) | ||
end | ||
|
||
# @return [Hash{:key => String, :value => String, :enabled => Bool}] | ||
# The environment variable XML node with attributes converted to a representative Hash | ||
# | ||
def to_h | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ruby standard name for this method is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems to be differing information. From what I've read, appears that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, actually you're right, didn't know about that. Let's keep |
||
{ :key => key, :value => value, :enabled => enabled } | ||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I definitely prefer that
assign_variable
.BTW, talking about
[]
and[]=
it actually seem like a good addition (but still while keeping thisassign_variable
of course).While
assign_variable
would take anEnvironmentVariable, Hash{Symbol=>String,Bool}
,[]=
would take the variable name as key and expect the variable content as value (and would assumeenabled=YES
, no way to specifyenabled
with that syntax). And[]
would take the variable name as key and return theEnvironmentVariable
.That could provide a nice syntactic sugar alternative. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me. Should
[]
operate on enabled variables only as well?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, since it would return an
EnvironmentVariable
anyway, I'd say let it access all variables (enabled or disabled). The user could still check the variable state once retrieved.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.