(快速參考)

6 應用程式設定檔

版本 4.1.3

6 應用程式設定檔

當您使用 create-app 指令建立 Grails 應用程式時,預設會使用「web」設定檔

grails create-app myapp

您可以使用 profile 參數指定不同的設定檔

grails create-app myapp --profile=rest-api

設定檔封裝了專為特定設定檔設計的專案指令、範本和外掛程式。設定檔的原始碼可以在 Github 上找到,而設定檔本身則以 JAR 檔案的形式發布到 Grails 中央儲存庫。

若要找出有哪些設定檔可用,請使用 list-profiles 指令

$ grails list-profiles

若要取得特定設定檔的詳細資訊,請使用 profile-info 指令

$ grails profile-info rest-api
當您在 grails 專案中呼叫 Grails CLI 時,profile-infolist-profiles 等指令將不可用。

設定檔儲存庫

預設情況下,Grails 會從 Grails 中央儲存庫 解析設定檔。不過,您可以透過在 USER_HOME/.grails/settings.groovy 檔案中指定儲存庫來覆寫將搜尋哪些儲存庫。

如果您希望除了 Grails 中央儲存庫之外,還使用自訂儲存庫解析設定檔,則也必須在檔案中指定 Grails 中央儲存庫

grails {
  profiles {
    repositories {
      myRepo {
        url = "http://foo.com/repo"
        snapshotsEnabled = true
      }
      grailsCentral {
        url = "https://repo.grails.org/grails/core"
        snapshotsEnabled = true
      }
    }
  }
}
Grails 使用 Aether 解析設定檔,因為在執行 create-app 指令時,Gradle 執行個體尚未可用。這表示您也可以在 USER_HOME/.m2/settings.xml 檔案中定義儲存庫和更進階的設定(代理伺服器、驗證等),如果您願意。

也可以將設定檔儲存庫的簡單憑證直接儲存在 USER_HOME/.grails/settings.groovy 檔案中。

grails {
  profiles {
    repositories {
      myRepo {
        url = "http://foo.com/repo"
        snapshotsEnabled = true
        username = "user"
        password = "pass"
      }
      ...
    }
  }
}

預設設定檔

要建立使用自訂設定檔的應用程式,您必須指定完整的成品。

$ grails create-app myapp --profile=com.mycompany.grails.profiles:myprofile:1.0.0

為了簡化此程序,您可以在 USER_HOME/.grails/settings.groovy 檔案中定義特定設定檔的預設值。

grails {
  profiles {
    myprofile {
      groupId = "com.mycompany.grails.profiles"
      version = "1.0.0"
    }
    repositories {
      ...
    }
  }
}

指定預設值後,使用該設定檔建立應用程式的指令會變成

$ grails create-app myapp --profile=myprofile

6.1 建立設定檔

建立新設定檔的構想是,您可以設定一組預設指令和外掛程式,這些指令和外掛程式針對特定技術或組織量身打造。

若要建立新設定檔,您可以使用 create-profile 指令,它會建立一個新的空設定檔,延伸基本設定檔

$ grails create-profile mycompany

上述指令會在執行指令的「mycompany」目錄中建立一個新設定檔。如果您在目錄中啟動互動模式,您會取得一組用於建立設定檔的指令

$ cd mycompany
$ grails
| Enter a command name to run. Use TAB for completion:
grails>

create-command      create-creator-command      create-feature      create-generator-command    create-gradle-command   create-template

指令如下

  • create-command - 建立一個新指令,當使用設定檔時,這個指令會在 Grails CLI 中提供

  • create-creator-command - 建立一個指令,這個指令可在 CLI 中使用,用於呈現範本(範例:create-controller)

  • create-generator-command - 建立一個指令,這個指令可在 CLI 中使用,用於根據網域類別呈現範本(範例:generate-controller)

  • create-feature - 建立一個可用於此設定檔的功能

  • create-gradle-command - 建立一個 CLI 指令,這個指令可以呼叫 gradle

  • create-template - 建立一個範本,這個範本可以由指令呈現

若要自訂設定檔的相依性,您可以在 profile.yml 中指定其他相依性。

以下是 profile.yml 檔案範例

features:
    defaults:
        - hibernate
        - asset-pipeline
build:
    plugins:
        - org.grails.grails-web
    excludes:
        - org.grails.grails-core
dependencies:
    compile:
        - "org.mycompany:myplugin:1.0.1"

有了上述設定,您可以使用 gradle install 將設定檔發佈到您的本機儲存庫。

$ gradle install

您的設定檔現在可以使用 create-app 指令。

$ grails create-app myapp --profile mycompany

使用上述指令,應用程式會使用「mycompany」設定檔建立,其中包含對「myplugin」外掛程式的其他相依性,也包含「hibernate」和「asset-pipeline」功能(稍後會詳細說明功能)。

請注意,如果您自訂設定檔的相依性座標(群組、版本等),您可能需要使用完全限定座標來建立應用程式

$ grails create-app myapp --profile com.mycompany:mycompany:1.0.1

6.2 設定檔繼承

一個設定檔可以延伸一個或多個不同的父設定檔。若要定義設定檔繼承,您可以修改設定檔的 build.gradle 並定義設定檔相依性。例如,您通常會想要延伸 base 設定檔

dependencies {
    runtime "org.grails.profiles:base:$baseProfileVersion"
}

透過繼承父層設定檔,您可以獲得下列好處

  • 執行 create-app 指令時,會先複製父層設定檔的結構

  • 相依項和 build.gradle 會從父層合併

  • application.yml 檔案會從父層合併

  • 會繼承父層設定檔的 CLI 指令

  • 會繼承父層設定檔的功能

若要定義繼承順序,請確定您的相依項已宣告在正確的順序中。例如

dependencies {
    runtime "org.grails.profiles:plugin:$baseProfileVersion"
    runtime "org.grails.profiles:web:$baseProfileVersion"
}

在上述程式片段中,會先複製 "plugin" 設定檔的結構,接著再複製 "web" 設定檔。此外,"web" 設定檔會覆寫 "plugin" 設定檔的指令,而如果相依項順序相反,則 "plugin" 設定檔會覆寫 "web" 設定檔。

6.3 發佈設定檔

將設定檔發佈至 Grails 中央儲存庫

使用 create-profile 指令建立的任何設定檔,都已設定好 build.gradle 中定義的 grails-profile-publish 外掛

apply plugin: "org.grails.grails-profile-publish"

若要使用此外掛將設定檔發佈至 Grails 中央儲存庫,請先將原始程式碼上傳至 Github(不接受封閉原始碼設定檔)。然後在 Bintray 上註冊帳戶,並在設定檔的 build.gradle 檔案中設定金鑰,如下所示

grailsPublish {
  user = 'YOUR USERNAME'
  key = 'YOUR KEY'
  githubSlug = 'your-repo/your-profile'
  license = 'Apache-2.0'
}
githubSlug 參數應指向您的 Github 儲存庫路徑。例如,如果您的儲存庫位於 https://github.com/foo/bar,則您的 githubSlugfoo/bar

設定好後,您可以執行 gradle publishProfile 來發佈您的設定檔

$ gradle publishProfile

設定檔會上傳至 Bintray。然後,您可以前往 Grails 設定檔儲存庫,並按一下 Bintray 介面上的「包含我的套件」按鈕,要求將您的設定檔包含在內(您必須登入才能看到此按鈕)。

將設定檔發佈至內部儲存庫

上述 grails-profile-publish 外掛會設定 Gradle 的 Maven Publish 外掛。若要發佈至內部儲存庫,您只需在 build.gradle 中定義儲存庫即可。例如

publishing {
    repositories {
        maven {
            credentials {
                username "foo"
                password "bar"
            }

            url "http://foo.com/repo"
        }
    }
}

設定好後,您可以使用 gradle publish 來發佈您的外掛

$ gradle publish

6.4 瞭解設定檔

設定檔是一個簡單的目錄,其中包含 profile.yml 檔案,以及包含設定檔定義的「指令」、「結構」和「範本」的目錄。範例

/web
    commands/
        create-controller.yml
        run-app.groovy
        ...
    features/
        asset-pipeline/
            skeleton
            feature.yml
    skeleton/
        grails-app/
            controllers/
            ...
        build.gradle
    templates/
        artifacts/
            Controller.groovy
    profile.yml

上述範例是「web」設定檔結構的程式片段。profile.yml 檔案用於描述設定檔,並控制建置的設定方式。

了解 profile.yml 描述符

profile.yml 可以包含以下子元素。

1) repositories

要包含在已生成組建中的 Maven 儲存庫清單。範例

repositories:
    - "https://repo.grails.org/grails/core"

2) build.repositories

要包含在已生成組建的 buildscript 區段中的 Maven 儲存庫清單。範例

build:
    repositories:
        - "https://repo.grails.org/grails/core"

3) build.plugins

要設定在已生成組建中的 Gradle 外掛清單。範例

build:
    plugins:
        - eclipse
        - idea
        - org.grails.grails-core

4) build.excludes

要排除從父設定檔繼承的 Gradle 外掛清單

build:
    excludes:
        - org.grails.grails-core

5) dependencies

要設定的範圍和相依性的對應。excludes 範圍可用於從父設定檔中排除。範例

dependencies:
    excludes:
        - "org.grails:hibernate:*"
    build:
        - "org.grails:grails-gradle-plugin:$grailsVersion"
    compile:
        - "org.springframework.boot:spring-boot-starter-logging"
        - "org.springframework.boot:spring-boot-autoconfigure"

6) features.defaults

如果沒有指定明確功能,要使用的預設功能清單。

features:
    defaults:
        - hibernate
        - asset-pipeline

7) skeleton.excludes

要從父設定檔的 skeleton 中排除的檔案清單(支援萬用字元)。

skeleton:
    excludes:
        - gradlew
        - gradlew.bat
        - gradle/

8) skeleton.parent.target

父設定檔的 skeleton 應複製到的目標資料夾。這可用於建立多專案組建。

skeleton:
    parent:
        target: app

9) skeleton.binaryExtensions

哪些檔案副檔名應從設定檔複製為二進位檔案。從父設定檔繼承和合併。

skeleton:
    binaryExtensions: [exe, zip]

10) skeleton.executable

在產生的應用程式中應標記為可執行的檔案模式。從父設定檔繼承和合併。這些模式使用 Ant 剖析。

skeleton:
    executable:
      - "**/gradlew*"
      - "**/grailsw*"

11) instructions

在建立應用程式後要顯示給使用者的文字

instructions: Here are some instructions

什麼時候會使用設定檔?

create-app 指令執行時,它會取得父設定檔的 skeleton,並將 skeleton 複製到新的專案結構中。

build.gradle 檔案的產生是取得 profile.yml 檔案中定義的所有相依性資訊,並產生所需的相依性。

此指令也會合併設定檔及其父設定檔中定義的任何 build.gradle 檔案。

grails-app/conf/application.yml 檔案也會合併成單一的 YAML 檔案,考量設定檔和所有父設定檔。

6.5 建立設定檔指令

設定檔可以使用 YAML 或 Groovy 腳本定義僅套用於該設定檔的新指令。以下是 YAML 中定義的 create-controller 指令範例

description:
    - Creates a controller
    - usage: 'create-controller <<controller name>>'
    - completer: org.grails.cli.interactive.completers.DomainClassCompleter
    - argument: "Controller Name"
      description: "The name of the controller"
steps:
 - command: render
   template: templates/artifacts/Controller.groovy
   destination: grails-app/controllers/`artifact.package.path`/`artifact.name`Controller.groovy
 - command: render
   template: templates/testing/Controller.groovy
   destination: src/test/groovy/`artifact.package.path`/`artifact.name`ControllerSpec.groovy
 - command: mkdir
   location: grails-app/views/`artifact.propertyName`

在 YAML 中定義的指令必須定義一個或多個步驟。每個步驟本身都是一個指令。可用的步驟類型為

  • render - 將範本呈現在給定的目的地(如前一個範例所示)

  • mkdir - 建立由 location 參數指定的目錄

  • execute - 執行由 class 參數指定的指令。必須是實作 Command 介面的類別。

  • gradle - 執行 tasks 參數指定的一個或多個 Gradle 任務。

例如,若要呼叫 Gradle 任務,您可以定義下列 YAML

description: Creates a WAR file for deployment to a container (like Tomcat)
minArguments: 0
usage: |
 war
steps:
 - command: gradle
   tasks:
     - war

如果您需要比宣告式 YAML 方法提供的更靈活的彈性,您可以建立 Groovy 程式碼指令。每個指令程式碼都從 GroovyScriptCommand 類別延伸,因此具有該類別所有可用的方法。

以下是使用 Groovy 編寫的 create-script 指令範例

description( "Creates a Grails script" ) {
  usage "grails create-script <<SCRIPT NAME>>"
  argument name:'Script Name', description:"The name of the script to create"
  flag name:'force', description:"Whether to overwrite existing files"
}

def scriptName = args[0]
def model = model(scriptName)
def overwrite = flag('force') ? true : false

render  template: template('artifacts/Script.groovy'),
        destination: file("src/main/scripts/${model.lowerCaseName}.groovy"),
        model: model,
        overwrite: overwrite

有關建立 CLI 指令的更多資訊,請參閱使用者指南「指令列」區段中的 建立自訂程式碼

6.6 建立設定檔功能

設定檔功能是一組可跨多個設定檔共用的範本和依賴項。通常您會建立一個具有多個功能的基本設定檔,以及從父設定檔繼承並因此可以使用父設定檔中可用功能的子設定檔。

若要建立功能,請從設定檔的根目錄使用 create-feature 指令

$ grails create-feature myfeature

這將建立一個 myfeature/feature.yml 檔案,如下所示

description: Description of the feature
# customize versions here
# dependencies:
#   compile:
#     - "org.grails.plugins:myplugin2:1.0"
#

更具體的範例。以下是「asset-pipeline」功能的 feature.yml 檔案

description: Adds Asset Pipeline to a Grails project
build:
    plugins:
        - asset-pipeline
dependencies:
    build:
        - 'com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0'
    runtime:
        - "org.grails.plugins:asset-pipeline"

功能的結構如下

FEATURE_DIR
    feature.yml
    skeleton/
        grails-app/
            conf/
                application.yml
        build.gradle

骨架的內容會複製到應用程式樹狀結構中,而 application.ymlbuild.gradle 會與設定檔中各自的對應項目合併使用。

使用 feature.yml,您可以定義其他依賴項。這讓使用者可以建立具有選用功能的應用程式。例如

$ grails create-app myapp --profile myprofile --features myfeature,hibernate

上述範例將使用您的新功能和「hibernate」功能建立新的應用程式。