Current section

42 Versions

Jump to

Compare versions

4 files changed
+80 additions
-45 deletions
  @@ -12,6 +12,15 @@ See [Conventional Commits](Https://conventionalcommits.org) for commit guideline
12 12
13 13 <!-- changelog -->
14 14
15 + ## v1.1.0 (2026-02-11)
16 +
17 +
18 +
19 +
20 + ### Features:
21 +
22 + * include sub_rules by default instead of on selection or `:all` by Zach Daniel
23 +
15 24 ## v1.0.3 (2026-02-10)
  @@ -7,7 +7,7 @@
7 7 {<<"GitHub">>,<<"https://github.com/ash-project/usage_rules">>},
8 8 {<<"Website">>,<<"https://ash-hq.org">>}]}.
9 9 {<<"name">>,<<"usage_rules">>}.
10 - {<<"version">>,<<"1.0.3">>}.
10 + {<<"version">>,<<"1.1.0">>}.
11 11 {<<"description">>,
12 12 <<"A config-driven dev tool for Elixir projects to manage AGENTS.md files and agent skills from dependencies">>}.
13 13 {<<"elixir">>,<<"~> 1.18">>}.
  @@ -367,13 +367,12 @@ if Code.ensure_loaded?(Igniter) do
367 367 resolve_regex_usage_rules(igniter, all_deps, regex, opts, rules_acc, errors_acc)
368 368
369 369 nil ->
370 - {package_name, sub_rule, opts} = parse_spec(spec)
370 + {package_name, opts} = parse_spec(spec)
371 371
372 372 resolve_named_usage_rules(
373 373 igniter,
374 374 all_deps,
375 375 package_name,
376 - sub_rule,
377 376 opts,
378 377 rules_acc,
379 378 errors_acc
  @@ -389,15 +388,38 @@ if Code.ensure_loaded?(Igniter) do
389 388 defp extract_regex_spec(_), do: nil
390 389
391 390 defp resolve_regex_usage_rules(igniter, all_deps, regex, opts, rules_acc, errors_acc) do
391 + sub_rules_opt = opts[:sub_rules] || :all
392 +
392 393 found =
393 394 all_deps
394 395 |> Enum.filter(fn {name, _path} -> Regex.match?(regex, to_string(name)) end)
395 396 |> Enum.flat_map(fn {package_name, package_path} ->
396 - if Igniter.exists?(igniter, Path.join(package_path, "usage-rules.md")) do
397 - [{package_name, package_path, nil, opts}]
398 - else
399 - []
400 - end
397 + main =
398 + if Igniter.exists?(igniter, Path.join(package_path, "usage-rules.md")) do
399 + [{package_name, package_path, nil, opts}]
400 + else
401 + []
402 + end
403 +
404 + subs =
405 + case sub_rules_opt do
406 + :all ->
407 + find_available_sub_rules(igniter, package_path)
408 + |> Enum.map(fn sr -> {package_name, package_path, sr, opts} end)
409 +
410 + list when is_list(list) ->
411 + Enum.flat_map(list, fn sr ->
412 + sub_path = Path.join([package_path, "usage-rules", "#{sr}.md"])
413 +
414 + if Igniter.exists?(igniter, sub_path) do
415 + [{package_name, package_path, sr, opts}]
416 + else
417 + []
418 + end
419 + end)
420 + end
421 +
422 + main ++ subs
401 423 end)
402 424
403 425 {rules_acc ++ found, errors_acc}
  @@ -407,52 +429,56 @@ if Code.ensure_loaded?(Igniter) do
407 429 igniter,
408 430 all_deps,
409 431 package_name,
410 - sub_rule,
411 432 opts,
412 433 rules_acc,
413 434 errors_acc
414 435 ) do
415 436 case Enum.find(all_deps, fn {name, _path} -> name == package_name end) do
416 437 {_name, package_path} ->
417 - case sub_rule do
418 - "all" ->
419 - found =
438 + sub_rules_opt = opts[:sub_rules] || :all
439 +
440 + main =
441 + if Igniter.exists?(igniter, Path.join(package_path, "usage-rules.md")) do
442 + [{package_name, package_path, nil, opts}]
443 + else
444 + []
445 + end
446 +
447 + case sub_rules_opt do
448 + :all ->
449 + subs =
420 450 find_available_sub_rules(igniter, package_path)
421 451 |> Enum.map(fn sr -> {package_name, package_path, sr, opts} end)
422 452
453 + found = main ++ subs
454 +
423 455 if Enum.any?(found) do
424 456 {rules_acc ++ found, errors_acc}
425 457 else
426 458 {rules_acc,
427 459 errors_acc ++
428 460 [
429 - "Package :#{package_name} is a dependency but has no sub-rules in usage-rules/"
461 + "Package :#{package_name} is a dependency but does not have a usage-rules.md file or sub-rules in usage-rules/"
430 462 ]}
431 463 end
432 464
433 - nil ->
434 - if Igniter.exists?(igniter, Path.join(package_path, "usage-rules.md")) do
435 - {rules_acc ++ [{package_name, package_path, nil, opts}], errors_acc}
436 - else
437 - {rules_acc,
438 - errors_acc ++
439 - [
440 - "Package :#{package_name} is a dependency but does not have a usage-rules.md file"
441 - ]}
442 - end
465 + list when is_list(list) ->
466 + {subs, sub_errors} =
467 + Enum.reduce(list, {[], []}, fn sr, {found_acc, err_acc} ->
468 + sub_path = Path.join([package_path, "usage-rules", "#{sr}.md"])
443 469
444 - sub_rule_name ->
445 - sub_path = Path.join([package_path, "usage-rules", "#{sub_rule_name}.md"])
470 + if Igniter.exists?(igniter, sub_path) do
471 + {found_acc ++ [{package_name, package_path, sr, opts}], err_acc}
472 + else
473 + {found_acc,
474 + err_acc ++
475 + [
476 + "Package :#{package_name} does not have a usage-rules/#{sr}.md file"
477 + ]}
478 + end
479 + end)
446 480
447 - if Igniter.exists?(igniter, sub_path) do
448 - {rules_acc ++ [{package_name, package_path, sub_rule_name, opts}], errors_acc}
449 - else
450 - {rules_acc,
451 - errors_acc ++
452 - [
453 - "Package :#{package_name} does not have a usage-rules/#{sub_rule_name}.md file"
454 - ]}
455 - end
481 + {rules_acc ++ main ++ subs, errors_acc ++ sub_errors}
456 482 end
457 483
458 484 nil ->
  @@ -465,32 +491,32 @@ if Code.ensure_loaded?(Igniter) do
465 491 end
466 492
467 493 @builtin_aliases %{
468 - elixir: {:usage_rules, "elixir"},
469 - otp: {:usage_rules, "otp"}
494 + elixir: {:usage_rules, [sub_rules: ["elixir"]]},
495 + otp: {:usage_rules, [sub_rules: ["otp"]]}
470 496 }
471 497
472 498 defp parse_spec({inner, opts}) when is_list(opts) do
473 - {name, sub_rule} = parse_spec_name(inner)
474 - {name, sub_rule, opts}
499 + {name, inner_opts} = parse_spec_inner(inner)
500 + {name, Keyword.merge(inner_opts, opts)}
475 501 end
476 502
477 503 defp parse_spec(spec) do
478 - {name, sub_rule} = parse_spec_name(spec)
479 - {name, sub_rule, []}
504 + parse_spec_inner(spec)
480 505 end
481 506
482 - defp parse_spec_name(spec) do
507 + defp parse_spec_inner(spec) do
483 508 case spec do
484 509 atom when is_atom(atom) and is_map_key(@builtin_aliases, atom) ->
485 510 @builtin_aliases[atom]
486 511
487 512 atom when is_atom(atom) ->
488 - {atom, nil}
513 + {atom, []}
489 514
490 515 binary when is_binary(binary) ->
491 516 case String.split(binary, ":", parts: 2) do
492 - [pkg] -> {String.to_atom(pkg), nil}
493 - [pkg, sub] -> {String.to_atom(pkg), sub}
517 + [pkg] -> {String.to_atom(pkg), []}
518 + [pkg, "all"] -> {String.to_atom(pkg), [sub_rules: :all]}
519 + [pkg, sub] -> {String.to_atom(pkg), [sub_rules: [sub]]}
494 520 end
495 521 end
496 522 end
  @@ -5,7 +5,7 @@
5 5 defmodule UsageRules.MixProject do
6 6 use Mix.Project
7 7
8 - @version "1.0.3"
8 + @version "1.1.0"
9 9 @description """
10 10 A config-driven dev tool for Elixir projects to manage AGENTS.md files and agent skills from dependencies
11 11 """