Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions lib/mix/tasks/usage_rules.sync.ex
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ if Code.ensure_loaded?(Igniter) do
if igniter.assigns[:test_mode?] do
igniter.rewrite.sources
|> Enum.filter(fn {path, _source} ->
String.match?(path, ~r|^deps/[^/]+/usage-rules\.md$|) ||
String.match?(path, ~r|^deps/[^/]+/mix\.exs$|) ||
String.match?(path, ~r|^deps/[^/]+/usage-rules\.md$|) ||
String.match?(path, ~r|^deps/[^/]+/usage-rules/[^/]+\.md$|) ||
String.match?(path, ~r|^deps/[^/]+/usage-rules/skills/[^/]+/SKILL\.md$|) ||
String.match?(path, ~r|^deps/[^/]+/usage-rules/skills/[^/]+/.+$|)
Expand All @@ -353,14 +354,18 @@ if Code.ensure_loaded?(Igniter) do
defp get_packages_with_usage_rules(igniter, all_deps) do
Enum.filter(all_deps, fn
{_name, path} when is_binary(path) and path != "" ->
Igniter.exists?(igniter, Path.join(path, "usage-rules.md")) ||
Igniter.exists?(igniter, Path.join(path, "usage-rules"))
package_has_usage_rules?(igniter, path)

_ ->
false
end)
end

defp package_has_usage_rules?(igniter, package_path) do
Igniter.exists?(igniter, Path.join(package_path, "usage-rules.md")) ||
Enum.any?(find_available_sub_rules(igniter, package_path))
end

# -------------------------------------------------------------------
# Config resolution
# -------------------------------------------------------------------
Expand Down Expand Up @@ -801,7 +806,12 @@ if Code.ensure_loaded?(Igniter) do
custom_description = skill_opts[:description]

# Resolve which packages to include in this skill (supports atoms and regexes)
resolved_packages = expand_dep_specs(usage_rule_specs, all_deps)
resolved_packages =
usage_rule_specs
|> expand_dep_specs(all_deps)
|> Enum.filter(fn {_pkg_name, package_path, _mode} ->
package_has_usage_rules?(igniter, package_path)
end)

if Enum.any?(resolved_packages) do
generate_built_skill(
Expand Down
30 changes: 30 additions & 0 deletions test/mix/tasks/usage_rules.sync_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,36 @@ defmodule Mix.Tasks.UsageRules.SyncTest do
refute content =~ "Req"
end

test "regex build skips deps without usage rules when rendering references and search docs" do
igniter =
project_with_deps(%{
"deps/phoenix/usage-rules/ecto.md" => "# Phoenix Ecto",
"deps/phoenix/usage-rules/liveview.md" => "# Phoenix LiveView",
"deps/phoenix_ecto/mix.exs" => "defmodule PhoenixEcto.MixProject, do: nil",
"deps/phoenix_html/mix.exs" => "defmodule PhoenixHTML.MixProject, do: nil"
})
|> sync(
skills: [
location: ".claude/skills",
build: [
"phoenix-framework": [usage_rules: [:phoenix, ~r/^phoenix_/]]
]
]
)
|> assert_creates(".claude/skills/phoenix-framework/SKILL.md")
|> assert_creates(".claude/skills/phoenix-framework/references/ecto.md")
|> assert_creates(".claude/skills/phoenix-framework/references/liveview.md")

content = file_content(igniter, ".claude/skills/phoenix-framework/SKILL.md")

assert content =~ "[ecto](references/ecto.md)"
assert content =~ "[liveview](references/liveview.md)"
refute content =~ "references/phoenix_ecto.md"
refute content =~ "references/phoenix_html.md"
refute content =~ "-p phoenix_ecto"
refute content =~ "-p phoenix_html"
end

test "removes stale managed skills no longer in build list" do
stale_skill_md =
"---\nname: use-old\nmetadata:\n managed-by: usage-rules\n---\n\n<!-- usage-rules-skill-start -->\nOld skill.\n<!-- usage-rules-skill-end -->"
Expand Down
Loading