# CodeQL クエリ スイートの作成

CodeQL 分析で頻繁に使用するクエリのクエリ スイートを作成できます。

CodeQL 分析で頻繁に使用するクエリのクエリ スイートを作成できます。 詳しくは、「[CodeQL クエリ セット](/ja/code-security/concepts/code-scanning/codeql/codeql-query-suites)」をご覧ください。

> \[!NOTE]
> 注: クエリ スイートに追加するカスタム クエリは [CodeQL パック](/ja/code-security/codeql-cli/getting-started-with-the-codeql-cli/customizing-analysis-with-codeql-packs)内にあり、正しいクエリ メタデータを含んでいる必要があります。 詳しくは、「[CodeQL CLI のカスタム クエリの記述](/ja/code-security/how-tos/scan-code-for-vulnerabilities/scan-from-the-command-line/writing-and-sharing-custom-queries-for-the-codeql-cli)」をご覧ください。

## クエリ スイートに追加するクエリの場所指定

クエリ スイートを作成するときは、選びたいクエリの場所を最初に指定する必要があります。 次を使用して、1 つ以上のクエリの場所を定義できます。

* ```
          `query` 命令: CodeQL に、指定された 1 つ以上の `.ql` ファイルを検索するように指示します。
  ```

  ```yaml
  - query: <path-to-query>
  ```

  引数は、スイート定義を含む CodeQL パックを基準にした 1 つ以上のファイル パスである必要があります。

* ```
          `queries` 命令: CodeQL に、`.ql` ファイルのディレクトリを再帰的にスキャンするように指示します。
  ```

  ```yaml
  - queries: <path-to-subdirectory>
  ```

  ディレクトリのパスは、スイート定義ファイルを含む CodeQL パックのルートを基準にする必要があります。 別の CodeQL パックに対するクエリを検索するには、`from` フィールドを追加します。

  ```yaml
  - queries: <path-to-subdirectory>
    from: <ql-pack-name>
    version: ^x.y.z
  ```

  ```
            `version` フィールドは省略可能であり、この CodeQL パックの互換性のあるバージョンの範囲を指定するものです。
  ```

バージョンを指定しない場合は、パックの最新バージョンが使用されます。

* ```
          `qlpack` 命令: CodeQL に、名前付き CodeQL パックの既定のスイートでクエリを解決するように指示します。
  ```

  ```yaml
  - qlpack: <qlpack-name>
    version: ^x.y.z
  ```

  クエリ パックの既定のスイートには、そのクエリ パック内で推奨されるクエリのセットが含まれています。 すべてのクエリ パックに既定のスイートがあるわけではありません。 指定されたクエリ パックで既定のスイートが定義されていない場合、qlpack 命令はパック内のすべてのクエリに解決されます。

  ```
            `version` フィールドは省略可能であり、この CodeQL パックの互換性のあるバージョンの範囲を指定するものです。
  ```

バージョンを指定しない場合は、パックの最新バージョンが使用されます。

> \[!NOTE]
> パス名がクエリ スイート定義に表示される場合は、常にスラッシュ `/` をディレクトリ区切りとして指定する必要があります。 これにより、クエリ スイート定義がすべてのオペレーティング システムで確実に機能します。

スイート定義には少なくとも 1 つの `query`、`queries`、または `qlpack` 命令を追加する必要があります。それ以外の場合、クエリは選ばれません。 スイートにこれ以上の命令が含まれない場合は、ファイルの一覧、指定されたディレクトリ、または名前付き CodeQL パックで見つかったすべてのクエリが選ばれます。 さらにフィルター処理命令がある場合は、それらの命令によって課される制約に一致するクエリのみが選ばれます。

## クエリ スイートでのクエリのフィルター処理

```
          `query`、`queries`、または `qlpack` 命令を指定してスイートに追加するクエリの初期セットを定義した後、`include` と `exclude` の命令を追加できます。 次の命令では、特定のプロパティに基づいて選択条件が定義されます。
```

* クエリのセットに対して `include` 命令を実行すると、条件に一致するすべてのクエリが選択に保持され、一致しないクエリは削除されます。
* クエリのセットに対して `exclude` 命令を実行すると、条件に一致するすべてのクエリが選択から削除され、一致しないクエリは保持されます。

フィルター命令の順序は重要です。 命令の場所指定後に表示される最初のフィルター命令によって、既定でクエリを含めるか除外するかが決まります。 最初のフィルターが `include`、最初に場所指定されたクエリは、明示的な `include` フィルターと一致する場合にのみスイートの一部になります。 最初のフィルターが `exclude`、最初に場所指定されたクエリは、明示的に除外されている場合にのみスイートの一部になります。

後続の命令は順番に実行され、ファイル内で後にある命令の方が前にある命令よりも優先されます。 そのため、`include` 命令は、同じクエリに一致する後の `exclude` 命令によってオーバーライドできます。 同様に、`exclude` は後の `include`によってオーバーライドできます。

どちらの命令でも、引数は制約ブロックです。つまり、制約を表す YAML マップです。 各制約はマップ エントリであり、この場合のキーは通常、クエリ メタデータ プロパティです。 次の値が考えられます。

* 1 つの文字列。
* ```
          `/` で囲まれた[正規表現](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html)。
  ```
* 文字列、正規表現、またはその両方を含むリスト。

制約に一致させるには、メタデータ値が文字列または正規表現のいずれかに一致する必要があります。 複数のメタデータ キーがある場合は、各キーを一致させる必要があります。
照合に使用できる標準メタデータ キーは `description`、`id`、`kind`、`name`、`tags`、`precision`、および `problem.severity` です。
クエリ メタデータ プロパティについて詳しくは、「[CodeQL クエリのメタデータ](https://codeql.github.com/docs/writing-codeql-queries/metadata-for-codeql-queries/#metadata-for-codeql-queries)」を参照してください。

メタデータ タグに加えて、制約ブロック内のキーは次の場合もあります。

* ```
          `query filename`: クエリ ファイル名の最後のパス コンポーネントと一致します。
  ```
* ```
          `query path`: 外側の CodeQL からの相対パスで、クエリ ファイルのパスと一致します。
  ```
* ```
          `tags contain`: 指定された照合文字列の 1 つが、`@tags` メタデータ プロパティの値のスペース区切りコンポーネントのいずれかに一致する必要があります。
  ```
* ```
          `tags contain all`: 指定されたそれぞれの照合文字列が、`@tags` メタデータ プロパティのコンポーネントのいずれかに一致する必要があります。
  ```

### 実行するクエリのフィルター処理の例

一般的なユース ケースは、ユーザーが実行したくない特定のクエリを除き、CodeQL パックですべてのクエリを実行するクエリ スイートを作成することです。 一般的には、クエリごとに一意で安定した識別子であるクエリ `id` でフィルター処理することをお勧めします。 次の 3 つのクエリ スイート定義は、意味的に同一であり、クエリ `id` でフィルター処理されます。

このフィルターは、除外された識別子を持つ 2 つのクエリを除き、`codeql/cpp-queries` の既定のスイート内のすべてのクエリと一致します。

```yaml
- qlpack: codeql/cpp-queries
- exclude:
    id:
      - cpp/cleartext-transmission
      - cpp/cleartext-storage-file
```

この例では、クエリごとに個別の `exclude` 命令が使用されます。

```yaml
- qlpack: codeql/cpp-queries
- exclude:
    id: cpp/cleartext-transmission
- exclude:
    id: cpp/cleartext-storage-file
```

この例では、正規表現によって同じ 2 つのクエリが除外されます。 また、`cpp/cleartext-` で始まる識別子を持つスイートに追加される今後のクエリも除外されます。

```yaml
- qlpack: codeql/cpp-queries
- exclude:
    id:
      - /^cpp\/cleartext-.*/
```

```
          `codeql/cpp-queries` CodeQL パックの既定のスイート内のすべてのクエリを選び、セキュリティ クエリのみを含むように絞り込むスイートを定義するには、次を使用します。
```

```yaml
- qlpack: codeql/cpp-queries
- include:
    tags contain: security
```

```
          `@kind problem` ディレクトリから `@precision high` と `my-custom-queries` のすべてのクエリが選ばれるスイートを定義するには、次を使用します。
```

```yaml
- queries: my-custom-queries
- include:
    kind: problem
    precision: very-high
```

次のクエリ スイート定義は、上記の定義とは異なる動作をします。 この定義では、`@kind problem`\_ または\_`@precision very-high` であるクエリを選択します。

```yaml
- queries: my-custom-queries
- include:
    kind: problem
- include:
    precision: very-high
```

```
          `@kind problem` を含むものを除き、`my-custom-queries` ディレクトリから `@problem.severity
```

recommendation\` のすべてのクエリが選ばれるスイートを作成するには、次を使用します。

```yaml
- queries: my-custom-queries
- include:
    kind: problem
- exclude:
    problem.severity: recommendation
```

```
          `@tag security` CodeQL パックから `@precision high` と `very-high` または `codeql/cpp-queries` のすべてのクエリが選ばれるスイートを作成するには、次を使用します。
```

```yaml
- queries: .
  from: codeql/cpp-queries
- include:
    tags contain: security
    precision:
    - high
    - very-high
```

> \[!NOTE]

```
          `codeql resolve queries /path/to/suite.qls` コマンドを使用すると、クエリ スイート定義で選ばれているクエリを確認できます。 詳しくは、「[AUTOTITLE](/code-security/codeql-cli/codeql-cli-manual/resolve-queries)」をご覧ください。
```

## 既存のクエリ スイート定義の再利用

既存のクエリ スイート定義は、次を指定することで再利用できます。

* ```
          `import` 命令: 以前に定義した `.qls` ファイルによって選ばれたクエリを現在のスイートに追加します。
  ```

  ```yaml
  - import: <path-to-query-suite>
  ```

  インポートされたスイートのパスは、現在のスイート定義を含む CodeQL パックを基準にする必要があります。 インポートされたクエリ スイートが別の QL パックにある場合は、次を使用できます。

  ```yaml
  - import: <path-to-query-suite>
    from: <ql-pack>
    version: ^x.y.z
  ```

  ```
            `version` フィールドは省略可能であり、この CodeQL パックの互換性のあるバージョンの範囲を指定するものです。
  ```

バージョンを指定しない場合は、パックの最新バージョンが使用されます。

```
            `import` 命令を使用して追加されたクエリは、後続の `exclude` 命令を使用してフィルター処理できます。
```

\*
`apply` 命令: 以前に定義した `.qls` ファイルのすべての命令を現在のスイートに追加します。 適用された `.qls` ファイル内の命令が、`apply` の代わりに表示されたかのようにして実行されます。
適用されたスイートの `include` と `exclude` の命令は、以前の命令によって追加されたクエリにも作用します。

```yaml
- apply: <path-to-query-suite>
```

```
            `apply` 命令を使用して、`.yml` ファイルに保存された一連の再利用可能な条件を複数のクエリ定義に適用することもできます。 詳しくは、下記の[例](#reusability-examples)をご覧ください。
```

### 再利用性の例

複数のクエリ スイート定義で同じ条件を使用するには、命令を含む別の `.yml` ファイルを作成します。 たとえば、`reusable-instructions.yml` という名前のファイルに次を保存します。

```yaml
- include:
    kind:
    - problem
    - path-problem
    tags contain: security
    precision:
    - high
    - very-high
```

現在のクエリ スイートと同じ CodeQL パックに `reusable-instructions.yml` を追加します。 次に、1 つ以上のクエリ スイートで、`apply` 命令を使用して、再利用可能な命令を現在のスイートに適用します。 例えば次が挙げられます。

```yaml
- queries: queries/cpp/custom
- apply: reusable-instructions.yml
```

これにより、`queries/cpp/custom` のクエリがフィルター処理され、再利用可能な条件に一致するもののみが含まれるようになります。

別の CodeQL パックのクエリで `reusable-instructions.yml` を使用してスイート定義を作成することもできます。
`.qls` ファイルがクエリと同じ CodeQL パックにある場合は、`from` 命令の直後に `apply` フィールドを追加できます。

```yaml
# load queries from the default suite of my-org/my-other-custom-queries
- qlpack: my-org/my-other-custom-queries

# apply the reusable instructions from the my-org/my-custom-instructions CodeQL pack
- apply: reusable-instructions.yml
  from: my-org/my-custom-instructions
  version: ^1.2.3 # optional
```

```
          `import` 命令の一般的なユース ケースは、別のクエリ スイートのクエリにさらにフィルターを適用することです。 たとえば、このスイートでは、`cpp-security-and-quality` スイートをさらにフィルター処理し、`low` と `medium` の有効桁数クエリが除外されます。
```

```yaml
- import: codeql-suites/cpp-security-and-quality.qls
  from: codeql/cpp-queries
- exclude:
    precision:
      - low
      - medium
```

別のスイートからインポートされたクエリを `include` する場合、構文は少し異なります。

```yaml
- import: codeql-suites/cpp-security-and-quality.qls
  from: codeql/cpp-queries
- exclude: {}
- include:
    precision:
      - very-high
      - high
```

空の `exclude` 命令に注目してください。 これは、後続の `include` 命令がインポートされたスイートからのクエリをフィルター処理できるようにするために必要です。

## クエリ スイートの名前付け

クエリ スイートの名前を指定するには、`description` 命令を指定します。

```yaml
- description: <name-of-query-suite>
```

## クエリ スイートの保存

```
          `.qls` 拡張子が付いたファイルにクエリ スイートを保存し、CodeQL パックに追加します。 詳しくは、「[AUTOTITLE](/code-security/codeql-cli/getting-started-with-the-codeql-cli/customizing-analysis-with-codeql-packs#custom-codeql-packs)」をご覧ください。
```

## CodeQL でのクエリ スイートの使用

```
          `.qls` ファイルを受け入れるコマンドに対して、コマンド ラインでクエリ スイートを指定できます。 たとえば、`query compile` を使用してスイート定義によって選ばれたクエリをコンパイルしたり、`database analyze` を使用して分析でクエリを使用したりできます。 CodeQL データベースを分析する方法について詳しくは、「[AUTOTITLE](/code-security/codeql-cli/getting-started-with-the-codeql-cli/analyzing-your-code-with-codeql-queries)」を参照してください。
```

## 詳細については、次を参照してください。

* ```
          [CodeQL クエリ](https://codeql.github.com/docs/writing-codeql-queries/codeql-queries/#codeql-queries)
  ```