mkdir testrepo
cd testrepo
exec git init --initial-branch=main .

cp ../src/v1.yml rules.yml
cp ../src/.pint.hcl .
env GIT_AUTHOR_NAME=pint
env GIT_AUTHOR_EMAIL=pint@example.com
env GIT_COMMITTER_NAME=pint
env GIT_COMMITTER_EMAIL=pint@example.com
exec git add .
exec git commit -am 'import rules and config'

exec git checkout -b v2
cp ../src/v2.yml rules.yml
exec git commit -am 'v2'

! exec pint -l debug --offline --no-color ci --json=report.json
! stdout .
cmp report.json ../expected.json

-- src/v1.yml --
- alert: rule1
  expr: sum(foo) by(job)
- alert: rule2
  expr: sum(foo) by(job)
  for: 0s

-- src/v2.yml --
- alert: rule1
  expr: sum(foo) by(job)
  for: 0s
- alert: rule2
  expr: sum(foo) by(job)
  for: 0s
- record: colo_job:fl_cf_html_bytes_in:rate10m
  expr: sum(rate(fl_cf_html_bytes_in[10m])) WITHOUT (colo_id, instance, node_type, region, node_status, job, colo_name)
- record: colo_job:foo:rate1m
  expr: sum(rate(foo[1m])) WITHOUT (instance)
- record: colo_job:foo:irate3m
  expr: sum(irate(foo[3m])) WITHOUT (colo_id)

- record: colo_job:down:count
  expr: up{job=~"foo"} == 0

- record: colo_job:down:count
  expr: up{job!~"foo"} == 0

# pint ignore/begin
{%- set foo = 1 %}
{% set bar = 2 -%}
{# comment #}
{#
  comment 
#}
# pint ignore/end

- record: colo_job:up:count
  expr: sum(foo) without(job)

- record: invalid
  expr: sum(foo) by ())

# pint ignore/begin
- record: colo_job:down:count
  expr: up == {{ foo }}
# pint ignore/end

- record: colo:multiline
  expr: |
    sum(
      multiline
    ) without(job, instance)

- record: colo:multiline:sum
  expr: |
    sum(sum) without(job)
    +
    sum(sum) without(job)

- record: colo:multiline2
  expr: >-
    sum(
      multiline2
    ) without(job, instance)

- record: colo_job:up:byinstance
  expr: sum(byinstance) by(instance)

- record: instance_mode:node_cpu:rate4m
  expr:  sum(rate(node_cpu_seconds_total[4m])) without (cpu)

- record: instance_mode:node_cpu:rate4m
  expr:  sum(rate(node_cpu_seconds_total[5m])) without (cpu)

- record: instance_mode:node_cpu:rate5min
  expr:  sum(irate(node_cpu_seconds_total[5m])) without (cpu)

- alert: Instance Is Down
  expr: up == 0

- alert: Error Rate
  expr: sum(rate(errors[5m])) > 0.5

- alert: Error Rate
  expr: sum(rate(errors[5m])) > 0.5
  annotations:
    link: http://docs
    summary: 'error rate: {{ $value }}'

-- src/.pint.hcl --
ci {
  baseBranch = "main"
}
parser {
  relaxed = [".*"]
}
rule {
    match {
      kind = "recording"
    }
    aggregate ".+" {
        keep = [ "job" ]
    }
    aggregate "colo(?:_.+)?:.+" {
        strip = [ "instance" ]
    }
}


-- expected.json --
[
  {
    "path": "rules.yml",
    "reporter": "alerts/comparison",
    "problem": "always firing alert",
    "details": "Prometheus alerting rules will trigger an alert for each query that returns *any* result.\nUnless you do want an alert to always fire you should write your query in a way that returns results only when some condition is met.\nIn most cases this can be achieved by having some condition in the query expression.\nFor example `up == 0` or `rate(error_total[2m]) \u003e 0`.\nBe careful as some PromQL operations will cause the query to always return the results, for example using the [bool modifier](https://prometheus.io/docs/prometheus/latest/querying/operators/#comparison-binary-operators).",
    "severity": "Warning",
    "lines": [
      2
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "alerts/for",
    "problem": "redundant field with default value",
    "severity": "Information",
    "lines": [
      3
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "required label is being removed via aggregation",
    "severity": "Warning",
    "lines": [
      8
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "label must be removed in aggregations",
    "severity": "Warning",
    "lines": [
      12
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/regexp",
    "problem": "redundant regexp",
    "details": "See [Prometheus documentation](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors) for details on how vector selectors work.",
    "severity": "Warning",
    "lines": [
      15
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/regexp",
    "problem": "redundant regexp",
    "details": "See [Prometheus documentation](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors) for details on how vector selectors work.",
    "severity": "Warning",
    "lines": [
      18
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "label must be removed in aggregations",
    "severity": "Warning",
    "lines": [
      30
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "required label is being removed via aggregation",
    "severity": "Warning",
    "lines": [
      30
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/syntax",
    "problem": "PromQL syntax error",
    "details": "[Click here](https://prometheus.io/docs/prometheus/latest/querying/basics/) for PromQL documentation.",
    "severity": "Fatal",
    "lines": [
      33
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "required label is being removed via aggregation",
    "severity": "Warning",
    "lines": [
      42,
      43,
      44
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "label must be removed in aggregations",
    "severity": "Warning",
    "lines": [
      48,
      49,
      50
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "required label is being removed via aggregation",
    "severity": "Warning",
    "lines": [
      48,
      49,
      50
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "required label is being removed via aggregation",
    "severity": "Warning",
    "lines": [
      54,
      55,
      56
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "label must be removed in aggregations",
    "severity": "Warning",
    "lines": [
      59
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "promql/aggregate",
    "problem": "required label is being removed via aggregation",
    "severity": "Warning",
    "lines": [
      59
    ]
  },
  {
    "path": "rules.yml",
    "reporter": "alerts/template",
    "problem": "use humanize filters for the results",
    "details": "[Click here](https://prometheus.io/docs/prometheus/latest/configuration/template_reference/) for a full list of all available template functions.",
    "severity": "Information",
    "lines": [
      77,
      78,
      79,
      80
    ]
  }
]
