<commit_before>// Generated file, do not edit.
package lang

import buildpb "github.com/bazelbuild/buildtools/build_proto"

var TypeOf = map[string]buildpb.Attribute_Discriminator{
	"aar":                      buildpb.Attribute_LABEL,
	"actual":                   buildpb.Attribute_LABEL,
	"aliases":                  buildpb.Attribute_STRING_LIST,
	"all_files":                buildpb.Attribute_LABEL,
	"alwayslink":               buildpb.Attribute_BOOLEAN,
	"app_asset_catalogs":       buildpb.Attribute_LABEL_LIST,
	"app_bundle_id":            buildpb.Attribute_STRING,
	"app_deps":                 buildpb.Attribute_LABEL_LIST,
	"app_entitlements":         buildpb.Attribute_LABEL,
	"app_icon":                 buildpb.Attribute_STRING,
	"app_infoplists":           buildpb.Attribute_LABEL_LIST,
	"app_name":                 buildpb.Attribute_STRING,
	"app_provisioning_profile": buildpb.Attribute_LABEL,
	"app_resources":            buildpb.Attribute_LABEL_LIST,
	"app_storyboards":          buildpb.Attribute_LABEL_LIST,
	"app_strings":              buildpb.Attribute_LABEL_LIST,
	"app_structured_resources": buildpb.Attribute_LABEL_LIST,
	"archives":                 buildpb.Attribute_LABEL_LIST,
	"args":                     buildpb.Attribute_STRING_LIST,
	"artifact":                 buildpb.Attribute_STRING,
	"asset_catalogs":           buildpb.Attribute_LABEL_LIST,
	"assets":                   buildpb.Attribute_LABEL_LIST,
	"assets_dir":               buildpb.Attribute_STRING,
	"avoid_deps":               buildpb.Attribute_LABEL_LIST,
	"binary":                   buildpb.Attribute_LABEL,
	"binary_type":              buildpb.Attribute_STRING,
	"blacklisted_protos":       buildpb.Attribute_LABEL_LIST,
	"bootclasspath":            buildpb.Attribute_LABEL_LIST,
	"build_file":               buildpb.Attribute_STRING,
	"build_file_content":       buildpb.Attribute_STRING,
	"bundle_id":                buildpb.Attribute_STRING,
	"bundle_imports":           buildpb.Attribute_LABEL_LIST,
	"bundle_loader":            buildpb.Attribute_LABEL,
	"bundles":                  buildpb.Attribute_LABEL_LIST,
	"classpath_resources":      buildpb.Attribute_LABEL_LIST,
	"cmd":                            buildpb.Attribute_STRING,
	"command_line":                   buildpb.Attribute_STRING,
	"commit":                         buildpb.Attribute_STRING,
	"compatible_with":                buildpb.Attribute_LABEL_LIST,
	"compiler_files":                 buildpb.Attribute_LABEL,
	"constraints":                    buildpb.Attribute_STRING_LIST,
	"copts":                          buildpb.Attribute_STRING_LIST,
	"cpu":                            buildpb.Attribute_STRING,
	"create_executable":              buildpb.Attribute_BOOLEAN,
	"crunch_png":                     buildpb.Attribute_BOOLEAN,
	"custom_package":                 buildpb.Attribute_STRING,
	"data":                           buildpb.Attribute_LABEL_LIST,
	"datamodels":                     buildpb.Attribute_LABEL_LIST,
	"default":                        buildpb.Attribute_LABEL,
	"default_copts":                  buildpb.Attribute_STRING_LIST,
	"default_deprecation":            buildpb.Attribute_STRING,
	"default_hdrs_check":             buildpb.Attribute_STRING,
	"default_ios_sdk_version":        buildpb.Attribute_STRING,
	"default_macosx_sdk_version":     buildpb.Attribute_STRING,
	"default_python_version":         buildpb.Attribute_STRING,
	"default_testonly":               buildpb.Attribute_BOOLEAN,
	"default_tvos_sdk_version":       buildpb.Attribute_STRING,
	"default_visibility":             buildpb.Attribute_STRING_LIST,
	"default_watchos_sdk_version":    buildpb.Attribute_STRING,
	"defines":                        buildpb.Attribute_STRING_LIST,
	"densities":                      buildpb.Attribute_STRING_LIST,
	"deploy_manifest_lines":          buildpb.Attribute_STRING_LIST,
	"deprecation":                    buildpb.Attribute_STRING,
	"deps":                           buildpb.Attribute_LABEL_LIST,
	"dex_shards":                     buildpb.Attribute_INTEGER,
	"dexopts":                        buildpb.Attribute_STRING_LIST,
	"distribs":                       buildpb.Attribute_DISTRIBUTION_SET,
	"dwp_files":                      buildpb.Attribute_LABEL,
	"dylibs":                         buildpb.Attribute_LABEL_LIST,
	"dynamic_runtime_libs":           buildpb.Attribute_LABEL_LIST,
	"enable_modules":                 buildpb.Attribute_BOOLEAN,
	"encoding":                       buildpb.Attribute_STRING,
	"entitlements":                   buildpb.Attribute_LABEL,
	"entry_classes":                  buildpb.Attribute_STRING_LIST,
	"executable":                     buildpb.Attribute_BOOLEAN,
	"exported_plugins":               buildpb.Attribute_LABEL_LIST,
	"exports":                        buildpb.Attribute_LABEL_LIST,
	"exports_manifest":               buildpb.Attribute_BOOLEAN,
	"expression":                     buildpb.Attribute_STRING,
	"ext_bundle_id":                  buildpb.Attribute_STRING,
	"ext_entitlements":               buildpb.Attribute_LABEL,
	"ext_families":                   buildpb.Attribute_STRING_LIST,
	"ext_infoplists":                 buildpb.Attribute_LABEL_LIST,
	"ext_provisioning_profile":       buildpb.Attribute_LABEL,
	"ext_resources":                  buildpb.Attribute_LABEL_LIST,
	"ext_strings":                    buildpb.Attribute_LABEL_LIST,
	"ext_structured_resources":       buildpb.Attribute_LABEL_LIST,
	"extclasspath":                   buildpb.Attribute_LABEL_LIST,
	"extensions":                     buildpb.Attribute_LABEL_LIST,
	"extra_actions":                  buildpb.Attribute_LABEL_LIST,
	"extra_srcs":                     buildpb.Attribute_LABEL_LIST,
	"families":                       buildpb.Attribute_STRING_LIST,
	"features":                       buildpb.Attribute_STRING_LIST,
	"flaky":                          buildpb.Attribute_BOOLEAN,
	"framework_imports":              buildpb.Attribute_LABEL_LIST,
	"genclass":                       buildpb.Attribute_LABEL_LIST,
	"generates_api":                  buildpb.Attribute_BOOLEAN,
	"hdrs":                           buildpb.Attribute_LABEL_LIST,
	"header_compiler":                buildpb.Attribute_LABEL_LIST,
	"heuristic_label_expansion":      buildpb.Attribute_BOOLEAN,
	"idl_import_root":                buildpb.Attribute_STRING,
	"idl_parcelables":                buildpb.Attribute_LABEL_LIST,
	"idl_srcs":                       buildpb.Attribute_LABEL_LIST,
	"ijar":                           buildpb.Attribute_LABEL_LIST,
	"imports":                        buildpb.Attribute_STRING_LIST,
	"includes":                       buildpb.Attribute_STRING_LIST,
	"incremental_dexing":             buildpb.Attribute_TRISTATE,
	"infoplist":                      buildpb.Attribute_LABEL,
	"infoplists":                     buildpb.Attribute_LABEL_LIST,
	"init_submodules":                buildpb.Attribute_BOOLEAN,
	"ios_device_arg":                 buildpb.Attribute_STRING_LIST,
	"ios_test_target_device":         buildpb.Attribute_LABEL,
	"ios_version":                    buildpb.Attribute_STRING,
	"ipa_post_processor":             buildpb.Attribute_LABEL,
	"is_dynamic":                     buildpb.Attribute_BOOLEAN,
	"jars":                           buildpb.Attribute_LABEL_LIST,
	"javabuilder":                    buildpb.Attribute_LABEL_LIST,
	"javac":                          buildpb.Attribute_LABEL_LIST,
	"javac_supports_workers":         buildpb.Attribute_BOOLEAN,
	"javacopts":                      buildpb.Attribute_STRING_LIST,
	"jre_deps":                       buildpb.Attribute_LABEL_LIST,
	"jvm_flags":                      buildpb.Attribute_STRING_LIST,
	"jvm_opts":                       buildpb.Attribute_STRING_LIST,
	"launch_image":                   buildpb.Attribute_STRING,
	"launch_storyboard":              buildpb.Attribute_LABEL,
	"launcher":                       buildpb.Attribute_LABEL,
	"licenses":                       buildpb.Attribute_LICENSE,
	"linker_files":                   buildpb.Attribute_LABEL,
	"linkopts":                       buildpb.Attribute_STRING_LIST,
	"linkshared":                     buildpb.Attribute_BOOLEAN,
	"linkstamp":                      buildpb.Attribute_LABEL,
	"linkstatic":                     buildpb.Attribute_BOOLEAN,
	"local":                          buildpb.Attribute_BOOLEAN,
	"main":                           buildpb.Attribute_LABEL,
	"main_class":                     buildpb.Attribute_STRING,
	"main_dex_list":                  buildpb.Attribute_LABEL,
	"main_dex_list_opts":             buildpb.Attribute_STRING_LIST,
	"main_dex_proguard_specs":        buildpb.Attribute_LABEL_LIST,
	"malloc":                         buildpb.Attribute_LABEL,
	"manifest":                       buildpb.Attribute_LABEL,
	"manifest_merger":                buildpb.Attribute_STRING,
	"manifest_values":                buildpb.Attribute_STRING_DICT,
	"message":                        buildpb.Attribute_STRING,
	"misc":                           buildpb.Attribute_STRING_LIST,
	"mnemonics":                      buildpb.Attribute_STRING_LIST,
	"module_map":                     buildpb.Attribute_LABEL,
	"multidex":                       buildpb.Attribute_STRING,
	"name":                           buildpb.Attribute_STRING,
	"neverlink":                      buildpb.Attribute_BOOLEAN,
	"nocompress_extensions":          buildpb.Attribute_STRING_LIST,
	"nocopts":                        buildpb.Attribute_STRING,
	"non_arc_srcs":                   buildpb.Attribute_LABEL_LIST,
	"non_propagated_deps":            buildpb.Attribute_LABEL_LIST,
	"objcopy_files":                  buildpb.Attribute_LABEL,
	"options_file":                   buildpb.Attribute_LABEL,
	"opts":                           buildpb.Attribute_STRING_LIST,
	"out":                            buildpb.Attribute_STRING,
	"out_templates":                  buildpb.Attribute_STRING_LIST,
	"output_group":                   buildpb.Attribute_STRING,
	"output_licenses":                buildpb.Attribute_LICENSE,
	"output_to_bindir":               buildpb.Attribute_BOOLEAN,
	"outs":                           buildpb.Attribute_STRING_LIST,
	"path":                           buildpb.Attribute_STRING,
	"pch":                            buildpb.Attribute_LABEL,
	"per_proto_includes":             buildpb.Attribute_BOOLEAN,
	"platform_type":                  buildpb.Attribute_STRING,
	"plugin":                         buildpb.Attribute_LABEL,
	"plugins":                        buildpb.Attribute_LABEL_LIST,
	"portable_proto_filters":         buildpb.Attribute_LABEL_LIST,
	"prefix":                         buildpb.Attribute_STRING,
	"processor_class":                buildpb.Attribute_STRING,
	"proguard_apply_mapping":         buildpb.Attribute_LABEL,
	"proguard_generate_mapping":      buildpb.Attribute_BOOLEAN,
	"proguard_specs":                 buildpb.Attribute_LABEL_LIST,
	"provisioning_profile":           buildpb.Attribute_LABEL,
	"pytype_deps":                    buildpb.Attribute_LABEL_LIST,
	"remote":                         buildpb.Attribute_STRING,
	"repository":                     buildpb.Attribute_STRING,
	"require_defined_version":        buildpb.Attribute_BOOLEAN,
	"requires_action_output":         buildpb.Attribute_BOOLEAN,
	"resource_configuration_filters": buildpb.Attribute_STRING_LIST,
	"resource_files":                 buildpb.Attribute_LABEL_LIST,
	"resource_strip_prefix":          buildpb.Attribute_STRING,
	"resources":                      buildpb.Attribute_LABEL_LIST,
	"restricted_to":                  buildpb.Attribute_LABEL_LIST,
	"runtime":                        buildpb.Attribute_LABEL,
	"runtime_deps":                   buildpb.Attribute_LABEL_LIST,
	"scope":                          buildpb.Attribute_LABEL_LIST,
	"sdk_dylibs":                     buildpb.Attribute_STRING_LIST,
	"sdk_frameworks":                 buildpb.Attribute_STRING_LIST,
	"sdk_includes":                   buildpb.Attribute_STRING_LIST,
	"server":                         buildpb.Attribute_STRING,
	"settings_file":                  buildpb.Attribute_STRING,
	"sha1":                           buildpb.Attribute_STRING,
	"sha256":                         buildpb.Attribute_STRING,
	"shard_count":                    buildpb.Attribute_INTEGER,
	"singlejar":                      buildpb.Attribute_LABEL_LIST,
	"size":                           buildpb.Attribute_STRING,
	"source_version":                 buildpb.Attribute_STRING,
	"srcjar":                         buildpb.Attribute_LABEL,
	"srcs":                           buildpb.Attribute_LABEL_LIST,
	"srcs_version":                   buildpb.Attribute_STRING,
	"stamp":                          buildpb.Attribute_TRISTATE,
	"static_runtime_libs":            buildpb.Attribute_LABEL_LIST,
	"storyboards":                    buildpb.Attribute_LABEL_LIST,
	"strict":                         buildpb.Attribute_BOOLEAN,
	"strings":                        buildpb.Attribute_LABEL_LIST,
	"strip":                          buildpb.Attribute_BOOLEAN,
	"strip_files":                    buildpb.Attribute_LABEL,
	"strip_prefix":                   buildpb.Attribute_STRING,
	"structured_resources":           buildpb.Attribute_LABEL_LIST,
	"supports_header_parsing":        buildpb.Attribute_BOOLEAN,
	"supports_param_files":           buildpb.Attribute_BOOLEAN,
	"tag":            buildpb.Attribute_STRING,
	"tags":           buildpb.Attribute_STRING_LIST,
	"target_device":  buildpb.Attribute_LABEL,
	"target_version": buildpb.Attribute_STRING,
	"test_class":     buildpb.Attribute_STRING,
	"testonly":       buildpb.Attribute_BOOLEAN,
	"tests":          buildpb.Attribute_LABEL_LIST,
	"textual_hdrs":   buildpb.Attribute_LABEL_LIST,
	"timeout":        buildpb.Attribute_STRING,
	"toolchains":     buildpb.Attribute_LABEL_LIST,
	"tools":          buildpb.Attribute_LABEL_LIST,
	"type":           buildpb.Attribute_STRING,
	"url":            buildpb.Attribute_STRING,
	"use_objc_header_names": buildpb.Attribute_BOOLEAN,
	"use_testrunner":        buildpb.Attribute_BOOLEAN,
	"values":                buildpb.Attribute_STRING_DICT,
	"version":               buildpb.Attribute_STRING,
	"versions":              buildpb.Attribute_LABEL_LIST,
	"visibility":            buildpb.Attribute_STRING_LIST,
	"weak_sdk_frameworks":   buildpb.Attribute_STRING_LIST,
	"xcode":                 buildpb.Attribute_LABEL,
	"xctest":                buildpb.Attribute_BOOLEAN,
	"xctest_app":            buildpb.Attribute_LABEL,
	"xibs":                  buildpb.Attribute_LABEL_LIST,
	"xlint":                 buildpb.Attribute_STRING_LIST,
}
<commit_msg>Fix tests broken by a formatting change in tables.gen.go<commit_after>// Generated file, do not edit.
package lang

import buildpb "github.com/bazelbuild/buildtools/build_proto"

var TypeOf = map[string]buildpb.Attribute_Discriminator{
	"aar":	buildpb.Attribute_LABEL,
	"actual":	buildpb.Attribute_LABEL,
	"aliases":	buildpb.Attribute_STRING_LIST,
	"all_files":	buildpb.Attribute_LABEL,
	"alwayslink":	buildpb.Attribute_BOOLEAN,
	"app_asset_catalogs":	buildpb.Attribute_LABEL_LIST,
	"app_bundle_id":	buildpb.Attribute_STRING,
	"app_deps":	buildpb.Attribute_LABEL_LIST,
	"app_entitlements":	buildpb.Attribute_LABEL,
	"app_icon":	buildpb.Attribute_STRING,
	"app_infoplists":	buildpb.Attribute_LABEL_LIST,
	"app_name":	buildpb.Attribute_STRING,
	"app_provisioning_profile":	buildpb.Attribute_LABEL,
	"app_resources":	buildpb.Attribute_LABEL_LIST,
	"app_storyboards":	buildpb.Attribute_LABEL_LIST,
	"app_strings":	buildpb.Attribute_LABEL_LIST,
	"app_structured_resources":	buildpb.Attribute_LABEL_LIST,
	"archives":	buildpb.Attribute_LABEL_LIST,
	"args":	buildpb.Attribute_STRING_LIST,
	"artifact":	buildpb.Attribute_STRING,
	"asset_catalogs":	buildpb.Attribute_LABEL_LIST,
	"assets":	buildpb.Attribute_LABEL_LIST,
	"assets_dir":	buildpb.Attribute_STRING,
	"avoid_deps":	buildpb.Attribute_LABEL_LIST,
	"binary":	buildpb.Attribute_LABEL,
	"binary_type":	buildpb.Attribute_STRING,
	"blacklisted_protos":	buildpb.Attribute_LABEL_LIST,
	"bootclasspath":	buildpb.Attribute_LABEL_LIST,
	"build_file":	buildpb.Attribute_STRING,
	"build_file_content":	buildpb.Attribute_STRING,
	"bundle_id":	buildpb.Attribute_STRING,
	"bundle_imports":	buildpb.Attribute_LABEL_LIST,
	"bundle_loader":	buildpb.Attribute_LABEL,
	"bundles":	buildpb.Attribute_LABEL_LIST,
	"classpath_resources":	buildpb.Attribute_LABEL_LIST,
	"cmd":	buildpb.Attribute_STRING,
	"command_line":	buildpb.Attribute_STRING,
	"commit":	buildpb.Attribute_STRING,
	"compatible_with":	buildpb.Attribute_LABEL_LIST,
	"compiler_files":	buildpb.Attribute_LABEL,
	"constraints":	buildpb.Attribute_STRING_LIST,
	"copts":	buildpb.Attribute_STRING_LIST,
	"cpu":	buildpb.Attribute_STRING,
	"create_executable":	buildpb.Attribute_BOOLEAN,
	"crunch_png":	buildpb.Attribute_BOOLEAN,
	"custom_package":	buildpb.Attribute_STRING,
	"data":	buildpb.Attribute_LABEL_LIST,
	"datamodels":	buildpb.Attribute_LABEL_LIST,
	"default":	buildpb.Attribute_LABEL,
	"default_copts":	buildpb.Attribute_STRING_LIST,
	"default_deprecation":	buildpb.Attribute_STRING,
	"default_hdrs_check":	buildpb.Attribute_STRING,
	"default_ios_sdk_version":	buildpb.Attribute_STRING,
	"default_macosx_sdk_version":	buildpb.Attribute_STRING,
	"default_python_version":	buildpb.Attribute_STRING,
	"default_testonly":	buildpb.Attribute_BOOLEAN,
	"default_tvos_sdk_version":	buildpb.Attribute_STRING,
	"default_visibility":	buildpb.Attribute_STRING_LIST,
	"default_watchos_sdk_version":	buildpb.Attribute_STRING,
	"defines":	buildpb.Attribute_STRING_LIST,
	"densities":	buildpb.Attribute_STRING_LIST,
	"deploy_manifest_lines":	buildpb.Attribute_STRING_LIST,
	"deprecation":	buildpb.Attribute_STRING,
	"deps":	buildpb.Attribute_LABEL_LIST,
	"dex_shards":	buildpb.Attribute_INTEGER,
	"dexopts":	buildpb.Attribute_STRING_LIST,
	"distribs":	buildpb.Attribute_DISTRIBUTION_SET,
	"dwp_files":	buildpb.Attribute_LABEL,
	"dylibs":	buildpb.Attribute_LABEL_LIST,
	"dynamic_runtime_libs":	buildpb.Attribute_LABEL_LIST,
	"enable_modules":	buildpb.Attribute_BOOLEAN,
	"encoding":	buildpb.Attribute_STRING,
	"entitlements":	buildpb.Attribute_LABEL,
	"entry_classes":	buildpb.Attribute_STRING_LIST,
	"executable":	buildpb.Attribute_BOOLEAN,
	"exported_plugins":	buildpb.Attribute_LABEL_LIST,
	"exports":	buildpb.Attribute_LABEL_LIST,
	"exports_manifest":	buildpb.Attribute_BOOLEAN,
	"expression":	buildpb.Attribute_STRING,
	"ext_bundle_id":	buildpb.Attribute_STRING,
	"ext_entitlements":	buildpb.Attribute_LABEL,
	"ext_families":	buildpb.Attribute_STRING_LIST,
	"ext_infoplists":	buildpb.Attribute_LABEL_LIST,
	"ext_provisioning_profile":	buildpb.Attribute_LABEL,
	"ext_resources":	buildpb.Attribute_LABEL_LIST,
	"ext_strings":	buildpb.Attribute_LABEL_LIST,
	"ext_structured_resources":	buildpb.Attribute_LABEL_LIST,
	"extclasspath":	buildpb.Attribute_LABEL_LIST,
	"extensions":	buildpb.Attribute_LABEL_LIST,
	"extra_actions":	buildpb.Attribute_LABEL_LIST,
	"extra_srcs":	buildpb.Attribute_LABEL_LIST,
	"families":	buildpb.Attribute_STRING_LIST,
	"features":	buildpb.Attribute_STRING_LIST,
	"flaky":	buildpb.Attribute_BOOLEAN,
	"framework_imports":	buildpb.Attribute_LABEL_LIST,
	"genclass":	buildpb.Attribute_LABEL_LIST,
	"generates_api":	buildpb.Attribute_BOOLEAN,
	"hdrs":	buildpb.Attribute_LABEL_LIST,
	"header_compiler":	buildpb.Attribute_LABEL_LIST,
	"heuristic_label_expansion":	buildpb.Attribute_BOOLEAN,
	"idl_import_root":	buildpb.Attribute_STRING,
	"idl_parcelables":	buildpb.Attribute_LABEL_LIST,
	"idl_srcs":	buildpb.Attribute_LABEL_LIST,
	"ijar":	buildpb.Attribute_LABEL_LIST,
	"imports":	buildpb.Attribute_STRING_LIST,
	"includes":	buildpb.Attribute_STRING_LIST,
	"incremental_dexing":	buildpb.Attribute_TRISTATE,
	"infoplist":	buildpb.Attribute_LABEL,
	"infoplists":	buildpb.Attribute_LABEL_LIST,
	"init_submodules":	buildpb.Attribute_BOOLEAN,
	"ios_device_arg":	buildpb.Attribute_STRING_LIST,
	"ios_test_target_device":	buildpb.Attribute_LABEL,
	"ios_version":	buildpb.Attribute_STRING,
	"ipa_post_processor":	buildpb.Attribute_LABEL,
	"is_dynamic":	buildpb.Attribute_BOOLEAN,
	"jars":	buildpb.Attribute_LABEL_LIST,
	"javabuilder":	buildpb.Attribute_LABEL_LIST,
	"javac":	buildpb.Attribute_LABEL_LIST,
	"javac_supports_workers":	buildpb.Attribute_BOOLEAN,
	"javacopts":	buildpb.Attribute_STRING_LIST,
	"jre_deps":	buildpb.Attribute_LABEL_LIST,
	"jvm_flags":	buildpb.Attribute_STRING_LIST,
	"jvm_opts":	buildpb.Attribute_STRING_LIST,
	"launch_image":	buildpb.Attribute_STRING,
	"launch_storyboard":	buildpb.Attribute_LABEL,
	"launcher":	buildpb.Attribute_LABEL,
	"licenses":	buildpb.Attribute_LICENSE,
	"linker_files":	buildpb.Attribute_LABEL,
	"linkopts":	buildpb.Attribute_STRING_LIST,
	"linkshared":	buildpb.Attribute_BOOLEAN,
	"linkstamp":	buildpb.Attribute_LABEL,
	"linkstatic":	buildpb.Attribute_BOOLEAN,
	"local":	buildpb.Attribute_BOOLEAN,
	"main":	buildpb.Attribute_LABEL,
	"main_class":	buildpb.Attribute_STRING,
	"main_dex_list":	buildpb.Attribute_LABEL,
	"main_dex_list_opts":	buildpb.Attribute_STRING_LIST,
	"main_dex_proguard_specs":	buildpb.Attribute_LABEL_LIST,
	"malloc":	buildpb.Attribute_LABEL,
	"manifest":	buildpb.Attribute_LABEL,
	"manifest_merger":	buildpb.Attribute_STRING,
	"manifest_values":	buildpb.Attribute_STRING_DICT,
	"message":	buildpb.Attribute_STRING,
	"misc":	buildpb.Attribute_STRING_LIST,
	"mnemonics":	buildpb.Attribute_STRING_LIST,
	"module_map":	buildpb.Attribute_LABEL,
	"multidex":	buildpb.Attribute_STRING,
	"name":	buildpb.Attribute_STRING,
	"neverlink":	buildpb.Attribute_BOOLEAN,
	"nocompress_extensions":	buildpb.Attribute_STRING_LIST,
	"nocopts":	buildpb.Attribute_STRING,
	"non_arc_srcs":	buildpb.Attribute_LABEL_LIST,
	"non_propagated_deps":	buildpb.Attribute_LABEL_LIST,
	"objcopy_files":	buildpb.Attribute_LABEL,
	"options_file":	buildpb.Attribute_LABEL,
	"opts":	buildpb.Attribute_STRING_LIST,
	"out":	buildpb.Attribute_STRING,
	"out_templates":	buildpb.Attribute_STRING_LIST,
	"output_group":	buildpb.Attribute_STRING,
	"output_licenses":	buildpb.Attribute_LICENSE,
	"output_to_bindir":	buildpb.Attribute_BOOLEAN,
	"outs":	buildpb.Attribute_STRING_LIST,
	"path":	buildpb.Attribute_STRING,
	"pch":	buildpb.Attribute_LABEL,
	"per_proto_includes":	buildpb.Attribute_BOOLEAN,
	"platform_type":	buildpb.Attribute_STRING,
	"plugin":	buildpb.Attribute_LABEL,
	"plugins":	buildpb.Attribute_LABEL_LIST,
	"portable_proto_filters":	buildpb.Attribute_LABEL_LIST,
	"prefix":	buildpb.Attribute_STRING,
	"processor_class":	buildpb.Attribute_STRING,
	"proguard_apply_mapping":	buildpb.Attribute_LABEL,
	"proguard_generate_mapping":	buildpb.Attribute_BOOLEAN,
	"proguard_specs":	buildpb.Attribute_LABEL_LIST,
	"provisioning_profile":	buildpb.Attribute_LABEL,
	"pytype_deps":	buildpb.Attribute_LABEL_LIST,
	"remote":	buildpb.Attribute_STRING,
	"repository":	buildpb.Attribute_STRING,
	"require_defined_version":	buildpb.Attribute_BOOLEAN,
	"requires_action_output":	buildpb.Attribute_BOOLEAN,
	"resource_configuration_filters":	buildpb.Attribute_STRING_LIST,
	"resource_files":	buildpb.Attribute_LABEL_LIST,
	"resource_strip_prefix":	buildpb.Attribute_STRING,
	"resources":	buildpb.Attribute_LABEL_LIST,
	"restricted_to":	buildpb.Attribute_LABEL_LIST,
	"runtime":	buildpb.Attribute_LABEL,
	"runtime_deps":	buildpb.Attribute_LABEL_LIST,
	"scope":	buildpb.Attribute_LABEL_LIST,
	"sdk_dylibs":	buildpb.Attribute_STRING_LIST,
	"sdk_frameworks":	buildpb.Attribute_STRING_LIST,
	"sdk_includes":	buildpb.Attribute_STRING_LIST,
	"server":	buildpb.Attribute_STRING,
	"settings_file":	buildpb.Attribute_STRING,
	"sha1":	buildpb.Attribute_STRING,
	"sha256":	buildpb.Attribute_STRING,
	"shard_count":	buildpb.Attribute_INTEGER,
	"singlejar":	buildpb.Attribute_LABEL_LIST,
	"size":	buildpb.Attribute_STRING,
	"source_version":	buildpb.Attribute_STRING,
	"srcjar":	buildpb.Attribute_LABEL,
	"srcs":	buildpb.Attribute_LABEL_LIST,
	"srcs_version":	buildpb.Attribute_STRING,
	"stamp":	buildpb.Attribute_TRISTATE,
	"static_runtime_libs":	buildpb.Attribute_LABEL_LIST,
	"storyboards":	buildpb.Attribute_LABEL_LIST,
	"strict":	buildpb.Attribute_BOOLEAN,
	"strings":	buildpb.Attribute_LABEL_LIST,
	"strip":	buildpb.Attribute_BOOLEAN,
	"strip_files":	buildpb.Attribute_LABEL,
	"strip_prefix":	buildpb.Attribute_STRING,
	"structured_resources":	buildpb.Attribute_LABEL_LIST,
	"supports_header_parsing":	buildpb.Attribute_BOOLEAN,
	"supports_param_files":	buildpb.Attribute_BOOLEAN,
	"tag":	buildpb.Attribute_STRING,
	"tags":	buildpb.Attribute_STRING_LIST,
	"target_device":	buildpb.Attribute_LABEL,
	"target_version":	buildpb.Attribute_STRING,
	"test_class":	buildpb.Attribute_STRING,
	"testonly":	buildpb.Attribute_BOOLEAN,
	"tests":	buildpb.Attribute_LABEL_LIST,
	"textual_hdrs":	buildpb.Attribute_LABEL_LIST,
	"timeout":	buildpb.Attribute_STRING,
	"toolchains":	buildpb.Attribute_LABEL_LIST,
	"tools":	buildpb.Attribute_LABEL_LIST,
	"type":	buildpb.Attribute_STRING,
	"url":	buildpb.Attribute_STRING,
	"use_objc_header_names":	buildpb.Attribute_BOOLEAN,
	"use_testrunner":	buildpb.Attribute_BOOLEAN,
	"values":	buildpb.Attribute_STRING_DICT,
	"version":	buildpb.Attribute_STRING,
	"versions":	buildpb.Attribute_LABEL_LIST,
	"visibility":	buildpb.Attribute_STRING_LIST,
	"weak_sdk_frameworks":	buildpb.Attribute_STRING_LIST,
	"xcode":	buildpb.Attribute_LABEL,
	"xctest":	buildpb.Attribute_BOOLEAN,
	"xctest_app":	buildpb.Attribute_LABEL,
	"xibs":	buildpb.Attribute_LABEL_LIST,
	"xlint":	buildpb.Attribute_STRING_LIST,
}
<|endoftext|>


<commit_before>package consul

import (
	"fmt"
	"time"

	"github.com/armon/go-metrics"
	"github.com/hashicorp/consul/consul/structs"
	"github.com/hashicorp/go-uuid"
)

// Session endpoint is used to manipulate sessions for KV
type Session struct {
	srv *Server
}

// Apply is used to apply a modifying request to the data store. This should
// only be used for operations that modify the data
func (s *Session) Apply(args *structs.SessionRequest, reply *string) error {
	if done, err := s.srv.forward("Session.Apply", args, args, reply); done {
		return err
	}
	defer metrics.MeasureSince([]string{"consul", "session", "apply"}, time.Now())

	// Verify the args
	if args.Session.ID == "" && args.Op == structs.SessionDestroy {
		return fmt.Errorf("Must provide ID")
	}
	if args.Session.Node == "" && args.Op == structs.SessionCreate {
		return fmt.Errorf("Must provide Node")
	}

	// Fetch the ACL token, if any, and apply the policy.
	acl, err := s.srv.resolveToken(args.Token)
	if err != nil {
		return err
	}
	if acl != nil && s.srv.config.ACLEnforceVersion8 {
		switch args.Op {
		case structs.SessionDestroy:
			state := s.srv.fsm.State()
			_, existing, err := state.SessionGet(args.Session.ID)
			if err != nil {
				return fmt.Errorf("Unknown session %q", args.Session.ID)
			}
			if !acl.SessionWrite(existing.Node) {
				return permissionDeniedErr
			}

		case structs.SessionCreate:
			if !acl.SessionWrite(args.Session.Node) {
				return permissionDeniedErr
			}

		default:
			return fmt.Errorf("Invalid session operation %q, args.Op")
		}
	}

	// Ensure that the specified behavior is allowed
	switch args.Session.Behavior {
	case "":
		// Default behavior to Release for backwards compatibility
		args.Session.Behavior = structs.SessionKeysRelease
	case structs.SessionKeysRelease:
	case structs.SessionKeysDelete:
	default:
		return fmt.Errorf("Invalid Behavior setting '%s'", args.Session.Behavior)
	}

	// Ensure the Session TTL is valid if provided
	if args.Session.TTL != "" {
		ttl, err := time.ParseDuration(args.Session.TTL)
		if err != nil {
			return fmt.Errorf("Session TTL '%s' invalid: %v", args.Session.TTL, err)
		}

		if ttl != 0 && (ttl < s.srv.config.SessionTTLMin || ttl > structs.SessionTTLMax) {
			return fmt.Errorf("Invalid Session TTL '%d', must be between [%v=%v]",
				ttl, s.srv.config.SessionTTLMin, structs.SessionTTLMax)
		}
	}

	// If this is a create, we must generate the Session ID. This must
	// be done prior to appending to the raft log, because the ID is not
	// deterministic. Once the entry is in the log, the state update MUST
	// be deterministic or the followers will not converge.
	if args.Op == structs.SessionCreate {
		// Generate a new session ID, verify uniqueness
		state := s.srv.fsm.State()
		for {
			var err error
			if args.Session.ID, err = uuid.GenerateUUID(); err != nil {
				s.srv.logger.Printf("[ERR] consul.session: UUID generation failed: %v", err)
				return err
			}
			_, sess, err := state.SessionGet(args.Session.ID)
			if err != nil {
				s.srv.logger.Printf("[ERR] consul.session: Session lookup failed: %v", err)
				return err
			}
			if sess == nil {
				break
			}
		}
	}

	// Apply the update
	resp, err := s.srv.raftApply(structs.SessionRequestType, args)
	if err != nil {
		s.srv.logger.Printf("[ERR] consul.session: Apply failed: %v", err)
		return err
	}

	if args.Op == structs.SessionCreate && args.Session.TTL != "" {
		// If we created a session with a TTL, reset the expiration timer
		s.srv.resetSessionTimer(args.Session.ID, &args.Session)
	} else if args.Op == structs.SessionDestroy {
		// If we destroyed a session, it might potentially have a TTL,
		// and we need to clear the timer
		s.srv.clearSessionTimer(args.Session.ID)
	}

	if respErr, ok := resp.(error); ok {
		return respErr
	}

	// Check if the return type is a string
	if respString, ok := resp.(string); ok {
		*reply = respString
	}
	return nil
}

// Get is used to retrieve a single session
func (s *Session) Get(args *structs.SessionSpecificRequest,
	reply *structs.IndexedSessions) error {
	if done, err := s.srv.forward("Session.Get", args, args, reply); done {
		return err
	}

	// Get the local state
	state := s.srv.fsm.State()
	return s.srv.blockingRPC(
		&args.QueryOptions,
		&reply.QueryMeta,
		state.GetQueryWatch("SessionGet"),
		func() error {
			index, session, err := state.SessionGet(args.Session)
			if err != nil {
				return err
			}

			reply.Index = index
			if session != nil {
				reply.Sessions = structs.Sessions{session}
			} else {
				reply.Sessions = nil
			}
			if err := s.srv.filterACL(args.Token, reply); err != nil {
				return err
			}
			return nil
		})
}

// List is used to list all the active sessions
func (s *Session) List(args *structs.DCSpecificRequest,
	reply *structs.IndexedSessions) error {
	if done, err := s.srv.forward("Session.List", args, args, reply); done {
		return err
	}

	// Get the local state
	state := s.srv.fsm.State()
	return s.srv.blockingRPC(
		&args.QueryOptions,
		&reply.QueryMeta,
		state.GetQueryWatch("SessionList"),
		func() error {
			index, sessions, err := state.SessionList()
			if err != nil {
				return err
			}

			reply.Index, reply.Sessions = index, sessions
			if err := s.srv.filterACL(args.Token, reply); err != nil {
				return err
			}
			return nil
		})
}

// NodeSessions is used to get all the sessions for a particular node
func (s *Session) NodeSessions(args *structs.NodeSpecificRequest,
	reply *structs.IndexedSessions) error {
	if done, err := s.srv.forward("Session.NodeSessions", args, args, reply); done {
		return err
	}

	// Get the local state
	state := s.srv.fsm.State()
	return s.srv.blockingRPC(
		&args.QueryOptions,
		&reply.QueryMeta,
		state.GetQueryWatch("NodeSessions"),
		func() error {
			index, sessions, err := state.NodeSessions(args.Node)
			if err != nil {
				return err
			}

			reply.Index, reply.Sessions = index, sessions
			if err := s.srv.filterACL(args.Token, reply); err != nil {
				return err
			}
			return nil
		})
}

// Renew is used to renew the TTL on a single session
func (s *Session) Renew(args *structs.SessionSpecificRequest,
	reply *structs.IndexedSessions) error {
	if done, err := s.srv.forward("Session.Renew", args, args, reply); done {
		return err
	}
	defer metrics.MeasureSince([]string{"consul", "session", "renew"}, time.Now())

	// Get the session, from local state.
	state := s.srv.fsm.State()
	index, session, err := state.SessionGet(args.Session)
	if err != nil {
		return err
	}

	reply.Index = index
	if session == nil {
		return nil
	}

	// Fetch the ACL token, if any, and apply the policy.
	acl, err := s.srv.resolveToken(args.Token)
	if err != nil {
		return err
	}
	if acl != nil && s.srv.config.ACLEnforceVersion8 {
		if !acl.SessionWrite(session.Node) {
			return permissionDeniedErr
		}
	}

	// Reset the session TTL timer.
	reply.Sessions = structs.Sessions{session}
	if err := s.srv.resetSessionTimer(args.Session, session); err != nil {
		s.srv.logger.Printf("[ERR] consul.session: Session renew failed: %v", err)
		return err
	}

	return nil
}
<commit_msg>fix fmt.Errorf error<commit_after>package consul

import (
	"fmt"
	"time"

	"github.com/armon/go-metrics"
	"github.com/hashicorp/consul/consul/structs"
	"github.com/hashicorp/go-uuid"
)

// Session endpoint is used to manipulate sessions for KV
type Session struct {
	srv *Server
}

// Apply is used to apply a modifying request to the data store. This should
// only be used for operations that modify the data
func (s *Session) Apply(args *structs.SessionRequest, reply *string) error {
	if done, err := s.srv.forward("Session.Apply", args, args, reply); done {
		return err
	}
	defer metrics.MeasureSince([]string{"consul", "session", "apply"}, time.Now())

	// Verify the args
	if args.Session.ID == "" && args.Op == structs.SessionDestroy {
		return fmt.Errorf("Must provide ID")
	}
	if args.Session.Node == "" && args.Op == structs.SessionCreate {
		return fmt.Errorf("Must provide Node")
	}

	// Fetch the ACL token, if any, and apply the policy.
	acl, err := s.srv.resolveToken(args.Token)
	if err != nil {
		return err
	}
	if acl != nil && s.srv.config.ACLEnforceVersion8 {
		switch args.Op {
		case structs.SessionDestroy:
			state := s.srv.fsm.State()
			_, existing, err := state.SessionGet(args.Session.ID)
			if err != nil {
				return fmt.Errorf("Unknown session %q", args.Session.ID)
			}
			if !acl.SessionWrite(existing.Node) {
				return permissionDeniedErr
			}

		case structs.SessionCreate:
			if !acl.SessionWrite(args.Session.Node) {
				return permissionDeniedErr
			}

		default:
			return fmt.Errorf("Invalid session operation %q", args.Op)
		}
	}

	// Ensure that the specified behavior is allowed
	switch args.Session.Behavior {
	case "":
		// Default behavior to Release for backwards compatibility
		args.Session.Behavior = structs.SessionKeysRelease
	case structs.SessionKeysRelease:
	case structs.SessionKeysDelete:
	default:
		return fmt.Errorf("Invalid Behavior setting '%s'", args.Session.Behavior)
	}

	// Ensure the Session TTL is valid if provided
	if args.Session.TTL != "" {
		ttl, err := time.ParseDuration(args.Session.TTL)
		if err != nil {
			return fmt.Errorf("Session TTL '%s' invalid: %v", args.Session.TTL, err)
		}

		if ttl != 0 && (ttl < s.srv.config.SessionTTLMin || ttl > structs.SessionTTLMax) {
			return fmt.Errorf("Invalid Session TTL '%d', must be between [%v=%v]",
				ttl, s.srv.config.SessionTTLMin, structs.SessionTTLMax)
		}
	}

	// If this is a create, we must generate the Session ID. This must
	// be done prior to appending to the raft log, because the ID is not
	// deterministic. Once the entry is in the log, the state update MUST
	// be deterministic or the followers will not converge.
	if args.Op == structs.SessionCreate {
		// Generate a new session ID, verify uniqueness
		state := s.srv.fsm.State()
		for {
			var err error
			if args.Session.ID, err = uuid.GenerateUUID(); err != nil {
				s.srv.logger.Printf("[ERR] consul.session: UUID generation failed: %v", err)
				return err
			}
			_, sess, err := state.SessionGet(args.Session.ID)
			if err != nil {
				s.srv.logger.Printf("[ERR] consul.session: Session lookup failed: %v", err)
				return err
			}
			if sess == nil {
				break
			}
		}
	}

	// Apply the update
	resp, err := s.srv.raftApply(structs.SessionRequestType, args)
	if err != nil {
		s.srv.logger.Printf("[ERR] consul.session: Apply failed: %v", err)
		return err
	}

	if args.Op == structs.SessionCreate && args.Session.TTL != "" {
		// If we created a session with a TTL, reset the expiration timer
		s.srv.resetSessionTimer(args.Session.ID, &args.Session)
	} else if args.Op == structs.SessionDestroy {
		// If we destroyed a session, it might potentially have a TTL,
		// and we need to clear the timer
		s.srv.clearSessionTimer(args.Session.ID)
	}

	if respErr, ok := resp.(error); ok {
		return respErr
	}

	// Check if the return type is a string
	if respString, ok := resp.(string); ok {
		*reply = respString
	}
	return nil
}

// Get is used to retrieve a single session
func (s *Session) Get(args *structs.SessionSpecificRequest,
	reply *structs.IndexedSessions) error {
	if done, err := s.srv.forward("Session.Get", args, args, reply); done {
		return err
	}

	// Get the local state
	state := s.srv.fsm.State()
	return s.srv.blockingRPC(
		&args.QueryOptions,
		&reply.QueryMeta,
		state.GetQueryWatch("SessionGet"),
		func() error {
			index, session, err := state.SessionGet(args.Session)
			if err != nil {
				return err
			}

			reply.Index = index
			if session != nil {
				reply.Sessions = structs.Sessions{session}
			} else {
				reply.Sessions = nil
			}
			if err := s.srv.filterACL(args.Token, reply); err != nil {
				return err
			}
			return nil
		})
}

// List is used to list all the active sessions
func (s *Session) List(args *structs.DCSpecificRequest,
	reply *structs.IndexedSessions) error {
	if done, err := s.srv.forward("Session.List", args, args, reply); done {
		return err
	}

	// Get the local state
	state := s.srv.fsm.State()
	return s.srv.blockingRPC(
		&args.QueryOptions,
		&reply.QueryMeta,
		state.GetQueryWatch("SessionList"),
		func() error {
			index, sessions, err := state.SessionList()
			if err != nil {
				return err
			}

			reply.Index, reply.Sessions = index, sessions
			if err := s.srv.filterACL(args.Token, reply); err != nil {
				return err
			}
			return nil
		})
}

// NodeSessions is used to get all the sessions for a particular node
func (s *Session) NodeSessions(args *structs.NodeSpecificRequest,
	reply *structs.IndexedSessions) error {
	if done, err := s.srv.forward("Session.NodeSessions", args, args, reply); done {
		return err
	}

	// Get the local state
	state := s.srv.fsm.State()
	return s.srv.blockingRPC(
		&args.QueryOptions,
		&reply.QueryMeta,
		state.GetQueryWatch("NodeSessions"),
		func() error {
			index, sessions, err := state.NodeSessions(args.Node)
			if err != nil {
				return err
			}

			reply.Index, reply.Sessions = index, sessions
			if err := s.srv.filterACL(args.Token, reply); err != nil {
				return err
			}
			return nil
		})
}

// Renew is used to renew the TTL on a single session
func (s *Session) Renew(args *structs.SessionSpecificRequest,
	reply *structs.IndexedSessions) error {
	if done, err := s.srv.forward("Session.Renew", args, args, reply); done {
		return err
	}
	defer metrics.MeasureSince([]string{"consul", "session", "renew"}, time.Now())

	// Get the session, from local state.
	state := s.srv.fsm.State()
	index, session, err := state.SessionGet(args.Session)
	if err != nil {
		return err
	}

	reply.Index = index
	if session == nil {
		return nil
	}

	// Fetch the ACL token, if any, and apply the policy.
	acl, err := s.srv.resolveToken(args.Token)
	if err != nil {
		return err
	}
	if acl != nil && s.srv.config.ACLEnforceVersion8 {
		if !acl.SessionWrite(session.Node) {
			return permissionDeniedErr
		}
	}

	// Reset the session TTL timer.
	reply.Sessions = structs.Sessions{session}
	if err := s.srv.resetSessionTimer(args.Session, session); err != nil {
		s.srv.logger.Printf("[ERR] consul.session: Session renew failed: %v", err)
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package daemon

import (
	"bytes"
	"encoding/json"
	"fmt"
	"sort"
	gosync "sync"
	"time"

	"github.com/pkg/errors"

	"github.com/weaveworks/flux"
	"github.com/weaveworks/flux/cluster"
	"github.com/weaveworks/flux/git"
	"github.com/weaveworks/flux/guid"
	"github.com/weaveworks/flux/history"
	"github.com/weaveworks/flux/job"
	"github.com/weaveworks/flux/policy"
	"github.com/weaveworks/flux/registry"
	"github.com/weaveworks/flux/release"
	"github.com/weaveworks/flux/remote"
	"github.com/weaveworks/flux/update"
)

// Combine these things to form Devasta^Wan implementation of
// Platform.
type Daemon struct {
	V           string
	Cluster     cluster.Cluster
	Registry    registry.Registry
	Repo        git.Repo
	Checkout    git.Checkout
	Jobs        *job.Queue
	EventWriter history.EventWriter
	// bookkeeping
	syncSoon     chan struct{}
	initSyncSoon gosync.Once
}

// Invariant.
var _ remote.Platform = &Daemon{}

func (d *Daemon) Version() (string, error) {
	return d.V, nil
}

func (d *Daemon) Ping() error {
	return d.Cluster.Ping()
}

func (d *Daemon) Export() ([]byte, error) {
	return d.Cluster.Export()
}

func (d *Daemon) ListServices(namespace string) ([]flux.ServiceStatus, error) {
	var res []flux.ServiceStatus
	services, err := d.Cluster.AllServices(namespace)
	if err != nil {
		return nil, errors.Wrap(err, "getting services from cluster")
	}

	automatedServices, err := d.Cluster.ServicesWithPolicy(d.Checkout.ManifestDir(), policy.Automated)
	if err != nil {
		return nil, errors.Wrap(err, "checking service policies")
	}
	lockedServices, err := d.Cluster.ServicesWithPolicy(d.Checkout.ManifestDir(), policy.Locked)
	if err != nil {
		return nil, errors.Wrap(err, "checking service policies")
	}

	for _, service := range services {
		res = append(res, flux.ServiceStatus{
			ID:         service.ID,
			Containers: containers2containers(service.ContainersOrNil()),
			Status:     service.Status,
			Automated:  automatedServices.Contains(service.ID),
			Locked:     lockedServices.Contains(service.ID),
		})
	}

	return res, nil
}

// List the images available for set of services
func (d *Daemon) ListImages(spec flux.ServiceSpec) ([]flux.ImageStatus, error) {
	var services []cluster.Service
	var err error
	if spec == flux.ServiceSpecAll {
		services, err = d.Cluster.AllServices("")
	} else {
		id, err := spec.AsID()
		if err != nil {
			return nil, errors.Wrap(err, "treating service spec as ID")
		}
		services, err = d.Cluster.SomeServices([]flux.ServiceID{id})
	}

	images, err := release.CollectAvailableImages(d.Registry, services)
	if err != nil {
		return nil, errors.Wrap(err, "getting images for services")
	}

	var res []flux.ImageStatus
	for _, service := range services {
		containers := containersWithAvailable(service, images)
		res = append(res, flux.ImageStatus{
			ID:         service.ID,
			Containers: containers,
		})
	}

	return res, nil
}

type JobFunc func(working git.Checkout) error

func (d *Daemon) queueJob(do JobFunc) job.ID {
	// TODO record job as current upon Do'ing (or in the loop)
	id := job.ID(guid.New())
	d.Jobs.Enqueue(&job.Job{
		ID: id,
		// make a working clone so we don't mess with files we will be
		// reading from elsewhere
		Do: func() error {
			working, err := d.Checkout.WorkingClone()
			if err != nil {
				return err
			}
			defer working.Clean()
			return do(working)
		},
	})
	println("enqueued job " + id)
	return id
}

// Apply the desired changes to the config files
func (d *Daemon) UpdateManifests(spec update.Spec) (job.ID, error) {
	switch s := spec.Spec.(type) {
	case flux.ReleaseSpec:
		return d.queueJob(func(working git.Checkout) error {
			rc := release.NewReleaseContext(d.Cluster, d.Registry, working)
			_, err := release.Release(rc, s)
			return err
		}), nil
	case policy.Updates:
		return d.queueJob(func(working git.Checkout) error {
			started := time.Now().UTC()
			// For each update
			var serviceIDs []flux.ServiceID
			for serviceID, update := range s {
				serviceIDs = append(serviceIDs, serviceID)
				// find the service manifest
				err := d.Cluster.UpdateManifest(working.ManifestDir(), string(serviceID), func(def []byte) ([]byte, error) {
					return d.Cluster.UpdatePolicies(def, update)
				})
				if err != nil {
					return err
				}
			}

			noteBytes, err := json.Marshal(s)
			if err != nil {
				return err
			}
			if err := working.CommitAndPush(policyCommitMessage(s, started), string(noteBytes)); err != nil {
				return err
			}

			revision, err := working.HeadRevision()
			if err != nil {
				return err
			}
			return d.LogEvent(history.Event{
				ServiceIDs: serviceIDs,
				Type:       history.EventCommit,
				StartedAt:  started,
				EndedAt:    started,
				LogLevel:   history.LogLevelInfo,
				Metadata: history.CommitEventMetadata{
					Revision: revision,
					Spec:     spec,
				},
			})
		}), nil
	default:
		var id job.ID
		return id, fmt.Errorf(`unknown update type "%s"`, spec.Type)
	}
}

// Tell the daemon to synchronise the cluster with the manifests in
// the git repo. This has an error return value because upstream there
// may be comms difficulties or other sources of problems; here, we
// always succeed because it's just bookkeeping.
func (d *Daemon) SyncNotify() error {
	d.askForSync()
	return nil
}

// Ask the daemon how far it's got applying things; in particular, is it
// past the supplied release? Return the list of commits between where
// we have applied and the ref given, inclusive. E.g., if you send HEAD,
// you'll get all the commits yet to be applied. If you send a hash
// and it's applied _past_ it, you'll get an empty list.
func (d *Daemon) SyncStatus(commitRef string) ([]string, error) {
	if err := d.Checkout.Pull(); err != nil {
		return nil, errors.Wrap(err, "updating repo for status")
	}
	rc := release.NewReleaseContext(d.Cluster, d.Registry, d.Checkout)
	return rc.ListRevisions(commitRef)
}

// Non-remote.Platform methods

// `logEvent` expects the result of applying updates, and records an event in
// the history about the release taking place. It returns the origin error if
// that was non-nil, otherwise the result of the attempted logging.
func (d *Daemon) logRelease(executeErr error, release flux.Release) error {
	errorMessage := ""
	logLevel := history.LogLevelInfo
	if executeErr != nil {
		errorMessage = executeErr.Error()
		logLevel = history.LogLevelError
	}

	var serviceIDs []flux.ServiceID
	for _, id := range release.Result.ServiceIDs() {
		serviceIDs = append(serviceIDs, flux.ServiceID(id))
	}

	err := d.LogEvent(history.Event{
		ServiceIDs: serviceIDs,
		Type:       history.EventRelease,
		StartedAt:  release.StartedAt,
		EndedAt:    release.EndedAt,
		LogLevel:   logLevel,
		Metadata: history.ReleaseEventMetadata{
			Release: release,
			Error:   errorMessage,
		},
	})
	if err != nil {
		if executeErr == nil {
			return errors.Wrap(err, "logging event")
		}
	}
	return executeErr
}

func (d *Daemon) LogEvent(ev history.Event) error {
	return d.EventWriter.LogEvent(ev)
}

// vvv helpers vvv

func containers2containers(cs []cluster.Container) []flux.Container {
	res := make([]flux.Container, len(cs))
	for i, c := range cs {
		id, _ := flux.ParseImageID(c.Image)
		res[i] = flux.Container{
			Name: c.Name,
			Current: flux.ImageDescription{
				ID: id,
			},
		}
	}
	return res
}

func containersWithAvailable(service cluster.Service, images release.ImageMap) (res []flux.Container) {
	for _, c := range service.ContainersOrNil() {
		id, _ := flux.ParseImageID(c.Image)
		repo := id.Repository()
		available := images[repo]
		res = append(res, flux.Container{
			Name: c.Name,
			Current: flux.ImageDescription{
				ID: id,
			},
			Available: available,
		})
	}
	return res
}

// policyEvents builds a map of events (by type), for all the events in this set of
// updates. There will be one event per type, containing all service ids
// affected by that event. e.g. all automated services will share an event.
func policyEvents(us policy.Updates, now time.Time) map[string]history.Event {
	eventsByType := map[string]history.Event{}
	for serviceID, update := range us {
		for _, eventType := range policyEventTypes(update) {
			e, ok := eventsByType[eventType]
			if !ok {
				e = history.Event{
					ServiceIDs: []flux.ServiceID{},
					Type:       eventType,
					StartedAt:  now,
					EndedAt:    now,
					LogLevel:   history.LogLevelInfo,
				}
			}
			e.ServiceIDs = append(e.ServiceIDs, serviceID)
			eventsByType[eventType] = e
		}
	}
	return eventsByType
}

func policyCommitMessage(us policy.Updates, now time.Time) string {
	events := policyEvents(us, now)
	commitMsg := &bytes.Buffer{}
	prefix := ""
	if len(events) > 1 {
		fmt.Fprintf(commitMsg, "Updated service policies:\n\n")
		prefix = "- "
	}
	for _, event := range events {
		fmt.Fprintf(commitMsg, "%s%v\n", prefix, event)
	}
	return commitMsg.String()
}

// policyEventTypes is a deduped list of all event types this update contains
func policyEventTypes(u policy.Update) []string {
	types := map[string]struct{}{}
	for _, p := range u.Add {
		switch p {
		case policy.Automated:
			types[history.EventAutomate] = struct{}{}
		case policy.Locked:
			types[history.EventLock] = struct{}{}
		}
	}

	for _, p := range u.Remove {
		switch p {
		case policy.Automated:
			types[history.EventDeautomate] = struct{}{}
		case policy.Locked:
			types[history.EventUnlock] = struct{}{}
		}
	}
	var result []string
	for t := range types {
		result = append(result, t)
	}
	sort.Strings(result)
	return result
}
<commit_msg>Add daemon check if eventWriter is nil, for standalone mode<commit_after>package daemon

import (
	"bytes"
	"encoding/json"
	"fmt"
	"sort"
	gosync "sync"
	"time"

	"github.com/pkg/errors"

	"github.com/weaveworks/flux"
	"github.com/weaveworks/flux/cluster"
	"github.com/weaveworks/flux/git"
	"github.com/weaveworks/flux/guid"
	"github.com/weaveworks/flux/history"
	"github.com/weaveworks/flux/job"
	"github.com/weaveworks/flux/policy"
	"github.com/weaveworks/flux/registry"
	"github.com/weaveworks/flux/release"
	"github.com/weaveworks/flux/remote"
	"github.com/weaveworks/flux/update"
)

// Combine these things to form Devasta^Wan implementation of
// Platform.
type Daemon struct {
	V           string
	Cluster     cluster.Cluster
	Registry    registry.Registry
	Repo        git.Repo
	Checkout    git.Checkout
	Jobs        *job.Queue
	EventWriter history.EventWriter
	// bookkeeping
	syncSoon     chan struct{}
	initSyncSoon gosync.Once
}

// Invariant.
var _ remote.Platform = &Daemon{}

func (d *Daemon) Version() (string, error) {
	return d.V, nil
}

func (d *Daemon) Ping() error {
	return d.Cluster.Ping()
}

func (d *Daemon) Export() ([]byte, error) {
	return d.Cluster.Export()
}

func (d *Daemon) ListServices(namespace string) ([]flux.ServiceStatus, error) {
	var res []flux.ServiceStatus
	services, err := d.Cluster.AllServices(namespace)
	if err != nil {
		return nil, errors.Wrap(err, "getting services from cluster")
	}

	automatedServices, err := d.Cluster.ServicesWithPolicy(d.Checkout.ManifestDir(), policy.Automated)
	if err != nil {
		return nil, errors.Wrap(err, "checking service policies")
	}
	lockedServices, err := d.Cluster.ServicesWithPolicy(d.Checkout.ManifestDir(), policy.Locked)
	if err != nil {
		return nil, errors.Wrap(err, "checking service policies")
	}

	for _, service := range services {
		res = append(res, flux.ServiceStatus{
			ID:         service.ID,
			Containers: containers2containers(service.ContainersOrNil()),
			Status:     service.Status,
			Automated:  automatedServices.Contains(service.ID),
			Locked:     lockedServices.Contains(service.ID),
		})
	}

	return res, nil
}

// List the images available for set of services
func (d *Daemon) ListImages(spec flux.ServiceSpec) ([]flux.ImageStatus, error) {
	var services []cluster.Service
	var err error
	if spec == flux.ServiceSpecAll {
		services, err = d.Cluster.AllServices("")
	} else {
		id, err := spec.AsID()
		if err != nil {
			return nil, errors.Wrap(err, "treating service spec as ID")
		}
		services, err = d.Cluster.SomeServices([]flux.ServiceID{id})
	}

	images, err := release.CollectAvailableImages(d.Registry, services)
	if err != nil {
		return nil, errors.Wrap(err, "getting images for services")
	}

	var res []flux.ImageStatus
	for _, service := range services {
		containers := containersWithAvailable(service, images)
		res = append(res, flux.ImageStatus{
			ID:         service.ID,
			Containers: containers,
		})
	}

	return res, nil
}

type JobFunc func(working git.Checkout) error

func (d *Daemon) queueJob(do JobFunc) job.ID {
	// TODO record job as current upon Do'ing (or in the loop)
	id := job.ID(guid.New())
	d.Jobs.Enqueue(&job.Job{
		ID: id,
		// make a working clone so we don't mess with files we will be
		// reading from elsewhere
		Do: func() error {
			working, err := d.Checkout.WorkingClone()
			if err != nil {
				return err
			}
			defer working.Clean()
			return do(working)
		},
	})
	println("enqueued job " + id)
	return id
}

// Apply the desired changes to the config files
func (d *Daemon) UpdateManifests(spec update.Spec) (job.ID, error) {
	switch s := spec.Spec.(type) {
	case flux.ReleaseSpec:
		return d.queueJob(func(working git.Checkout) error {
			rc := release.NewReleaseContext(d.Cluster, d.Registry, working)
			_, err := release.Release(rc, s)
			return err
		}), nil
	case policy.Updates:
		return d.queueJob(func(working git.Checkout) error {
			started := time.Now().UTC()
			// For each update
			var serviceIDs []flux.ServiceID
			for serviceID, update := range s {
				serviceIDs = append(serviceIDs, serviceID)
				// find the service manifest
				err := d.Cluster.UpdateManifest(working.ManifestDir(), string(serviceID), func(def []byte) ([]byte, error) {
					return d.Cluster.UpdatePolicies(def, update)
				})
				if err != nil {
					return err
				}
			}

			noteBytes, err := json.Marshal(s)
			if err != nil {
				return err
			}
			if err := working.CommitAndPush(policyCommitMessage(s, started), string(noteBytes)); err != nil {
				return err
			}

			revision, err := working.HeadRevision()
			if err != nil {
				return err
			}
			return d.LogEvent(history.Event{
				ServiceIDs: serviceIDs,
				Type:       history.EventCommit,
				StartedAt:  started,
				EndedAt:    started,
				LogLevel:   history.LogLevelInfo,
				Metadata: history.CommitEventMetadata{
					Revision: revision,
					Spec:     spec,
				},
			})
		}), nil
	default:
		var id job.ID
		return id, fmt.Errorf(`unknown update type "%s"`, spec.Type)
	}
}

// Tell the daemon to synchronise the cluster with the manifests in
// the git repo. This has an error return value because upstream there
// may be comms difficulties or other sources of problems; here, we
// always succeed because it's just bookkeeping.
func (d *Daemon) SyncNotify() error {
	d.askForSync()
	return nil
}

// Ask the daemon how far it's got applying things; in particular, is it
// past the supplied release? Return the list of commits between where
// we have applied and the ref given, inclusive. E.g., if you send HEAD,
// you'll get all the commits yet to be applied. If you send a hash
// and it's applied _past_ it, you'll get an empty list.
func (d *Daemon) SyncStatus(commitRef string) ([]string, error) {
	if err := d.Checkout.Pull(); err != nil {
		return nil, errors.Wrap(err, "updating repo for status")
	}
	rc := release.NewReleaseContext(d.Cluster, d.Registry, d.Checkout)
	return rc.ListRevisions(commitRef)
}

// Non-remote.Platform methods

// `logEvent` expects the result of applying updates, and records an event in
// the history about the release taking place. It returns the origin error if
// that was non-nil, otherwise the result of the attempted logging.
func (d *Daemon) logRelease(executeErr error, release flux.Release) error {
	errorMessage := ""
	logLevel := history.LogLevelInfo
	if executeErr != nil {
		errorMessage = executeErr.Error()
		logLevel = history.LogLevelError
	}

	var serviceIDs []flux.ServiceID
	for _, id := range release.Result.ServiceIDs() {
		serviceIDs = append(serviceIDs, flux.ServiceID(id))
	}

	err := d.LogEvent(history.Event{
		ServiceIDs: serviceIDs,
		Type:       history.EventRelease,
		StartedAt:  release.StartedAt,
		EndedAt:    release.EndedAt,
		LogLevel:   logLevel,
		Metadata: history.ReleaseEventMetadata{
			Release: release,
			Error:   errorMessage,
		},
	})
	if err != nil {
		if executeErr == nil {
			return errors.Wrap(err, "logging event")
		}
	}
	return executeErr
}

func (d *Daemon) LogEvent(ev history.Event) error {
	if d.EventWriter == nil {
		return nil
	}
	return d.EventWriter.LogEvent(ev)
}

// vvv helpers vvv

func containers2containers(cs []cluster.Container) []flux.Container {
	res := make([]flux.Container, len(cs))
	for i, c := range cs {
		id, _ := flux.ParseImageID(c.Image)
		res[i] = flux.Container{
			Name: c.Name,
			Current: flux.ImageDescription{
				ID: id,
			},
		}
	}
	return res
}

func containersWithAvailable(service cluster.Service, images release.ImageMap) (res []flux.Container) {
	for _, c := range service.ContainersOrNil() {
		id, _ := flux.ParseImageID(c.Image)
		repo := id.Repository()
		available := images[repo]
		res = append(res, flux.Container{
			Name: c.Name,
			Current: flux.ImageDescription{
				ID: id,
			},
			Available: available,
		})
	}
	return res
}

// policyEvents builds a map of events (by type), for all the events in this set of
// updates. There will be one event per type, containing all service ids
// affected by that event. e.g. all automated services will share an event.
func policyEvents(us policy.Updates, now time.Time) map[string]history.Event {
	eventsByType := map[string]history.Event{}
	for serviceID, update := range us {
		for _, eventType := range policyEventTypes(update) {
			e, ok := eventsByType[eventType]
			if !ok {
				e = history.Event{
					ServiceIDs: []flux.ServiceID{},
					Type:       eventType,
					StartedAt:  now,
					EndedAt:    now,
					LogLevel:   history.LogLevelInfo,
				}
			}
			e.ServiceIDs = append(e.ServiceIDs, serviceID)
			eventsByType[eventType] = e
		}
	}
	return eventsByType
}

func policyCommitMessage(us policy.Updates, now time.Time) string {
	events := policyEvents(us, now)
	commitMsg := &bytes.Buffer{}
	prefix := ""
	if len(events) > 1 {
		fmt.Fprintf(commitMsg, "Updated service policies:\n\n")
		prefix = "- "
	}
	for _, event := range events {
		fmt.Fprintf(commitMsg, "%s%v\n", prefix, event)
	}
	return commitMsg.String()
}

// policyEventTypes is a deduped list of all event types this update contains
func policyEventTypes(u policy.Update) []string {
	types := map[string]struct{}{}
	for _, p := range u.Add {
		switch p {
		case policy.Automated:
			types[history.EventAutomate] = struct{}{}
		case policy.Locked:
			types[history.EventLock] = struct{}{}
		}
	}

	for _, p := range u.Remove {
		switch p {
		case policy.Automated:
			types[history.EventDeautomate] = struct{}{}
		case policy.Locked:
			types[history.EventUnlock] = struct{}{}
		}
	}
	var result []string
	for t := range types {
		result = append(result, t)
	}
	sort.Strings(result)
	return result
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"

	"github.com/gorilla/mux"
)

func main() {
	r := mux.NewRouter()

	files := r.Path("/files/{id}").Subrouter()
	files.Methods("POST").HandlerFunc(FileCreateHandle)

	http.ListenAndServe(":8000", r)
}

func FileCreateHandle(rw http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	path := "/Users/sebastian/" + id
	body, _ := ioutil.ReadAll(r.Body)

	f, _ := os.Create(path)
	defer f.Close()

	f.Write(body)
	f.Sync()

	fmt.Fprintf(rw, "Created file with id: %s", id)
}
<commit_msg>WIP: Get implementation<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"

	"github.com/gorilla/mux"
)

func main() {
	r := mux.NewRouter()

	file := r.Path("/files/{id}").Subrouter()
	file.Methods("GET").HandlerFunc(FileGetHandler)
	file.Methods("POST").HandlerFunc(FileCreateHandler)

	http.ListenAndServe(":8000", r)
}

func FileCreateHandler(rw http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	path := "/Users/sebastian/" + id
	body, _ := ioutil.ReadAll(r.Body)

	f, _ := os.Create(path)
	defer f.Close()

	f.Write(body)
	f.Sync()

	fmt.Fprintf(rw, "Created file with id: %s", id)
}

func FileGetHandler(rw http.ResponseWriter, r *http.Request) {
	id := mux.Vars(r)["id"]
	path := "/Users/sebastian/" + id

	data, _ := ioutil.ReadFile(path)

	fmt.Fprint(rw, string(data))
}
<|endoftext|>


<commit_before>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package state_test

import (
	stdtesting "testing"

	"github.com/juju/names"
	gc "gopkg.in/check.v1"
	"gopkg.in/mgo.v2"

	"github.com/juju/juju/state"
	statetesting "github.com/juju/juju/state/testing"
	"github.com/juju/juju/testing"
)

// TestPackage integrates the tests into gotest.
func TestPackage(t *stdtesting.T) {
	testing.MgoTestPackage(t)
}

// ConnSuite provides the infrastructure for all other
// test suites (StateSuite, CharmSuite, MachineSuite, etc).
type ConnSuite struct {
	statetesting.StateSuite
	annotations  *mgo.Collection
	charms       *mgo.Collection
	machines     *mgo.Collection
	instanceData *mgo.Collection
	relations    *mgo.Collection
	services     *mgo.Collection
	units        *mgo.Collection
	stateServers *mgo.Collection
	policy       statetesting.MockPolicy
	envTag       names.EnvironTag
}

func (cs *ConnSuite) SetUpTest(c *gc.C) {
	c.Log("SetUpTest")

	cs.policy = statetesting.MockPolicy{}
	cs.StateSuite.Policy = &cs.policy

	cs.StateSuite.SetUpTest(c)

	cs.envTag = cs.State.EnvironTag()

	jujuDB := cs.MgoSuite.Session.DB("juju")
	cs.annotations = jujuDB.C("annotations")
	cs.charms = jujuDB.C("charms")
	cs.machines = jujuDB.C("machines")
	cs.instanceData = jujuDB.C("instanceData")
	cs.relations = jujuDB.C("relations")
	cs.services = jujuDB.C("services")
	cs.units = jujuDB.C("units")
	cs.stateServers = jujuDB.C("stateServers")

	c.Log("SetUpTest done")
}

func (s *ConnSuite) AddTestingCharm(c *gc.C, name string) *state.Charm {
	return state.AddTestingCharm(c, s.State, name)
}

func (s *ConnSuite) AddTestingService(c *gc.C, name string, ch *state.Charm) *state.Service {
	return state.AddTestingService(c, s.State, name, ch, s.Owner)
}

func (s *ConnSuite) AddTestingServiceWithNetworks(c *gc.C, name string, ch *state.Charm, networks []string) *state.Service {
	return state.AddTestingServiceWithNetworks(c, s.State, name, ch, s.Owner, networks)
}

func (s *ConnSuite) AddTestingServiceWithStorage(c *gc.C, name string, ch *state.Charm, storage map[string]state.StorageConstraints) *state.Service {
	return state.AddTestingServiceWithStorage(c, s.State, name, ch, s.Owner, storage)
}

func (s *ConnSuite) AddSeriesCharm(c *gc.C, name, series string) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "", "", series, -1)
}

// AddConfigCharm clones a testing charm, replaces its config with
// the given YAML string and adds it to the state, using the given
// revision.
func (s *ConnSuite) AddConfigCharm(c *gc.C, name, configYaml string, revision int) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "config.yaml", configYaml, "quantal", revision)
}

// AddActionsCharm clones a testing charm, replaces its actions schema with
// the given YAML, and adds it to the state, using the given revision.
func (s *ConnSuite) AddActionsCharm(c *gc.C, name, actionsYaml string, revision int) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "actions.yaml", actionsYaml, "quantal", revision)
}

// AddMetaCharm clones a testing charm, replaces its metadata with the
// given YAML string and adds it to the state, using the given revision.
func (s *ConnSuite) AddMetaCharm(c *gc.C, name, metaYaml string, revsion int) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "metadata.yaml", metaYaml, "quantal", revsion)
}

// AddMetricsCharm clones a testing charm, replaces its metrics declaration with the
// given YAML string and adds it to the state, using the given revision.
func (s *ConnSuite) AddMetricsCharm(c *gc.C, name, metricsYaml string, revsion int) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "metrics.yaml", metricsYaml, "quantal", revsion)
}
<commit_msg>state: disable the package tests in -race mode<commit_after>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package state_test

import (
	"github.com/juju/names"
	gc "gopkg.in/check.v1"
	"gopkg.in/mgo.v2"

	"github.com/juju/juju/state"
	statetesting "github.com/juju/juju/state/testing"
)

// ConnSuite provides the infrastructure for all other
// test suites (StateSuite, CharmSuite, MachineSuite, etc).
type ConnSuite struct {
	statetesting.StateSuite
	annotations  *mgo.Collection
	charms       *mgo.Collection
	machines     *mgo.Collection
	instanceData *mgo.Collection
	relations    *mgo.Collection
	services     *mgo.Collection
	units        *mgo.Collection
	stateServers *mgo.Collection
	policy       statetesting.MockPolicy
	envTag       names.EnvironTag
}

func (cs *ConnSuite) SetUpTest(c *gc.C) {
	c.Log("SetUpTest")

	cs.policy = statetesting.MockPolicy{}
	cs.StateSuite.Policy = &cs.policy

	cs.StateSuite.SetUpTest(c)

	cs.envTag = cs.State.EnvironTag()

	jujuDB := cs.MgoSuite.Session.DB("juju")
	cs.annotations = jujuDB.C("annotations")
	cs.charms = jujuDB.C("charms")
	cs.machines = jujuDB.C("machines")
	cs.instanceData = jujuDB.C("instanceData")
	cs.relations = jujuDB.C("relations")
	cs.services = jujuDB.C("services")
	cs.units = jujuDB.C("units")
	cs.stateServers = jujuDB.C("stateServers")

	c.Log("SetUpTest done")
}

func (s *ConnSuite) AddTestingCharm(c *gc.C, name string) *state.Charm {
	return state.AddTestingCharm(c, s.State, name)
}

func (s *ConnSuite) AddTestingService(c *gc.C, name string, ch *state.Charm) *state.Service {
	return state.AddTestingService(c, s.State, name, ch, s.Owner)
}

func (s *ConnSuite) AddTestingServiceWithNetworks(c *gc.C, name string, ch *state.Charm, networks []string) *state.Service {
	return state.AddTestingServiceWithNetworks(c, s.State, name, ch, s.Owner, networks)
}

func (s *ConnSuite) AddTestingServiceWithStorage(c *gc.C, name string, ch *state.Charm, storage map[string]state.StorageConstraints) *state.Service {
	return state.AddTestingServiceWithStorage(c, s.State, name, ch, s.Owner, storage)
}

func (s *ConnSuite) AddSeriesCharm(c *gc.C, name, series string) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "", "", series, -1)
}

// AddConfigCharm clones a testing charm, replaces its config with
// the given YAML string and adds it to the state, using the given
// revision.
func (s *ConnSuite) AddConfigCharm(c *gc.C, name, configYaml string, revision int) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "config.yaml", configYaml, "quantal", revision)
}

// AddActionsCharm clones a testing charm, replaces its actions schema with
// the given YAML, and adds it to the state, using the given revision.
func (s *ConnSuite) AddActionsCharm(c *gc.C, name, actionsYaml string, revision int) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "actions.yaml", actionsYaml, "quantal", revision)
}

// AddMetaCharm clones a testing charm, replaces its metadata with the
// given YAML string and adds it to the state, using the given revision.
func (s *ConnSuite) AddMetaCharm(c *gc.C, name, metaYaml string, revsion int) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "metadata.yaml", metaYaml, "quantal", revsion)
}

// AddMetricsCharm clones a testing charm, replaces its metrics declaration with the
// given YAML string and adds it to the state, using the given revision.
func (s *ConnSuite) AddMetricsCharm(c *gc.C, name, metricsYaml string, revsion int) *state.Charm {
	return state.AddCustomCharm(c, s.State, name, "metrics.yaml", metricsYaml, "quantal", revsion)
}
<|endoftext|>


<commit_before>package tools

import (
	"crypto/rand"
	"math"
	"math/big"
)

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const (
	letterIdxBits = 6                    // 6 bits to represent a letter index
	letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
	letterIdxMax  = 63 / letterIdxBits   // # of letter indices fitting in 63 bits
)

var maxInt = big.NewInt(math.MaxInt64)

func RandomString(n int) string {
	b := make([]byte, n)
	// A randsrc.Int63() generates 63 random bits, enough for
	// letterIdxMax characters!
	cache, _ := rand.Int(rand.Reader, maxInt)
	for i, remain := n-1, letterIdxMax; i >= 0; {
		if remain == 0 {
			cache, _ = rand.Int(rand.Reader, maxInt)
			remain = letterIdxMax
		}
		if idx := int(cache.Int64() & letterIdxMask); idx < len(letterBytes) {
			b[i] = letterBytes[idx]
			i--
		}
		cache.SetInt64(cache.Int64() >> letterIdxBits)
		remain--
	}

	return string(b)
}
<commit_msg>Create a RandFloat64() using crypto/rand<commit_after>package tools

import (
	"crypto/rand"
	"math"
	"math/big"
)

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const (
	letterIdxBits = 6                    // 6 bits to represent a letter index
	letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
	letterIdxMax  = 63 / letterIdxBits   // # of letter indices fitting in 63 bits
)

var maxInt = big.NewInt(math.MaxInt64)

func RandomString(n int) string {
	b := make([]byte, n)
	// A randsrc.Int63() generates 63 random bits, enough for
	// letterIdxMax characters!
	cache, _ := rand.Int(rand.Reader, maxInt)
	for i, remain := n-1, letterIdxMax; i >= 0; {
		if remain == 0 {
			cache, _ = rand.Int(rand.Reader, maxInt)
			remain = letterIdxMax
		}
		if idx := int(cache.Int64() & letterIdxMask); idx < len(letterBytes) {
			b[i] = letterBytes[idx]
			i--
		}
		cache.SetInt64(cache.Int64() >> letterIdxBits)
		remain--
	}

	return string(b)
}

func RandFloat64() float64 {
again:
	fbig, _ := rand.Int(rand.Reader, maxInt)
	f := float64(fbig.Int64()) / (1 << 63)
	if f == 1 {
		goto again
	}
	return f
}
<|endoftext|>


<commit_before>// Copyright 2011, Bryan Matsuo. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

/*
 *  Filename:    template.go
 *  Package:     main
 *  Author:      Bryan Matsuo <bmatsuo@soe.ucsc.edu>
 *  Created:     Sun Jul  3 17:55:40 PDT 2011
 *  Description:
 */
import (
	"errors"
	"fmt"
	"io"
	"os"
	//"log"
	"bytes"
	//"strings"
	//"io/ioutil"
	"path/filepath"
	//"runtime"
	"text/template"
	//"github.com/hoisie/mustache.go"
)

const (
	TemplateFileExt = ".t"
)

// Template errors
var (
	ErrNoTemplates = errors.New("No valid templates found")
	ErrNoExist     = errors.New("Requested template does not exist")
	ErrParse       = errors.New("Couldn't parse template")
)

type Executor interface {
	Execute(io.Writer, interface{}) error
}

type ExecutorSet interface {
	Execute(io.Writer, string, interface{}) error
}

func collectBytes(f func(w io.Writer) error) (p []byte, err error) {
	b := new(bytes.Buffer)
	err = f(b)
	p = b.Bytes()
	return
}

//  Call t.Execute with the given data, writing to a []byte buffer.
func Executed(t Executor, data interface{}) ([]byte, error) {
	return collectBytes(func(w io.Writer) error { return t.Execute(w, data) })
}

//  Call s.Execute with the given name data, writing to a []byte buffer.
func ExecutedSet(s ExecutorSet, name string, data interface{}) ([]byte, error) {
	return collectBytes(func(w io.Writer) error { return s.Execute(w, name, data) })
}

//  Returns an os-specific pattern <root>/"*"/*<TemplateFileExt>
func TemplateGlobPattern(root string) string {
	return filepath.Join(root, "*", fmt.Sprintf("*%s", TemplateFileExt))
}

type TemplateMultiSet []*template.Template

//  Call function CollectTemplates on each given root and create a TemplateMultiSet.
func MakeTemplateMultiSet(f template.FuncMap, roots ...string) (ms TemplateMultiSet, err error) {
	var s *template.Template
	ms = make(TemplateMultiSet, 0, len(roots))
	for i := range roots {
		if s, err = CollectTemplates(roots[i], f); err != nil {
			fmt.Fprintln(os.Stderr, err)
		} else {
			ms = append(ms, s)
		}
	}
	if len(ms) == 0 {
		err = ErrNoTemplates
	}
	return
}

func FindTemplates() (TemplateMultiSet, error) {
	troots := make([]string, 0, 2)
	if alt := AppConfig.AltRoot; alt != "" {
		troots = append(troots, alt)
	}
	troots = append(troots, filepath.Join(GetTemplateRoot()...))
	return MakeTemplateMultiSet(DefaultFuncMap(), troots...)
}

//  Execute a template in first s in ms for which s.Template(name) is non-nil.
func (ms TemplateMultiSet) Execute(wr io.Writer, name string, data interface{}) error {
	for _, s := range ms {
		if t := s.Lookup(name); t != nil {
			return t.Execute(wr, data)
		}
	}
	return ErrNoTemplates
}

func emptyTemplate(name string) (*template.Template, error) { return template.New(name).Parse("") }

//  Parse templates <root>/*/*.t, allowing them a given function map.
func CollectTemplates(root string, f template.FuncMap) (s *template.Template, err error) {
	switch s, err = emptyTemplate(root); {
	case err != nil:
		return
	case f != nil:
		s.Funcs(f)
	}
	return s.ParseGlob(TemplateGlobPattern(root))
}

//  The template directory of the goinstall'ed gonew package.
func GetTemplateRoot() []string { return []string{GonewRoot, "templates"} }
<commit_msg>Remove messy unused imports and gofmt.<commit_after>// Copyright 2011, Bryan Matsuo. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

/*
 *  Filename:    template.go
 *  Package:     main
 *  Author:      Bryan Matsuo <bmatsuo@soe.ucsc.edu>
 *  Created:     Sun Jul  3 17:55:40 PDT 2011
 *  Description:
 */
import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"text/template"
)

// The file extension used by Gonew template files. Custom templates must all
// use this extension.
const (
	TemplateFileExt = ".t"
)

// Template errors
var (
	ErrNoTemplates = errors.New("No valid templates found")
	ErrNoExist     = errors.New("Requested template does not exist")
	ErrParse       = errors.New("Couldn't parse template")
)

type Executor interface {
	Execute(io.Writer, interface{}) error
}

type ExecutorSet interface {
	Execute(io.Writer, string, interface{}) error
}

func collectBytes(f func(w io.Writer) error) (p []byte, err error) {
	b := new(bytes.Buffer)
	err = f(b)
	p = b.Bytes()
	return
}

//  Call t.Execute with the given data, writing to a []byte buffer.
func Executed(t Executor, data interface{}) ([]byte, error) {
	return collectBytes(func(w io.Writer) error { return t.Execute(w, data) })
}

//  Call s.Execute with the given name data, writing to a []byte buffer.
func ExecutedSet(s ExecutorSet, name string, data interface{}) ([]byte, error) {
	return collectBytes(func(w io.Writer) error { return s.Execute(w, name, data) })
}

//  Returns an os-specific pattern <root>/"*"/*<TemplateFileExt>
func TemplateGlobPattern(root string) string {
	return filepath.Join(root, "*", fmt.Sprintf("*%s", TemplateFileExt))
}

type TemplateMultiSet []*template.Template

//  Call function CollectTemplates on each given root and create a TemplateMultiSet.
func MakeTemplateMultiSet(f template.FuncMap, roots ...string) (ms TemplateMultiSet, err error) {
	var s *template.Template
	ms = make(TemplateMultiSet, 0, len(roots))
	for i := range roots {
		if s, err = CollectTemplates(roots[i], f); err != nil {
			fmt.Fprintln(os.Stderr, err)
		} else {
			ms = append(ms, s)
		}
	}
	if len(ms) == 0 {
		err = ErrNoTemplates
	}
	return
}

func FindTemplates() (TemplateMultiSet, error) {
	troots := make([]string, 0, 2)
	if alt := AppConfig.AltRoot; alt != "" {
		troots = append(troots, alt)
	}
	troots = append(troots, filepath.Join(GetTemplateRoot()...))
	return MakeTemplateMultiSet(DefaultFuncMap(), troots...)
}

//  Execute a template in first s in ms for which s.Template(name) is non-nil.
func (ms TemplateMultiSet) Execute(wr io.Writer, name string, data interface{}) error {
	for _, s := range ms {
		if t := s.Lookup(name); t != nil {
			return t.Execute(wr, data)
		}
	}
	return ErrNoTemplates
}

func emptyTemplate(name string) (*template.Template, error) { return template.New(name).Parse("") }

//  Parse templates <root>/*/*.t, allowing them a given function map.
func CollectTemplates(root string, f template.FuncMap) (s *template.Template, err error) {
	switch s, err = emptyTemplate(root); {
	case err != nil:
		return
	case f != nil:
		s.Funcs(f)
	}
	return s.ParseGlob(TemplateGlobPattern(root))
}

//  The template directory of the goinstall'ed gonew package.
func GetTemplateRoot() []string { return []string{GonewRoot, "templates"} }
<|endoftext|>


<commit_before>package kocha

import (
	"bytes"
	"fmt"
	"html/template"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"

	"github.com/naoina/kocha/util"
)

const (
	LayoutDir        = "layout"
	ErrorTemplateDir = "error"
)

// TemplatePathInfo represents an information of template paths.
type TemplatePathInfo struct {
	Name  string   // name of the application.
	Paths []string // directory paths of the template files.
}

// Template represents the templates information.
type Template struct {
	PathInfo   TemplatePathInfo // information of location of template paths.
	FuncMap    TemplateFuncMap  // same as template.FuncMap.
	LeftDelim  string           // left action delimiter.
	RightDelim string           // right action delimiter.

	m   templateMap
	app *Application
}

// Get gets a parsed template.
func (t *Template) Get(layout, name, format string) (*template.Template, error) {
	var r *template.Template
	tmpl := t.m[t.app.Config.AppName][format]
	if tmpl == nil {
		goto ErrNotFound
	}
	if layout != "" {
		r = tmpl.Lookup(filepath.Join(LayoutDir, layout) + "." + format)
	} else {
		r = tmpl.Lookup(name + "." + format)
	}
	if r == nil {
		goto ErrNotFound
	}
	return r, nil
ErrNotFound:
	return nil, fmt.Errorf("kocha: template not found: %s:%s/%s.%s", t.app.Config.AppName, layout, name, format)
}

func (t *Template) build(app *Application) (*Template, error) {
	t.app = app
	if t.LeftDelim == "" {
		t.LeftDelim = "{{"
	}
	if t.RightDelim == "" {
		t.RightDelim = "}}"
	}
	t, err := t.buildFuncMap()
	if err != nil {
		return nil, err
	}
	t, err = t.buildTemplateMap()
	if err != nil {
		return nil, err
	}
	return t, nil
}

func (t *Template) buildFuncMap() (*Template, error) {
	m := TemplateFuncMap{
		"yield":           t.yield,
		"in":              t.in,
		"url":             t.url,
		"nl2br":           t.nl2br,
		"raw":             t.raw,
		"invoke_template": t.invokeTemplate,
		"flash":           t.flash,
		"join":            t.join,
	}
	for name, fn := range t.FuncMap {
		m[name] = fn
	}
	t.FuncMap = m
	return t, nil
}

// buildTemplateMap returns templateMap constructed from templateSet.
func (t *Template) buildTemplateMap() (*Template, error) {
	info := t.PathInfo
	var templatePaths map[string]map[string]map[string]string
	if data := t.app.ResourceSet.Get("_kocha_template_paths"); data != nil {
		if paths, ok := data.(map[string]map[string]map[string]string); ok {
			templatePaths = paths
		}
	}
	if templatePaths == nil {
		templatePaths = map[string]map[string]map[string]string{
			info.Name: make(map[string]map[string]string),
		}
		for _, rootPath := range info.Paths {
			if err := t.collectTemplatePaths(templatePaths[info.Name], rootPath); err != nil {
				return nil, err
			}
		}
		t.app.ResourceSet.Add("_kocha_template_paths", templatePaths)
	}
	templateSet := templateMap{
		info.Name: make(map[string]*template.Template),
	}
	for appName, templates := range templatePaths {
		if err := t.buildAppTemplateSet(templateSet[appName], templates); err != nil {
			return nil, err
		}
	}
	t.m = templateSet
	return t, nil
}

// TemplateFuncMap is an alias of templete.FuncMap.
type TemplateFuncMap template.FuncMap

type templateMap map[string]map[string]*template.Template

func (t *Template) collectTemplatePaths(templatePaths map[string]map[string]string, templateDir string) error {
	return filepath.Walk(templateDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		baseName, err := filepath.Rel(templateDir, path)
		if err != nil {
			return err
		}
		name, ext := util.SplitExt(strings.TrimSuffix(baseName, util.TemplateSuffix))
		if _, exists := templatePaths[ext]; !exists {
			templatePaths[ext] = make(map[string]string)
		}
		templatePaths[ext][name] = path
		return nil
	})
}

func (t *Template) buildAppTemplateSet(appTemplateSet map[string]*template.Template, templates map[string]map[string]string) error {
	for ext, templateInfos := range templates {
		tmpl := template.New("")
		for _, path := range templateInfos {
			var templateBytes []byte
			if data := t.app.ResourceSet.Get(fmt.Sprintf("_kocha_%s.%s", path, ext)); data != nil {
				if b, ok := data.([]byte); ok {
					templateBytes = b
				}
			}
			if templateBytes == nil {
				b, err := ioutil.ReadFile(path)
				if err != nil {
					return err
				}
				templateBytes = b
				t.app.ResourceSet.Add(fmt.Sprintf("_kocha_%s.%s", path, ext), b)
			}
			name := strings.TrimSuffix(t.relativePath(path), util.TemplateSuffix)
			content := fmt.Sprint(
				t.LeftDelim, "$ := .Data", t.RightDelim,
				string(templateBytes),
			)
			if _, err := tmpl.New(name).Delims(t.LeftDelim, t.RightDelim).Funcs(template.FuncMap(t.FuncMap)).Parse(content); err != nil {
				return err
			}
		}
		appTemplateSet[ext] = tmpl
	}
	return nil
}

func (t *Template) relativePath(targpath string) string {
	for _, basepath := range t.PathInfo.Paths {
		if p, err := filepath.Rel(basepath, targpath); err == nil {
			return p
		}
	}
	return targpath
}

func (t *Template) yield(c *Context) (template.HTML, error) {
	tmpl, err := t.Get("", c.Name, c.Format)
	if err != nil {
		return "", err
	}
	buf := bufPool.Get().(*bytes.Buffer)
	defer func() {
		buf.Reset()
		bufPool.Put(buf)
	}()
	if err := tmpl.Execute(buf, c); err != nil {
		return "", err
	}
	return template.HTML(buf.String()), nil
}

// in is for "in" template function.
func (t *Template) in(a, b interface{}) (bool, error) {
	v := reflect.ValueOf(a)
	switch v.Kind() {
	case reflect.Slice, reflect.Array, reflect.String:
		if v.IsNil() {
			return false, nil
		}
		for i := 0; i < v.Len(); i++ {
			if v.Index(i).Interface() == b {
				return true, nil
			}
		}
	default:
		return false, fmt.Errorf("valid types are slice, array and string, got `%s'", v.Kind())
	}
	return false, nil
}

// url is for "url" template function.
func (t *Template) url(name string, v ...interface{}) (string, error) {
	return t.app.Router.Reverse(name, v...)
}

// nl2br is for "nl2br" template function.
func (t *Template) nl2br(text string) template.HTML {
	return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", "
", -1))
}

// raw is for "raw" template function.
func (t *Template) raw(text string) template.HTML {
	return template.HTML(text)
}

// invokeTemplate is for "invoke_template" template function.
func (t *Template) invokeTemplate(unit Unit, tmplName, defTmplName string, ctx ...*Context) (html template.HTML, err error) {
	var c *Context
	switch len(ctx) {
	case 0: // do nothing.
	case 1:
		c = ctx[0]
	default:
		return "", fmt.Errorf("number of context must be 0 or 1")
	}
	t.app.Invoke(unit, func() {
		if html, err = t.readPartialTemplate(tmplName, c); err != nil {
			// TODO: logging error.
			panic(ErrInvokeDefault)
		}
	}, func() {
		html, err = t.readPartialTemplate(defTmplName, c)
	})
	return html, err
}

// flash is for "flash" template function.
// This is a shorthand for {{.Flash.Get "success"}} in template.
func (t *Template) flash(c *Context, key string) string {
	return c.Flash.Get(key)
}

// join is for "join" template function.
func (t *Template) join(a interface{}, sep string) (string, error) {
	v := reflect.ValueOf(a)
	switch v.Kind() {
	case reflect.Slice, reflect.Array:
		// do nothing.
	default:
		return "", fmt.Errorf("valid types of first argument are slice or array, got `%s'", v.Kind())
	}
	if v.Len() == 0 {
		return "", nil
	}
	buf := append(make([]byte, 0, v.Len()*2-1), fmt.Sprint(v.Index(0).Interface())...)
	for i := 1; i < v.Len(); i++ {
		buf = append(append(buf, sep...), fmt.Sprint(v.Index(i).Interface())...)
	}
	return string(buf), nil
}

func (t *Template) readPartialTemplate(name string, c *Context) (template.HTML, error) {
	tmpl, err := t.Get("", name, "html")
	if err != nil {
		return "", err
	}
	buf := bufPool.Get().(*bytes.Buffer)
	defer func() {
		buf.Reset()
		bufPool.Put(buf)
	}()
	if err := tmpl.Execute(buf, c); err != nil {
		return "", err
	}
	return template.HTML(buf.String()), nil
}

func errorTemplateName(code int) string {
	return filepath.Join(ErrorTemplateDir, strconv.Itoa(code))
}
<commit_msg>template: Fix a panic occurs if Config.Template is nil<commit_after>package kocha

import (
	"bytes"
	"fmt"
	"html/template"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"

	"github.com/naoina/kocha/util"
)

const (
	LayoutDir        = "layout"
	ErrorTemplateDir = "error"
)

// TemplatePathInfo represents an information of template paths.
type TemplatePathInfo struct {
	Name  string   // name of the application.
	Paths []string // directory paths of the template files.
}

// Template represents the templates information.
type Template struct {
	PathInfo   TemplatePathInfo // information of location of template paths.
	FuncMap    TemplateFuncMap  // same as template.FuncMap.
	LeftDelim  string           // left action delimiter.
	RightDelim string           // right action delimiter.

	m   templateMap
	app *Application
}

// Get gets a parsed template.
func (t *Template) Get(layout, name, format string) (*template.Template, error) {
	var r *template.Template
	tmpl := t.m[t.app.Config.AppName][format]
	if tmpl == nil {
		goto ErrNotFound
	}
	if layout != "" {
		r = tmpl.Lookup(filepath.Join(LayoutDir, layout) + "." + format)
	} else {
		r = tmpl.Lookup(name + "." + format)
	}
	if r == nil {
		goto ErrNotFound
	}
	return r, nil
ErrNotFound:
	return nil, fmt.Errorf("kocha: template not found: %s:%s/%s.%s", t.app.Config.AppName, layout, name, format)
}

func (t *Template) build(app *Application) (*Template, error) {
	if t == nil {
		t = &Template{}
	}
	t.app = app
	if t.LeftDelim == "" {
		t.LeftDelim = "{{"
	}
	if t.RightDelim == "" {
		t.RightDelim = "}}"
	}
	t, err := t.buildFuncMap()
	if err != nil {
		return nil, err
	}
	t, err = t.buildTemplateMap()
	if err != nil {
		return nil, err
	}
	return t, nil
}

func (t *Template) buildFuncMap() (*Template, error) {
	m := TemplateFuncMap{
		"yield":           t.yield,
		"in":              t.in,
		"url":             t.url,
		"nl2br":           t.nl2br,
		"raw":             t.raw,
		"invoke_template": t.invokeTemplate,
		"flash":           t.flash,
		"join":            t.join,
	}
	for name, fn := range t.FuncMap {
		m[name] = fn
	}
	t.FuncMap = m
	return t, nil
}

// buildTemplateMap returns templateMap constructed from templateSet.
func (t *Template) buildTemplateMap() (*Template, error) {
	info := t.PathInfo
	var templatePaths map[string]map[string]map[string]string
	if data := t.app.ResourceSet.Get("_kocha_template_paths"); data != nil {
		if paths, ok := data.(map[string]map[string]map[string]string); ok {
			templatePaths = paths
		}
	}
	if templatePaths == nil {
		templatePaths = map[string]map[string]map[string]string{
			info.Name: make(map[string]map[string]string),
		}
		for _, rootPath := range info.Paths {
			if err := t.collectTemplatePaths(templatePaths[info.Name], rootPath); err != nil {
				return nil, err
			}
		}
		t.app.ResourceSet.Add("_kocha_template_paths", templatePaths)
	}
	templateSet := templateMap{
		info.Name: make(map[string]*template.Template),
	}
	for appName, templates := range templatePaths {
		if err := t.buildAppTemplateSet(templateSet[appName], templates); err != nil {
			return nil, err
		}
	}
	t.m = templateSet
	return t, nil
}

// TemplateFuncMap is an alias of templete.FuncMap.
type TemplateFuncMap template.FuncMap

type templateMap map[string]map[string]*template.Template

func (t *Template) collectTemplatePaths(templatePaths map[string]map[string]string, templateDir string) error {
	return filepath.Walk(templateDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		baseName, err := filepath.Rel(templateDir, path)
		if err != nil {
			return err
		}
		name, ext := util.SplitExt(strings.TrimSuffix(baseName, util.TemplateSuffix))
		if _, exists := templatePaths[ext]; !exists {
			templatePaths[ext] = make(map[string]string)
		}
		templatePaths[ext][name] = path
		return nil
	})
}

func (t *Template) buildAppTemplateSet(appTemplateSet map[string]*template.Template, templates map[string]map[string]string) error {
	for ext, templateInfos := range templates {
		tmpl := template.New("")
		for _, path := range templateInfos {
			var templateBytes []byte
			if data := t.app.ResourceSet.Get(fmt.Sprintf("_kocha_%s.%s", path, ext)); data != nil {
				if b, ok := data.([]byte); ok {
					templateBytes = b
				}
			}
			if templateBytes == nil {
				b, err := ioutil.ReadFile(path)
				if err != nil {
					return err
				}
				templateBytes = b
				t.app.ResourceSet.Add(fmt.Sprintf("_kocha_%s.%s", path, ext), b)
			}
			name := strings.TrimSuffix(t.relativePath(path), util.TemplateSuffix)
			content := fmt.Sprint(
				t.LeftDelim, "$ := .Data", t.RightDelim,
				string(templateBytes),
			)
			if _, err := tmpl.New(name).Delims(t.LeftDelim, t.RightDelim).Funcs(template.FuncMap(t.FuncMap)).Parse(content); err != nil {
				return err
			}
		}
		appTemplateSet[ext] = tmpl
	}
	return nil
}

func (t *Template) relativePath(targpath string) string {
	for _, basepath := range t.PathInfo.Paths {
		if p, err := filepath.Rel(basepath, targpath); err == nil {
			return p
		}
	}
	return targpath
}

func (t *Template) yield(c *Context) (template.HTML, error) {
	tmpl, err := t.Get("", c.Name, c.Format)
	if err != nil {
		return "", err
	}
	buf := bufPool.Get().(*bytes.Buffer)
	defer func() {
		buf.Reset()
		bufPool.Put(buf)
	}()
	if err := tmpl.Execute(buf, c); err != nil {
		return "", err
	}
	return template.HTML(buf.String()), nil
}

// in is for "in" template function.
func (t *Template) in(a, b interface{}) (bool, error) {
	v := reflect.ValueOf(a)
	switch v.Kind() {
	case reflect.Slice, reflect.Array, reflect.String:
		if v.IsNil() {
			return false, nil
		}
		for i := 0; i < v.Len(); i++ {
			if v.Index(i).Interface() == b {
				return true, nil
			}
		}
	default:
		return false, fmt.Errorf("valid types are slice, array and string, got `%s'", v.Kind())
	}
	return false, nil
}

// url is for "url" template function.
func (t *Template) url(name string, v ...interface{}) (string, error) {
	return t.app.Router.Reverse(name, v...)
}

// nl2br is for "nl2br" template function.
func (t *Template) nl2br(text string) template.HTML {
	return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", "
", -1))
}

// raw is for "raw" template function.
func (t *Template) raw(text string) template.HTML {
	return template.HTML(text)
}

// invokeTemplate is for "invoke_template" template function.
func (t *Template) invokeTemplate(unit Unit, tmplName, defTmplName string, ctx ...*Context) (html template.HTML, err error) {
	var c *Context
	switch len(ctx) {
	case 0: // do nothing.
	case 1:
		c = ctx[0]
	default:
		return "", fmt.Errorf("number of context must be 0 or 1")
	}
	t.app.Invoke(unit, func() {
		if html, err = t.readPartialTemplate(tmplName, c); err != nil {
			// TODO: logging error.
			panic(ErrInvokeDefault)
		}
	}, func() {
		html, err = t.readPartialTemplate(defTmplName, c)
	})
	return html, err
}

// flash is for "flash" template function.
// This is a shorthand for {{.Flash.Get "success"}} in template.
func (t *Template) flash(c *Context, key string) string {
	return c.Flash.Get(key)
}

// join is for "join" template function.
func (t *Template) join(a interface{}, sep string) (string, error) {
	v := reflect.ValueOf(a)
	switch v.Kind() {
	case reflect.Slice, reflect.Array:
		// do nothing.
	default:
		return "", fmt.Errorf("valid types of first argument are slice or array, got `%s'", v.Kind())
	}
	if v.Len() == 0 {
		return "", nil
	}
	buf := append(make([]byte, 0, v.Len()*2-1), fmt.Sprint(v.Index(0).Interface())...)
	for i := 1; i < v.Len(); i++ {
		buf = append(append(buf, sep...), fmt.Sprint(v.Index(i).Interface())...)
	}
	return string(buf), nil
}

func (t *Template) readPartialTemplate(name string, c *Context) (template.HTML, error) {
	tmpl, err := t.Get("", name, "html")
	if err != nil {
		return "", err
	}
	buf := bufPool.Get().(*bytes.Buffer)
	defer func() {
		buf.Reset()
		bufPool.Put(buf)
	}()
	if err := tmpl.Execute(buf, c); err != nil {
		return "", err
	}
	return template.HTML(buf.String()), nil
}

func errorTemplateName(code int) string {
	return filepath.Join(ErrorTemplateDir, strconv.Itoa(code))
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Tigera, Inc. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package client

import (
	"github.com/tigera/libcalico-go/lib/common"
)

// AssignIPArgs defines the set of arguments for assigning a specific IP address.
type AssignIPArgs struct {
	// The IP address to assign.
	IP common.IP

	// If specified, a handle which can be used to retrieve / release
	// the allocated IP addresses in the future.
	HandleID *string

	// A key/value mapping of metadata to store with the allocations.
	Attrs map[string]string

	// If specified, the hostname of the host on which IP addresses
	// will be allocated.  If not specified, this will default
	// to the value provided by os.Hostname.
	Hostname *string
}

// AutoAssignArgs defines the set of arguments for assigning one or more
// IP addresses.
type AutoAssignArgs struct {
	// The number of IPv4 addresses to automatically assign.
	Num4 int

	// The number of IPv6 addresses to automatically assign.
	Num6 int

	// If specified, a handle which can be used to retrieve / release
	// the allocated IP addresses in the future.
	HandleID *string

	// A key/value mapping of metadata to store with the allocations.
	Attrs map[string]string

	// If specified, the hostname of the host on which IP addresses
	// will be allocated.  If not specified, this will default
	// to the value provided by os.Hostname.
	Hostname *string

	// If specified, the previously configured IPv4 pool from which
	// to assign IPv4 addresses.  If not specified, this defaults to all IPv4 pools.
	IPv4Pool *common.IPNet

	// If specified, the previously configured IPv6 pool from which
	// to assign IPv6 addresses.  If not specified, this defaults to all IPv6 pools.
	IPv6Pool *common.IPNet
}

// IPAMConfig contains global configuration options for Calico IPAM.
type IPAMConfig struct {
	// When StrictAffinity is true, addresses from a given block can only be
	// assigned by hosts with the blocks affinity.  If false, then AutoAllocateBlocks
	// must be true.
	StrictAffinity bool

	// When AutoAllocateBlocks is true, the IPAM client will automatically
	// allocate blocks as needed to assign addresses.  If false, then
	// StrictAffinity must be true.
	AutoAllocateBlocks bool
}
<commit_msg>Improve IPAMConfig GoDoc<commit_after>// Copyright (c) 2016 Tigera, Inc. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package client

import (
	"github.com/tigera/libcalico-go/lib/common"
)

// AssignIPArgs defines the set of arguments for assigning a specific IP address.
type AssignIPArgs struct {
	// The IP address to assign.
	IP common.IP

	// If specified, a handle which can be used to retrieve / release
	// the allocated IP addresses in the future.
	HandleID *string

	// A key/value mapping of metadata to store with the allocations.
	Attrs map[string]string

	// If specified, the hostname of the host on which IP addresses
	// will be allocated.  If not specified, this will default
	// to the value provided by os.Hostname.
	Hostname *string
}

// AutoAssignArgs defines the set of arguments for assigning one or more
// IP addresses.
type AutoAssignArgs struct {
	// The number of IPv4 addresses to automatically assign.
	Num4 int

	// The number of IPv6 addresses to automatically assign.
	Num6 int

	// If specified, a handle which can be used to retrieve / release
	// the allocated IP addresses in the future.
	HandleID *string

	// A key/value mapping of metadata to store with the allocations.
	Attrs map[string]string

	// If specified, the hostname of the host on which IP addresses
	// will be allocated.  If not specified, this will default
	// to the value provided by os.Hostname.
	Hostname *string

	// If specified, the previously configured IPv4 pool from which
	// to assign IPv4 addresses.  If not specified, this defaults to all IPv4 pools.
	IPv4Pool *common.IPNet

	// If specified, the previously configured IPv6 pool from which
	// to assign IPv6 addresses.  If not specified, this defaults to all IPv6 pools.
	IPv6Pool *common.IPNet
}

// IPAMConfig contains global configuration options for Calico IPAM.
// This IPAM configuration is stored in the datastore and configures the behavior
// of Calico IPAM across an entire Calico cluster.
type IPAMConfig struct {
	// When StrictAffinity is true, addresses from a given block can only be
	// assigned by hosts with the blocks affinity.  If false, then AutoAllocateBlocks
	// must be true.  The default value is false.
	StrictAffinity bool

	// When AutoAllocateBlocks is true, Calico will automatically
	// allocate blocks of IP address to hosts as needed to assign addresses.
	// If false, then StrictAffinity must be true.  The default value is true.
	AutoAllocateBlocks bool
}
<|endoftext|>