├── .editorconfig ├── Editor.meta ├── Editor ├── CodeWriter.PackageSymlinker.Editor.asmdef ├── CodeWriter.PackageSymlinker.Editor.asmdef.meta ├── PackageSymLinkerWindow.cs └── PackageSymLinkerWindow.cs.meta ├── LICENSE.md ├── LICENSE.md.meta ├── README.md ├── README.md.meta ├── package.json └── package.json.meta /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | [*] 3 | charset = utf-8 4 | end_of_line = crlf 5 | trim_trailing_whitespace = false 6 | insert_final_newline = false 7 | indent_style = space 8 | indent_size = 4 9 | 10 | # Microsoft .NET properties 11 | csharp_indent_braces = false 12 | csharp_indent_switch_labels = true 13 | csharp_new_line_before_catch = true 14 | csharp_new_line_before_else = true 15 | csharp_new_line_before_finally = true 16 | csharp_new_line_before_members_in_object_initializers = false 17 | csharp_new_line_before_open_brace = all 18 | csharp_new_line_between_query_expression_clauses = true 19 | csharp_preferred_modifier_order = public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion 20 | csharp_preserve_single_line_blocks = true 21 | csharp_space_after_cast = true 22 | csharp_space_after_colon_in_inheritance_clause = true 23 | csharp_space_after_comma = true 24 | csharp_space_after_dot = false 25 | csharp_space_after_keywords_in_control_flow_statements = true 26 | csharp_space_after_semicolon_in_for_statement = true 27 | csharp_space_around_binary_operators = before_and_after 28 | csharp_space_before_colon_in_inheritance_clause = true 29 | csharp_space_before_comma = false 30 | csharp_space_before_dot = false 31 | csharp_space_before_open_square_brackets = false 32 | csharp_space_before_semicolon_in_for_statement = false 33 | csharp_space_between_empty_square_brackets = false 34 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 35 | csharp_space_between_method_call_name_and_opening_parenthesis = false 36 | csharp_space_between_method_call_parameter_list_parentheses = false 37 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 38 | csharp_space_between_method_declaration_name_and_open_parenthesis = false 39 | csharp_space_between_method_declaration_parameter_list_parentheses = false 40 | csharp_space_between_parentheses = false 41 | csharp_space_between_square_brackets = false 42 | csharp_style_var_elsewhere = true:suggestion 43 | csharp_style_var_for_built_in_types = true:suggestion 44 | csharp_style_var_when_type_is_apparent = true:suggestion 45 | csharp_using_directive_placement = outside_namespace:silent 46 | dotnet_naming_rule.constants_rule.severity = warning 47 | dotnet_naming_rule.constants_rule.style = upper_camel_case_style 48 | dotnet_naming_rule.constants_rule.symbols = constants_symbols 49 | dotnet_naming_rule.event_rule.severity = warning 50 | dotnet_naming_rule.event_rule.style = upper_camel_case_style 51 | dotnet_naming_rule.event_rule.symbols = event_symbols 52 | dotnet_naming_rule.interfaces_rule.severity = warning 53 | dotnet_naming_rule.interfaces_rule.style = i_upper_camel_case_style 54 | dotnet_naming_rule.interfaces_rule.symbols = interfaces_symbols 55 | dotnet_naming_rule.locals_rule.severity = warning 56 | dotnet_naming_rule.locals_rule.style = lower_camel_case_style 57 | dotnet_naming_rule.locals_rule.symbols = locals_symbols 58 | dotnet_naming_rule.local_constants_rule.severity = warning 59 | dotnet_naming_rule.local_constants_rule.style = lower_camel_case_style 60 | dotnet_naming_rule.local_constants_rule.symbols = local_constants_symbols 61 | dotnet_naming_rule.local_functions_rule.severity = warning 62 | dotnet_naming_rule.local_functions_rule.style = upper_camel_case_style 63 | dotnet_naming_rule.local_functions_rule.symbols = local_functions_symbols 64 | dotnet_naming_rule.method_rule.severity = warning 65 | dotnet_naming_rule.method_rule.style = upper_camel_case_style 66 | dotnet_naming_rule.method_rule.symbols = method_symbols 67 | dotnet_naming_rule.parameters_rule.severity = warning 68 | dotnet_naming_rule.parameters_rule.style = lower_camel_case_style 69 | dotnet_naming_rule.parameters_rule.symbols = parameters_symbols 70 | dotnet_naming_rule.private_constants_rule.severity = warning 71 | dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style 72 | dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols 73 | dotnet_naming_rule.private_instance_fields_rule.severity = warning 74 | dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style_1 75 | dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols 76 | dotnet_naming_rule.private_static_fields_rule.severity = warning 77 | dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style_1 78 | dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols 79 | dotnet_naming_rule.private_static_readonly_rule.severity = warning 80 | dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style 81 | dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols 82 | dotnet_naming_rule.property_rule.severity = warning 83 | dotnet_naming_rule.property_rule.style = upper_camel_case_style 84 | dotnet_naming_rule.property_rule.symbols = property_symbols 85 | dotnet_naming_rule.public_fields_rule.severity = warning 86 | dotnet_naming_rule.public_fields_rule.style = lower_camel_case_style 87 | dotnet_naming_rule.public_fields_rule.symbols = public_fields_symbols 88 | dotnet_naming_rule.static_readonly_rule.severity = warning 89 | dotnet_naming_rule.static_readonly_rule.style = upper_camel_case_style 90 | dotnet_naming_rule.static_readonly_rule.symbols = static_readonly_symbols 91 | dotnet_naming_rule.types_and_namespaces_rule.severity = warning 92 | dotnet_naming_rule.types_and_namespaces_rule.style = upper_camel_case_style 93 | dotnet_naming_rule.types_and_namespaces_rule.symbols = types_and_namespaces_symbols 94 | dotnet_naming_rule.type_parameters_rule.severity = warning 95 | dotnet_naming_rule.type_parameters_rule.style = t_upper_camel_case_style 96 | dotnet_naming_rule.type_parameters_rule.symbols = type_parameters_symbols 97 | dotnet_naming_style.i_upper_camel_case_style.capitalization = pascal_case 98 | dotnet_naming_style.i_upper_camel_case_style.required_prefix = I 99 | dotnet_naming_style.lower_camel_case_style.capitalization = camel_case 100 | dotnet_naming_style.lower_camel_case_style_1.capitalization = camel_case 101 | dotnet_naming_style.lower_camel_case_style_1.required_prefix = _ 102 | dotnet_naming_style.t_upper_camel_case_style.capitalization = pascal_case 103 | dotnet_naming_style.t_upper_camel_case_style.required_prefix = T 104 | dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case 105 | dotnet_naming_symbols.constants_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected 106 | dotnet_naming_symbols.constants_symbols.applicable_kinds = field 107 | dotnet_naming_symbols.constants_symbols.required_modifiers = const 108 | dotnet_naming_symbols.event_symbols.applicable_accessibilities = * 109 | dotnet_naming_symbols.event_symbols.applicable_kinds = event 110 | dotnet_naming_symbols.interfaces_symbols.applicable_accessibilities = * 111 | dotnet_naming_symbols.interfaces_symbols.applicable_kinds = interface 112 | dotnet_naming_symbols.locals_symbols.applicable_accessibilities = * 113 | dotnet_naming_symbols.locals_symbols.applicable_kinds = local 114 | dotnet_naming_symbols.local_constants_symbols.applicable_accessibilities = * 115 | dotnet_naming_symbols.local_constants_symbols.applicable_kinds = local 116 | dotnet_naming_symbols.local_constants_symbols.required_modifiers = const 117 | dotnet_naming_symbols.local_functions_symbols.applicable_accessibilities = * 118 | dotnet_naming_symbols.local_functions_symbols.applicable_kinds = local_function 119 | dotnet_naming_symbols.method_symbols.applicable_accessibilities = * 120 | dotnet_naming_symbols.method_symbols.applicable_kinds = method 121 | dotnet_naming_symbols.parameters_symbols.applicable_accessibilities = * 122 | dotnet_naming_symbols.parameters_symbols.applicable_kinds = parameter 123 | dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private 124 | dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field 125 | dotnet_naming_symbols.private_constants_symbols.required_modifiers = const 126 | dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private 127 | dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field 128 | dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private 129 | dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field 130 | dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static 131 | dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private 132 | dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field 133 | dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static,readonly 134 | dotnet_naming_symbols.property_symbols.applicable_accessibilities = * 135 | dotnet_naming_symbols.property_symbols.applicable_kinds = property 136 | dotnet_naming_symbols.public_fields_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected 137 | dotnet_naming_symbols.public_fields_symbols.applicable_kinds = field 138 | dotnet_naming_symbols.static_readonly_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected 139 | dotnet_naming_symbols.static_readonly_symbols.applicable_kinds = field 140 | dotnet_naming_symbols.static_readonly_symbols.required_modifiers = static,readonly 141 | dotnet_naming_symbols.types_and_namespaces_symbols.applicable_accessibilities = * 142 | dotnet_naming_symbols.types_and_namespaces_symbols.applicable_kinds = namespace,class,struct,enum,delegate 143 | dotnet_naming_symbols.type_parameters_symbols.applicable_accessibilities = * 144 | dotnet_naming_symbols.type_parameters_symbols.applicable_kinds = type_parameter 145 | dotnet_separate_import_directive_groups = false 146 | dotnet_sort_system_directives_first = true 147 | dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none 148 | dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none 149 | dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none 150 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion 151 | dotnet_style_predefined_type_for_member_access = true:suggestion 152 | dotnet_style_qualification_for_event = false:suggestion 153 | dotnet_style_qualification_for_field = false:suggestion 154 | dotnet_style_qualification_for_method = false:suggestion 155 | dotnet_style_qualification_for_property = false:suggestion 156 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion 157 | file_header_template = 158 | 159 | # ReSharper properties 160 | resharper_accessor_owner_body = expression_body 161 | resharper_alignment_tab_fill_style = use_spaces 162 | resharper_align_first_arg_by_paren = false 163 | resharper_align_linq_query = false 164 | resharper_align_multiline_array_and_object_initializer = false 165 | resharper_align_multiline_array_initializer = true 166 | resharper_align_multiline_ctor_init = true 167 | resharper_align_multiline_expression_braces = false 168 | resharper_align_multiline_implements_list = true 169 | resharper_align_multiline_property_pattern = false 170 | resharper_align_multiline_switch_expression = false 171 | resharper_align_multiline_type_argument = true 172 | resharper_align_multiline_type_parameter = true 173 | resharper_align_multline_type_parameter_constrains = false 174 | resharper_align_multline_type_parameter_list = false 175 | resharper_align_ternary = align_not_nested 176 | resharper_align_tuple_components = false 177 | resharper_allow_alias = true 178 | resharper_allow_comment_after_lbrace = false 179 | resharper_allow_far_alignment = false 180 | resharper_always_use_end_of_line_brace_style = false 181 | resharper_anonymous_method_declaration_braces = next_line 182 | resharper_apply_auto_detected_rules = true 183 | resharper_apply_on_completion = false 184 | resharper_arguments_anonymous_function = positional 185 | resharper_arguments_literal = positional 186 | resharper_arguments_named = positional 187 | resharper_arguments_other = positional 188 | resharper_arguments_skip_single = false 189 | resharper_arguments_string_literal = positional 190 | resharper_attribute_style = do_not_touch 191 | resharper_autodetect_indent_settings = true 192 | resharper_blank_lines_after_block_statements = 1 193 | resharper_blank_lines_after_case = 0 194 | resharper_blank_lines_after_control_transfer_statements = 0 195 | resharper_blank_lines_after_imports = 1 196 | resharper_blank_lines_after_multiline_statements = 0 197 | resharper_blank_lines_after_options = 1 198 | resharper_blank_lines_after_start_comment = 1 199 | resharper_blank_lines_after_using_list = 1 200 | resharper_blank_lines_around_accessor = 0 201 | resharper_blank_lines_around_auto_property = 1 202 | resharper_blank_lines_around_block_case_section = 0 203 | resharper_blank_lines_around_class_definition = 1 204 | resharper_blank_lines_around_field = 1 205 | resharper_blank_lines_around_function_declaration = 0 206 | resharper_blank_lines_around_function_definition = 1 207 | resharper_blank_lines_around_global_attribute = 0 208 | resharper_blank_lines_around_invocable = 1 209 | resharper_blank_lines_around_local_method = 1 210 | resharper_blank_lines_around_multiline_case_section = 0 211 | resharper_blank_lines_around_namespace = 1 212 | resharper_blank_lines_around_other_declaration = 0 213 | resharper_blank_lines_around_property = 1 214 | resharper_blank_lines_around_razor_functions = 1 215 | resharper_blank_lines_around_razor_helpers = 1 216 | resharper_blank_lines_around_razor_sections = 1 217 | resharper_blank_lines_around_region = 1 218 | resharper_blank_lines_around_single_line_accessor = 0 219 | resharper_blank_lines_around_single_line_auto_property = 0 220 | resharper_blank_lines_around_single_line_field = 0 221 | resharper_blank_lines_around_single_line_function_definition = 0 222 | resharper_blank_lines_around_single_line_invocable = 0 223 | resharper_blank_lines_around_single_line_local_method = 0 224 | resharper_blank_lines_around_single_line_property = 0 225 | resharper_blank_lines_around_single_line_type = 1 226 | resharper_blank_lines_around_type = 1 227 | resharper_blank_lines_before_block_statements = 0 228 | resharper_blank_lines_before_case = 0 229 | resharper_blank_lines_before_control_transfer_statements = 0 230 | resharper_blank_lines_before_multiline_statements = 0 231 | resharper_blank_lines_before_single_line_comment = 0 232 | resharper_blank_lines_inside_namespace = 0 233 | resharper_blank_lines_inside_region = 1 234 | resharper_blank_lines_inside_type = 0 235 | resharper_blank_line_after_pi = true 236 | resharper_braces_for_dowhile = required 237 | resharper_braces_for_fixed = required 238 | resharper_braces_for_for = not_required 239 | resharper_braces_for_foreach = not_required 240 | resharper_braces_for_ifelse = not_required_for_both 241 | resharper_braces_for_lock = required 242 | resharper_braces_for_using = required 243 | resharper_braces_for_while = not_required 244 | resharper_braces_redundant = true 245 | resharper_break_template_declaration = line_break 246 | resharper_can_use_global_alias = true 247 | resharper_constructor_or_destructor_body = block_body 248 | resharper_continuous_indent_multiplier = 1 249 | resharper_continuous_line_indent = single 250 | resharper_cpp_align_multiline_argument = true 251 | resharper_cpp_align_multiline_binary_expressions_chain = false 252 | resharper_cpp_align_multiline_calls_chain = true 253 | resharper_cpp_align_multiline_extends_list = true 254 | resharper_cpp_align_multiline_for_stmt = true 255 | resharper_cpp_align_multiline_parameter = true 256 | resharper_cpp_align_multiple_declaration = true 257 | resharper_cpp_case_block_braces = next_line_shifted_2 258 | resharper_cpp_indent_switch_labels = false 259 | resharper_cpp_max_line_length = 120 260 | resharper_cpp_new_line_before_while = true 261 | resharper_cpp_space_after_cast = false 262 | resharper_cpp_space_around_binary_operator = true 263 | resharper_cpp_wrap_lines = true 264 | resharper_csharp_align_multiline_argument = false 265 | resharper_csharp_align_multiline_binary_expressions_chain = true 266 | resharper_csharp_align_multiline_calls_chain = false 267 | resharper_csharp_align_multiline_expression = false 268 | resharper_csharp_align_multiline_extends_list = false 269 | resharper_csharp_align_multiline_for_stmt = false 270 | resharper_csharp_align_multiline_parameter = false 271 | resharper_csharp_align_multiple_declaration = false 272 | resharper_csharp_max_line_length = 120 273 | resharper_csharp_naming_rule.enum_member = AaBb 274 | resharper_csharp_naming_rule.method_property_event = AaBb 275 | resharper_csharp_naming_rule.other = AaBb 276 | resharper_csharp_naming_rule.public_fields = aaBb, AaBb 277 | resharper_csharp_new_line_before_while = false 278 | resharper_csharp_prefer_qualified_reference = false 279 | resharper_csharp_space_after_unary_operator = false 280 | resharper_csharp_wrap_lines = true 281 | resharper_cxxcli_property_declaration_braces = next_line 282 | resharper_default_exception_variable_name = e 283 | resharper_default_value_when_type_evident = default_literal 284 | resharper_default_value_when_type_not_evident = default_literal 285 | resharper_delete_quotes_from_solid_values = false 286 | resharper_disable_blank_line_changes = false 287 | resharper_disable_formatter = false 288 | resharper_disable_indenter = false 289 | resharper_disable_int_align = false 290 | resharper_disable_line_break_changes = false 291 | resharper_disable_line_break_removal = false 292 | resharper_disable_space_changes = false 293 | resharper_disable_space_changes_before_trailing_comment = false 294 | resharper_dont_remove_extra_blank_lines = false 295 | resharper_empty_block_style = multiline 296 | resharper_enable_wrapping = false 297 | resharper_enforce_line_ending_style = false 298 | resharper_event_handler_pattern_long = $object$On$event$ 299 | resharper_event_handler_pattern_short = On$event$ 300 | resharper_expression_braces = inside 301 | resharper_expression_pars = inside 302 | resharper_extra_spaces = remove_all 303 | resharper_force_attribute_style = separate 304 | resharper_force_chop_compound_do_expression = false 305 | resharper_force_chop_compound_if_expression = false 306 | resharper_force_chop_compound_while_expression = false 307 | resharper_format_leading_spaces_decl = false 308 | resharper_free_block_braces = next_line 309 | resharper_fsharp_align_function_signature_to_indentation = false 310 | resharper_fsharp_alternative_long_member_definitions = false 311 | resharper_fsharp_indent_on_try_with = false 312 | resharper_fsharp_keep_if_then_in_same_line = false 313 | resharper_fsharp_max_array_or_list_width = 40 314 | resharper_fsharp_max_elmish_width = 40 315 | resharper_fsharp_max_function_binding_width = 40 316 | resharper_fsharp_max_if_then_else_short_width = 40 317 | resharper_fsharp_max_infix_operator_expression = 50 318 | resharper_fsharp_max_line_length = 120 319 | resharper_fsharp_max_record_width = 40 320 | resharper_fsharp_max_value_binding_width = 40 321 | resharper_fsharp_multiline_block_brackets_on_same_column = false 322 | resharper_fsharp_newline_between_type_definition_and_members = false 323 | resharper_fsharp_semicolon_at_end_of_line = false 324 | resharper_fsharp_single_argument_web_mode = false 325 | resharper_fsharp_space_after_comma = true 326 | resharper_fsharp_space_after_semicolon = true 327 | resharper_fsharp_space_around_delimiter = true 328 | resharper_fsharp_space_before_class_constructor = false 329 | resharper_fsharp_space_before_colon = false 330 | resharper_fsharp_space_before_lowercase_invocation = true 331 | resharper_fsharp_space_before_member = false 332 | resharper_fsharp_space_before_parameter = true 333 | resharper_fsharp_space_before_semicolon = false 334 | resharper_fsharp_space_before_uppercase_invocation = false 335 | resharper_fsharp_wrap_lines = true 336 | resharper_function_declaration_return_type_style = do_not_change 337 | resharper_function_definition_return_type_style = do_not_change 338 | resharper_generator_mode = false 339 | resharper_html_attribute_indent = align_by_first_attribute 340 | resharper_html_linebreak_before_elements = body,div,p,form,h1,h2,h3 341 | resharper_html_max_blank_lines_between_tags = 2 342 | resharper_html_max_line_length = 120 343 | resharper_html_pi_attribute_style = on_single_line 344 | resharper_html_space_before_self_closing = false 345 | resharper_html_wrap_lines = true 346 | resharper_ignore_space_preservation = false 347 | resharper_include_prefix_comment_in_indent = false 348 | resharper_indent_access_specifiers_from_class = false 349 | resharper_indent_aligned_ternary = true 350 | resharper_indent_anonymous_method_block = false 351 | resharper_indent_case_from_select = true 352 | resharper_indent_child_elements = OneIndent 353 | resharper_indent_class_members_from_access_specifiers = false 354 | resharper_indent_comment = true 355 | resharper_indent_inside_namespace = true 356 | resharper_indent_invocation_pars = inside 357 | resharper_indent_method_decl_pars = inside 358 | resharper_indent_nested_fixed_stmt = false 359 | resharper_indent_nested_foreach_stmt = false 360 | resharper_indent_nested_for_stmt = false 361 | resharper_indent_nested_lock_stmt = false 362 | resharper_indent_nested_usings_stmt = false 363 | resharper_indent_nested_while_stmt = false 364 | resharper_indent_pars = inside 365 | resharper_indent_preprocessor_directives = normal 366 | resharper_indent_preprocessor_if = no_indent 367 | resharper_indent_preprocessor_other = no_indent 368 | resharper_indent_preprocessor_region = usual_indent 369 | resharper_indent_statement_pars = inside 370 | resharper_indent_text = OneIndent 371 | resharper_indent_typearg_angles = inside 372 | resharper_indent_typeparam_angles = inside 373 | resharper_indent_type_constraints = true 374 | resharper_indent_wrapped_function_names = false 375 | resharper_instance_members_qualify_declared_in = this_class, base_class 376 | resharper_int_align = false 377 | resharper_int_align_comments = false 378 | resharper_int_align_declaration_names = false 379 | resharper_int_align_eq = false 380 | resharper_int_align_fix_in_adjacent = true 381 | resharper_invocable_declaration_braces = next_line 382 | resharper_keep_blank_lines_in_code = 2 383 | resharper_keep_blank_lines_in_declarations = 2 384 | resharper_keep_existing_attribute_arrangement = true 385 | resharper_keep_existing_declaration_block_arrangement = false 386 | resharper_keep_existing_declaration_parens_arrangement = true 387 | resharper_keep_existing_embedded_arrangement = true 388 | resharper_keep_existing_embedded_block_arrangement = false 389 | resharper_keep_existing_enum_arrangement = false 390 | resharper_keep_existing_expr_member_arrangement = true 391 | resharper_keep_existing_invocation_parens_arrangement = true 392 | resharper_keep_existing_property_patterns_arrangement = true 393 | resharper_keep_existing_switch_expression_arrangement = true 394 | resharper_keep_nontrivial_alias = true 395 | resharper_keep_user_linebreaks = true 396 | resharper_keep_user_wrapping = true 397 | resharper_linebreaks_around_razor_statements = true 398 | resharper_linebreaks_inside_tags_for_elements_longer_than = 2147483647 399 | resharper_linebreaks_inside_tags_for_elements_with_child_elements = true 400 | resharper_linebreaks_inside_tags_for_multiline_elements = true 401 | resharper_linebreak_before_all_elements = false 402 | resharper_linebreak_before_multiline_elements = true 403 | resharper_linebreak_before_singleline_elements = false 404 | resharper_line_break_after_colon_in_member_initializer_lists = do_not_change 405 | resharper_line_break_after_comma_in_member_initializer_lists = false 406 | resharper_line_break_before_comma_in_member_initializer_lists = false 407 | resharper_linkage_specification_braces = end_of_line 408 | resharper_linkage_specification_indentation = none 409 | resharper_local_function_body = block_body 410 | resharper_max_array_initializer_elements_on_line = 10000 411 | resharper_max_attribute_length_for_same_line = 38 412 | resharper_max_enum_members_on_line = 3 413 | resharper_max_formal_parameters_on_line = 10000 414 | resharper_max_initializer_elements_on_line = 4 415 | resharper_max_invocation_arguments_on_line = 10000 416 | resharper_member_initializer_list_style = do_not_change 417 | resharper_method_or_operator_body = block_body 418 | resharper_namespace_declaration_braces = next_line 419 | resharper_namespace_indentation = all 420 | resharper_nested_ternary_style = autodetect 421 | resharper_never_outdent_pipe_operators = true 422 | resharper_new_line_before_catch = true 423 | resharper_new_line_before_else = true 424 | resharper_new_line_before_enumerators = true 425 | resharper_normalize_tag_names = false 426 | resharper_no_indent_inside_elements = html,body,thead,tbody,tfoot 427 | resharper_no_indent_inside_if_element_longer_than = 200 428 | resharper_object_creation_when_type_evident = target_typed 429 | resharper_object_creation_when_type_not_evident = explicitly_typed 430 | resharper_old_engine = false 431 | resharper_other_braces = next_line 432 | resharper_outdent_binary_operators = true 433 | resharper_outdent_binary_ops = false 434 | resharper_outdent_commas = false 435 | resharper_outdent_dots = false 436 | resharper_outdent_namespace_member = false 437 | resharper_outdent_ternary_ops = false 438 | resharper_parentheses_non_obvious_operations = none, bitwise, bitwise_inclusive_or, bitwise_exclusive_or, shift, bitwise_and 439 | resharper_parentheses_redundancy_style = remove_if_not_clarifies_precedence 440 | resharper_pi_attributes_indent = align_by_first_attribute 441 | resharper_place_attribute_on_same_line = true 442 | resharper_place_comments_at_first_column = false 443 | resharper_place_constructor_initializer_on_same_line = true 444 | resharper_place_event_attribute_on_same_line = false 445 | resharper_place_expr_accessor_on_single_line = if_owner_is_single_line 446 | resharper_place_expr_method_on_single_line = if_owner_is_single_line 447 | resharper_place_expr_property_on_single_line = if_owner_is_single_line 448 | resharper_place_linq_into_on_new_line = true 449 | resharper_place_namespace_definitions_on_same_line = false 450 | resharper_place_property_attribute_on_same_line = false 451 | resharper_place_simple_case_statement_on_same_line = false 452 | resharper_place_simple_embedded_statement_on_same_line = if_owner_is_single_line 453 | resharper_place_simple_initializer_on_single_line = true 454 | resharper_place_simple_property_pattern_on_single_line = true 455 | resharper_place_simple_switch_expression_on_single_line = false 456 | resharper_place_type_constraints_on_same_line = true 457 | resharper_prefer_explicit_discard_declaration = false 458 | resharper_prefer_separate_deconstructed_variables_declaration = false 459 | resharper_preserve_spaces_inside_tags = pre,textarea 460 | resharper_qualified_using_at_nested_scope = false 461 | resharper_quote_style = doublequoted 462 | resharper_razor_prefer_qualified_reference = true 463 | resharper_remove_blank_lines_near_braces = false 464 | resharper_remove_blank_lines_near_braces_in_code = true 465 | resharper_remove_blank_lines_near_braces_in_declarations = true 466 | resharper_remove_this_qualifier = true 467 | resharper_requires_expression_braces = next_line 468 | resharper_resx_attribute_indent = single_indent 469 | resharper_resx_linebreak_before_elements = 470 | resharper_resx_max_blank_lines_between_tags = 0 471 | resharper_resx_max_line_length = 2147483647 472 | resharper_resx_pi_attribute_style = do_not_touch 473 | resharper_resx_space_before_self_closing = false 474 | resharper_resx_wrap_lines = false 475 | resharper_resx_wrap_tags_and_pi = false 476 | resharper_resx_wrap_text = false 477 | resharper_shaderlab_brace_style = next_line 478 | resharper_shaderlab_max_line_length = 120 479 | resharper_shaderlab_wrap_lines = true 480 | resharper_show_autodetect_configure_formatting_tip = true 481 | resharper_simple_block_style = do_not_change 482 | resharper_simple_case_statement_style = do_not_change 483 | resharper_simple_embedded_statement_style = do_not_change 484 | resharper_sort_attributes = false 485 | resharper_sort_class_selectors = false 486 | resharper_sort_usings = true 487 | resharper_sort_usings_lowercase_first = false 488 | resharper_spaces_around_eq_in_attribute = false 489 | resharper_spaces_around_eq_in_pi_attribute = false 490 | resharper_spaces_inside_tags = false 491 | resharper_space_after_attributes = true 492 | resharper_space_after_attribute_target_colon = true 493 | resharper_space_after_colon = true 494 | resharper_space_after_colon_in_case = true 495 | resharper_space_after_colon_in_inheritance_clause = true 496 | resharper_space_after_comma = true 497 | resharper_space_after_for_colon = true 498 | resharper_space_after_keywords_in_control_flow_statements = true 499 | resharper_space_after_last_attribute = false 500 | resharper_space_after_last_pi_attribute = false 501 | resharper_space_after_operator_keyword = true 502 | resharper_space_after_ptr_in_data_member = true 503 | resharper_space_after_ptr_in_data_members = false 504 | resharper_space_after_ptr_in_method = true 505 | resharper_space_after_ref_in_data_member = true 506 | resharper_space_after_ref_in_data_members = false 507 | resharper_space_after_ref_in_method = true 508 | resharper_space_after_semicolon_in_for_statement = true 509 | resharper_space_after_ternary_colon = true 510 | resharper_space_after_ternary_quest = true 511 | resharper_space_after_triple_slash = true 512 | resharper_space_after_type_parameter_constraint_colon = true 513 | resharper_space_around_additive_op = true 514 | resharper_space_around_alias_eq = true 515 | resharper_space_around_assignment_op = true 516 | resharper_space_around_assignment_operator = true 517 | resharper_space_around_deref_in_trailing_return_type = true 518 | resharper_space_around_lambda_arrow = true 519 | resharper_space_around_member_access_operator = false 520 | resharper_space_around_relational_op = true 521 | resharper_space_around_shift_op = true 522 | resharper_space_around_stmt_colon = true 523 | resharper_space_around_ternary_operator = true 524 | resharper_space_before_array_rank_parentheses = false 525 | resharper_space_before_attribute_target_colon = false 526 | resharper_space_before_checked_parentheses = false 527 | resharper_space_before_colon = false 528 | resharper_space_before_colon_in_case = false 529 | resharper_space_before_colon_in_inheritance_clause = true 530 | resharper_space_before_comma = false 531 | resharper_space_before_default_parentheses = false 532 | resharper_space_before_empty_invocation_parentheses = false 533 | resharper_space_before_empty_method_parentheses = false 534 | resharper_space_before_for_colon = true 535 | resharper_space_before_initializer_braces = false 536 | resharper_space_before_invocation_parentheses = false 537 | resharper_space_before_label_colon = false 538 | resharper_space_before_lambda_parentheses = false 539 | resharper_space_before_method_parentheses = false 540 | resharper_space_before_nameof_parentheses = false 541 | resharper_space_before_nullable_mark = false 542 | resharper_space_before_open_square_brackets = false 543 | resharper_space_before_pointer_asterik_declaration = false 544 | resharper_space_before_ptr_in_abstract_decl = false 545 | resharper_space_before_ptr_in_data_member = false 546 | resharper_space_before_ptr_in_data_members = true 547 | resharper_space_before_ptr_in_method = false 548 | resharper_space_before_ref_in_abstract_decl = false 549 | resharper_space_before_ref_in_data_member = false 550 | resharper_space_before_ref_in_data_members = true 551 | resharper_space_before_ref_in_method = false 552 | resharper_space_before_semicolon = false 553 | resharper_space_before_semicolon_in_for_statement = false 554 | resharper_space_before_singleline_accessorholder = true 555 | resharper_space_before_sizeof_parentheses = false 556 | resharper_space_before_template_args = false 557 | resharper_space_before_template_params = true 558 | resharper_space_before_ternary_colon = true 559 | resharper_space_before_ternary_quest = true 560 | resharper_space_before_trailing_comment = true 561 | resharper_space_before_typeof_parentheses = false 562 | resharper_space_before_type_argument_angle = false 563 | resharper_space_before_type_parameter_angle = false 564 | resharper_space_before_type_parameter_constraint_colon = true 565 | resharper_space_before_type_parameter_parentheses = true 566 | resharper_space_between_accessors_in_singleline_property = true 567 | resharper_space_between_attribute_sections = true 568 | resharper_space_between_closing_angle_brackets_in_template_args = false 569 | resharper_space_between_keyword_and_expression = true 570 | resharper_space_between_keyword_and_type = true 571 | resharper_space_between_method_call_empty_parameter_list_parentheses = false 572 | resharper_space_between_method_call_name_and_opening_parenthesis = false 573 | resharper_space_between_method_call_parameter_list_parentheses = false 574 | resharper_space_between_method_declaration_empty_parameter_list_parentheses = false 575 | resharper_space_between_method_declaration_name_and_open_parenthesis = false 576 | resharper_space_between_method_declaration_parameter_list_parentheses = false 577 | resharper_space_between_parentheses_of_control_flow_statements = false 578 | resharper_space_between_square_brackets = false 579 | resharper_space_between_typecast_parentheses = false 580 | resharper_space_in_singleline_accessorholder = true 581 | resharper_space_in_singleline_anonymous_method = true 582 | resharper_space_in_singleline_method = true 583 | resharper_space_near_postfix_and_prefix_op = false 584 | resharper_space_within_array_initialization_braces = false 585 | resharper_space_within_array_rank_empty_parentheses = false 586 | resharper_space_within_array_rank_parentheses = false 587 | resharper_space_within_attribute_angles = false 588 | resharper_space_within_checked_parentheses = false 589 | resharper_space_within_default_parentheses = false 590 | resharper_space_within_empty_braces = true 591 | resharper_space_within_empty_initializer_braces = false 592 | resharper_space_within_empty_invocation_parentheses = false 593 | resharper_space_within_empty_method_parentheses = false 594 | resharper_space_within_empty_template_params = false 595 | resharper_space_within_expression_parentheses = false 596 | resharper_space_within_initializer_braces = false 597 | resharper_space_within_invocation_parentheses = false 598 | resharper_space_within_method_parentheses = false 599 | resharper_space_within_nameof_parentheses = false 600 | resharper_space_within_parentheses = false 601 | resharper_space_within_single_line_array_initializer_braces = false 602 | resharper_space_within_sizeof_parentheses = false 603 | resharper_space_within_template_args = false 604 | resharper_space_within_template_params = false 605 | resharper_space_within_tuple_parentheses = false 606 | resharper_space_within_typeof_parentheses = false 607 | resharper_space_within_type_argument_angles = false 608 | resharper_space_within_type_parameter_angles = false 609 | resharper_space_within_type_parameter_parentheses = false 610 | resharper_special_else_if_treatment = true 611 | resharper_static_members_qualify_members = none 612 | resharper_static_members_qualify_with = declared_type 613 | resharper_stick_comment = true 614 | resharper_support_vs_event_naming_pattern = true 615 | resharper_toplevel_function_declaration_return_type_style = do_not_change 616 | resharper_toplevel_function_definition_return_type_style = do_not_change 617 | resharper_trailing_comma_in_multiline_lists = false 618 | resharper_trailing_comma_in_singleline_lists = false 619 | resharper_type_declaration_braces = next_line 620 | resharper_use_continuous_indent_inside_initializer_braces = true 621 | resharper_use_continuous_indent_inside_parens = true 622 | resharper_use_continuous_line_indent_in_expression_braces = false 623 | resharper_use_continuous_line_indent_in_method_pars = false 624 | resharper_use_heuristics_for_body_style = true 625 | resharper_use_indents_from_main_language_in_file = true 626 | resharper_use_indent_from_previous_element = true 627 | resharper_use_indent_from_vs = false 628 | resharper_use_roslyn_logic_for_evident_types = false 629 | resharper_vb_align_multiline_argument = true 630 | resharper_vb_align_multiline_expression = true 631 | resharper_vb_align_multiline_parameter = true 632 | resharper_vb_align_multiple_declaration = true 633 | resharper_vb_max_line_length = 120 634 | resharper_vb_place_field_attribute_on_same_line = true 635 | resharper_vb_place_method_attribute_on_same_line = false 636 | resharper_vb_place_type_attribute_on_same_line = false 637 | resharper_vb_prefer_qualified_reference = false 638 | resharper_vb_space_after_unary_operator = true 639 | resharper_vb_space_around_multiplicative_op = false 640 | resharper_vb_wrap_lines = true 641 | resharper_wrap_after_binary_opsign = true 642 | resharper_wrap_after_declaration_lpar = false 643 | resharper_wrap_after_dot = false 644 | resharper_wrap_after_dot_in_method_calls = false 645 | resharper_wrap_after_expression_lbrace = true 646 | resharper_wrap_after_invocation_lpar = false 647 | resharper_wrap_arguments_style = wrap_if_long 648 | resharper_wrap_around_elements = true 649 | resharper_wrap_array_initializer_style = wrap_if_long 650 | resharper_wrap_base_clause_style = wrap_if_long 651 | resharper_wrap_before_arrow_with_expressions = false 652 | resharper_wrap_before_binary_opsign = false 653 | resharper_wrap_before_colon = false 654 | resharper_wrap_before_comma = false 655 | resharper_wrap_before_comma_in_base_clause = false 656 | resharper_wrap_before_declaration_lpar = false 657 | resharper_wrap_before_declaration_rpar = false 658 | resharper_wrap_before_expression_rbrace = true 659 | resharper_wrap_before_extends_colon = false 660 | resharper_wrap_before_first_type_parameter_constraint = false 661 | resharper_wrap_before_invocation_lpar = false 662 | resharper_wrap_before_invocation_rpar = false 663 | resharper_wrap_before_linq_expression = false 664 | resharper_wrap_before_ternary_opsigns = true 665 | resharper_wrap_before_type_parameter_langle = false 666 | resharper_wrap_braced_init_list_style = wrap_if_long 667 | resharper_wrap_chained_binary_expressions = wrap_if_long 668 | resharper_wrap_chained_method_calls = wrap_if_long 669 | resharper_wrap_ctor_initializer_style = wrap_if_long 670 | resharper_wrap_enumeration_style = chop_if_long 671 | resharper_wrap_enum_declaration = chop_always 672 | resharper_wrap_extends_list_style = wrap_if_long 673 | resharper_wrap_for_stmt_header_style = chop_if_long 674 | resharper_wrap_multiple_declaration_style = chop_if_long 675 | resharper_wrap_multiple_type_parameter_constraints_style = chop_if_long 676 | resharper_wrap_object_and_collection_initializer_style = chop_if_long 677 | resharper_wrap_parameters_style = wrap_if_long 678 | resharper_wrap_property_pattern = chop_if_long 679 | resharper_wrap_switch_expression = chop_always 680 | resharper_wrap_ternary_expr_style = chop_if_long 681 | resharper_wrap_verbatim_interpolated_strings = no_wrap 682 | resharper_xmldoc_attribute_indent = single_indent 683 | resharper_xmldoc_linebreak_before_elements = summary,remarks,example,returns,param,typeparam,value,para 684 | resharper_xmldoc_max_blank_lines_between_tags = 0 685 | resharper_xmldoc_max_line_length = 120 686 | resharper_xmldoc_pi_attribute_style = do_not_touch 687 | resharper_xmldoc_space_before_self_closing = true 688 | resharper_xmldoc_wrap_lines = true 689 | resharper_xmldoc_wrap_tags_and_pi = true 690 | resharper_xmldoc_wrap_text = true 691 | resharper_xml_attribute_indent = align_by_first_attribute 692 | resharper_xml_linebreak_before_elements = 693 | resharper_xml_max_blank_lines_between_tags = 2 694 | resharper_xml_max_line_length = 120 695 | resharper_xml_pi_attribute_style = do_not_touch 696 | resharper_xml_space_before_self_closing = true 697 | resharper_xml_wrap_lines = true 698 | resharper_xml_wrap_tags_and_pi = true 699 | resharper_xml_wrap_text = false 700 | 701 | [*.asmdef] 702 | indent_style = space 703 | indent_size = 2 704 | 705 | [*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,fs,fsi,fsscript,fsx,hlsl,hlsli,hlslinc,master,ml,mli,nuspec,paml,razor,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}] 706 | indent_style = space 707 | indent_size = 4 708 | tab_width = 4 709 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f7b12e3197d84564b88b2d78e70712f9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/CodeWriter.PackageSymlinker.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CodeWriter.PackageSymlinker.Editor", 3 | "references": [], 4 | "includePlatforms": [ 5 | "Editor" 6 | ], 7 | "excludePlatforms": [], 8 | "allowUnsafeCode": false, 9 | "overrideReferences": false, 10 | "precompiledReferences": [], 11 | "autoReferenced": true, 12 | "defineConstraints": [], 13 | "versionDefines": [], 14 | "noEngineReferences": false 15 | } -------------------------------------------------------------------------------- /Editor/CodeWriter.PackageSymlinker.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 987d96980b027104f9d32dbee358527d 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/PackageSymLinkerWindow.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Globalization; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using UnityEditor; 10 | using UnityEditor.PackageManager; 11 | using UnityEngine; 12 | using Debug = UnityEngine.Debug; 13 | 14 | namespace CodeWriter.PackageSymLinker 15 | { 16 | public class PackageSymLinkerWindow : EditorWindow, IHasCustomMenu 17 | { 18 | private const string RecentPackagesPrefsKey = "PackageSymlinker_Recent"; 19 | private const char RecentPackagesSeparator = '#'; 20 | 21 | [MenuItem("Tools/Package Symlinker")] 22 | public static void OpenWindow() 23 | { 24 | var window = GetWindow(); 25 | window.Show(); 26 | } 27 | 28 | [SerializeField] private List symLinks = new List(); 29 | [SerializeField] private Vector2 scroll; 30 | [SerializeField] private string[] recentPackagesPaths = Array.Empty(); 31 | [SerializeField] private Package[] recentPackageInfo = Array.Empty(); 32 | 33 | private void OnEnable() 34 | { 35 | ReloadLinkedPackages(); 36 | RefreshRecentPackages(); 37 | } 38 | 39 | private void OnFocus() 40 | { 41 | ReloadLinkedPackages(); 42 | RefreshRecentPackages(); 43 | } 44 | 45 | private void OnGUI() 46 | { 47 | OnToolbarGUI(); 48 | 49 | scroll = GUILayout.BeginScrollView(scroll, false, true); 50 | OnLinkedPackagesGUI(); 51 | GUILayout.Space(50); 52 | OnRecentPackagesGUI(); 53 | EditorGUILayout.EndScrollView(); 54 | } 55 | 56 | public void AddItemsToMenu(GenericMenu menu) 57 | { 58 | menu.AddItem(new GUIContent("Clear Recent"), false, ClearRecentPackages); 59 | } 60 | 61 | private void OnToolbarGUI() 62 | { 63 | GUILayout.BeginHorizontal(EditorStyles.toolbar); 64 | 65 | GUILayout.Space(5); 66 | 67 | if (GUILayout.Button("Link Package", EditorStyles.toolbarButton)) 68 | { 69 | AddPackage(); 70 | } 71 | 72 | GUILayout.FlexibleSpace(); 73 | 74 | GUILayout.EndHorizontal(); 75 | } 76 | 77 | private void OnLinkedPackagesGUI() 78 | { 79 | var labelStyle = EditorStyles.boldLabel; 80 | labelStyle.richText = true; 81 | 82 | if (symLinks.Count == 0) 83 | { 84 | GUILayout.Space(20); 85 | GUILayout.BeginHorizontal(); 86 | GUILayout.FlexibleSpace(); 87 | GUILayout.Label("No symbolic linked packages in project", EditorStyles.largeLabel); 88 | GUILayout.FlexibleSpace(); 89 | GUILayout.EndHorizontal(); 90 | GUILayout.Space(20); 91 | 92 | return; 93 | } 94 | 95 | GUILayout.Label("Linked packages", EditorStyles.largeLabel); 96 | 97 | foreach (var symLink in symLinks) 98 | { 99 | GUILayout.BeginVertical(EditorStyles.helpBox); 100 | 101 | GUILayout.BeginHorizontal(); 102 | GUILayout.Label($"{symLink.package.name} : {symLink.package.version}", labelStyle); 103 | if (GUILayout.Button("Delete link", GUILayout.Width(120))) 104 | { 105 | DeletePackage(symLink.path); 106 | } 107 | 108 | GUILayout.EndHorizontal(); 109 | 110 | GUILayout.Label(symLink.path, EditorStyles.miniLabel); 111 | 112 | GUILayout.EndVertical(); 113 | } 114 | } 115 | 116 | private void OnRecentPackagesGUI() 117 | { 118 | if (recentPackagesPaths.Length == 0) 119 | { 120 | return; 121 | } 122 | 123 | GUILayout.Label("Recent packages", EditorStyles.largeLabel); 124 | 125 | for (var index = 0; index < recentPackagesPaths.Length; index++) 126 | { 127 | var packagePath = recentPackagesPaths[index]; 128 | var package = recentPackageInfo[index]; 129 | 130 | if (string.IsNullOrEmpty(package.name)) 131 | { 132 | continue; 133 | } 134 | 135 | GUILayout.BeginVertical(EditorStyles.helpBox); 136 | 137 | GUILayout.BeginHorizontal(); 138 | GUILayout.Label($"{package.name} : {package.version}", EditorStyles.boldLabel); 139 | 140 | if (IsPackageLinked(package.name)) 141 | { 142 | GUILayout.Label("Linked", EditorStyles.centeredGreyMiniLabel, GUILayout.Width(120)); 143 | } 144 | else 145 | { 146 | if (GUILayout.Button("Link", GUILayout.Width(120))) 147 | { 148 | AddPackage(packagePath); 149 | } 150 | } 151 | 152 | GUILayout.EndHorizontal(); 153 | 154 | GUILayout.Label(packagePath, EditorStyles.miniLabel); 155 | 156 | GUILayout.EndVertical(); 157 | } 158 | } 159 | 160 | private void ReloadLinkedPackages() 161 | { 162 | var packagesFolderPath = GetPackagesFolderPath(); 163 | 164 | var dirPaths = Directory.GetDirectories(packagesFolderPath); 165 | 166 | symLinks = dirPaths 167 | .Where(path => 168 | { 169 | const FileAttributes attrs = FileAttributes.Directory | FileAttributes.ReparsePoint; 170 | var srcPackageJsonPath = Path.Combine(path, "package.json"); 171 | return (File.GetAttributes(path) & attrs) == attrs && File.Exists(srcPackageJsonPath); 172 | }) 173 | .Select(path => 174 | { 175 | var srcPackageJsonPath = Path.Combine(path, "package.json"); 176 | var packageJsonString = File.ReadAllText(srcPackageJsonPath); 177 | var packageInfo = JsonUtility.FromJson(packageJsonString); 178 | 179 | return new SymlinkedDirInfo 180 | { 181 | path = path, 182 | package = packageInfo 183 | }; 184 | }) 185 | .ToList(); 186 | 187 | if (symLinks.Count > 0) 188 | { 189 | titleContent = new GUIContent($"Package Symlinker ({symLinks.Count})"); 190 | } 191 | else 192 | { 193 | titleContent = new GUIContent($"Package Symlinker"); 194 | } 195 | } 196 | 197 | private void AddPackage() 198 | { 199 | var srcFolderPath = EditorUtility.OpenFolderPanel("Select Package", string.Empty, string.Empty); 200 | AddPackage(srcFolderPath); 201 | } 202 | 203 | private void AddPackage(string srcFolderPath) 204 | { 205 | if (string.IsNullOrEmpty(srcFolderPath)) 206 | { 207 | Debug.LogError("No folder selected"); 208 | return; 209 | } 210 | 211 | srcFolderPath = srcFolderPath.Replace('/', Path.DirectorySeparatorChar); 212 | 213 | var srcPackageJsonPath = Path.Combine(srcFolderPath, "package.json"); 214 | if (!File.Exists(srcPackageJsonPath)) 215 | { 216 | Debug.LogError("package.json file not found at " + srcPackageJsonPath); 217 | return; 218 | } 219 | 220 | var packageJsonString = File.ReadAllText(srcPackageJsonPath); 221 | var packageInfo = JsonUtility.FromJson(packageJsonString); 222 | 223 | if (string.IsNullOrEmpty(packageInfo.name)) 224 | { 225 | Debug.LogError("package.json name is null or empty"); 226 | return; 227 | } 228 | 229 | var dstPackagesFolderPath = GetPackagesFolderPath(); 230 | 231 | #if UNITY_EDITOR_WIN 232 | var dstPackagePath = Path.Combine(dstPackagesFolderPath, packageInfo.name); 233 | var command = $"mklink /j \"{dstPackagePath}\" \"{srcFolderPath}\""; 234 | #else 235 | var command = $"ln -s {srcFolderPath} {dstPackagesFolderPath}"; 236 | #endif 237 | if (TryExecuteCmd(command, out _, out var error) != 0) 238 | { 239 | //on osx return code can be not 0 240 | //double check error 241 | if(string.IsNullOrEmpty(error) == false) 242 | { 243 | Debug.LogError($"Failed to link package: {error}"); 244 | return; 245 | } 246 | } 247 | 248 | AddPackageToRecent(srcFolderPath); 249 | Client.Resolve(); 250 | AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); 251 | ReloadLinkedPackages(); 252 | } 253 | 254 | private void DeletePackage(string path) 255 | { 256 | #if UNITY_EDITOR_WIN 257 | var command = $"rd \"{path}\""; 258 | #else 259 | var command = $"unlink {path}"; 260 | #endif 261 | if (TryExecuteCmd(command, out _, out var error) != 0) 262 | { 263 | //on osx return code can be not 0 264 | //double check error 265 | if(string.IsNullOrEmpty(error) == false) 266 | { 267 | Debug.LogError($"Failed to delete package link: {error}"); 268 | return; 269 | } 270 | } 271 | 272 | AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); 273 | ReloadLinkedPackages(); 274 | } 275 | 276 | public static string GetPackagesFolderPath() 277 | { 278 | var assetsFolderPath = Application.dataPath; 279 | var projectFolderPath = assetsFolderPath.Substring(0, assetsFolderPath.Length - "/Assets".Length); 280 | var packageFolderPath = projectFolderPath + "/Packages"; 281 | return packageFolderPath.Replace('/', Path.DirectorySeparatorChar); 282 | } 283 | 284 | public static int TryExecuteCmd(string command, out string output, out string error) 285 | { 286 | #if UNITY_EDITOR_WIN 287 | var cmd = "cmd.exe"; 288 | var args = $"/c {command}"; 289 | #else 290 | var cmd = "/bin/bash"; 291 | var args = $"-c \"{command}\""; 292 | #endif 293 | var startInfo = new ProcessStartInfo 294 | { 295 | FileName = cmd, 296 | Arguments = args, 297 | CreateNoWindow = true, 298 | UseShellExecute = false, 299 | RedirectStandardError = true, 300 | RedirectStandardOutput = true, 301 | StandardOutputEncoding = Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage), 302 | StandardErrorEncoding = Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage), 303 | }; 304 | 305 | var launchProcess = Process.Start(startInfo); 306 | if (launchProcess == null || launchProcess.HasExited || launchProcess.Id == 0) 307 | { 308 | output = error = string.Empty; 309 | return int.MinValue; 310 | } 311 | 312 | var outputBuilder = new StringBuilder(); 313 | var errorBuilder = new StringBuilder(); 314 | 315 | launchProcess.OutputDataReceived += (sender, e) => outputBuilder.AppendLine(e.Data ?? ""); 316 | launchProcess.ErrorDataReceived += (sender, e) => errorBuilder.AppendLine(e.Data ?? ""); 317 | 318 | launchProcess.BeginOutputReadLine(); 319 | launchProcess.BeginErrorReadLine(); 320 | launchProcess.EnableRaisingEvents = true; 321 | 322 | launchProcess.WaitForExit(); 323 | 324 | output = outputBuilder.ToString(); 325 | error = errorBuilder.ToString(); 326 | return launchProcess.ExitCode; 327 | } 328 | 329 | private void RefreshRecentPackages() 330 | { 331 | recentPackagesPaths = EditorPrefs.GetString(RecentPackagesPrefsKey, "") 332 | .Split(RecentPackagesSeparator, StringSplitOptions.RemoveEmptyEntries); 333 | 334 | recentPackageInfo = new Package[recentPackagesPaths.Length]; 335 | 336 | for (var i = 0; i < recentPackageInfo.Length; i++) 337 | { 338 | var packageJsonPath = Path.Combine(recentPackagesPaths[i], "package.json"); 339 | if (!File.Exists(packageJsonPath)) 340 | { 341 | continue; 342 | } 343 | 344 | var packageJsonString = File.ReadAllText(packageJsonPath); 345 | var packageInfo = JsonUtility.FromJson(packageJsonString); 346 | 347 | recentPackageInfo[i] = packageInfo; 348 | } 349 | } 350 | 351 | private void AddPackageToRecent(string path) 352 | { 353 | RefreshRecentPackages(); 354 | 355 | var list = recentPackagesPaths.ToList(); 356 | list.Remove(path); 357 | list.Add(path); 358 | recentPackagesPaths = list.ToArray(); 359 | EditorPrefs.SetString(RecentPackagesPrefsKey, string.Join(RecentPackagesSeparator, recentPackagesPaths)); 360 | 361 | RefreshRecentPackages(); 362 | } 363 | 364 | private void ClearRecentPackages() 365 | { 366 | EditorPrefs.SetString(RecentPackagesPrefsKey, ""); 367 | RefreshRecentPackages(); 368 | } 369 | 370 | private bool IsPackageLinked(string packageName) 371 | { 372 | foreach (var dir in symLinks) 373 | { 374 | if (dir.package.name == packageName) 375 | { 376 | return true; 377 | } 378 | } 379 | 380 | return false; 381 | } 382 | 383 | [Serializable] 384 | private struct Package 385 | { 386 | public string name; 387 | public string version; 388 | } 389 | 390 | [Serializable] 391 | private struct SymlinkedDirInfo 392 | { 393 | public string path; 394 | public Package package; 395 | } 396 | } 397 | } 398 | #endif -------------------------------------------------------------------------------- /Editor/PackageSymLinkerWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf4811d94e8413c47b16842b8fe1f952 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Vlad Vanifatov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e1b6cc8dede74db41932ed9e148e0692 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Package Symlinker [![Github license](https://img.shields.io/github/license/codewriter-packages/Package-Symlinker.svg?style=flat-square)](#) [![GitHub package.json version](https://img.shields.io/github/package-json/v/codewriter-packages/Package-Symlinker?style=flat-square)](#) 2 | Tool for maintaining symbolic linked packages for Unity 3 | 4 | [![Package Symlinker Preview](https://user-images.githubusercontent.com/26966368/104042200-3a2b1b00-51eb-11eb-875c-9503cf2af12b.png)](#) 5 | 6 | Supported Editor Platforms: 7 | * Windows 8 | * MacOS 9 | * Linux* 10 | 11 | > Linux should work well, but has not been tested. 12 | 13 | ## About 14 | 15 | Unity allow you to develop modular code and reuse it across multiple projects using packages. 16 | This packages usually placed in separate Unity project. 17 | So you development process may be similar to the following: 18 | 1) Switch to project with your packages 19 | 2) Edit the code 20 | 3) Publish new package version to registry (github, bitbucket or your own) 21 | 4) Switch to real project 22 | 5) Update package to latest version 23 | 6) Check that in real project all work correctly 24 | 7) Repeat from step 1 if any bug found 25 | 26 | It seems that it would be much more easy to edit packages directly in a real project? 27 | 28 | **Package Symlinker is a tool that allows you in a couple of clicks create symbolic links to packages, so you can edit any package as if it were located right in the project.** 29 | 30 | With this tool your workflow can be simplified to: 31 | 1) Create a symbolic link to the package 32 | 2) Edit the package directly in real project 33 | 3) Delete symbolic link 34 | 3) Publish new package version to registry 35 | 5) Update real project to latest package version 36 | 37 | ## Install 38 | Library distributed as git package ([How to install package from git URL](https://docs.unity3d.com/Manual/upm-ui-giturl.html)) 39 |
Git URL: `https://github.com/codewriter-packages/Package-Symlinker.git` 40 | 41 | ## License 42 | 43 | Package Symlinker is [MIT licensed](./LICENSE.md). 44 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 14cbebd612ff9ea48b3428c3f6f589b0 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.codewriter.package-symlinker", 3 | "displayName": "Package Symlinker", 4 | "description": "Tool for maintaining symbolic linked packages for Unity", 5 | "version": "1.2.0", 6 | "unity": "2019.1", 7 | "license": "MIT", 8 | "author": "CodeWriter (https://github.com/orgs/codewriter-packages)", 9 | "homepage": "https://github.com/codewriter-packages/Package-Symlinker#readme", 10 | "dependencies": {} 11 | } 12 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c1f7bb9e50645bd4d8e2d1ad835a9ebf 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------