Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
875dfba1b2 | ||
|
|
e960dd9da8 |
@@ -103,6 +103,7 @@ A detail that is set is used and not asked; the summary marks it with
|
|||||||
| `GITHUB_OWNER` | GitHub user or organization | letters, digits, `-`; used only when GitHub is used |
|
| `GITHUB_OWNER` | GitHub user or organization | letters, digits, `-`; used only when GitHub is used |
|
||||||
| `PROJECT_DIRECTORY` | local directory | not empty, not starting with `-` |
|
| `PROJECT_DIRECTORY` | local directory | not empty, not starting with `-` |
|
||||||
| `ENABLE_PLAN_GATE` | enable the plan gate | `yes` or `no` |
|
| `ENABLE_PLAN_GATE` | enable the plan gate | `yes` or `no` |
|
||||||
|
| `PROJECT_LICENSE` | license of the project | a Gitea license key (letters, digits, `.`, `+`, `-`; at most 64), such as `AGPL-3.0` or `MIT`, or `none` |
|
||||||
|
|
||||||
- A key that is present counts as set, even when its value is empty. Only
|
- A key that is present counts as set, even when its value is empty. Only
|
||||||
`PROJECT_DESCRIPTION` may be empty (no description); an empty value for any
|
`PROJECT_DESCRIPTION` may be empty (no description); an empty value for any
|
||||||
@@ -111,7 +112,12 @@ A detail that is set is used and not asked; the summary marks it with
|
|||||||
key. The script never falls back to asking for it.
|
key. The script never falls back to asking for it.
|
||||||
- `USE_GITHUB=no` skips the GitHub owner and every GitHub step; a
|
- `USE_GITHUB=no` skips the GitHub owner and every GitHub step; a
|
||||||
`GITHUB_OWNER` set at the same time is ignored, with a warning.
|
`GITHUB_OWNER` set at the same time is ignored, with a warning.
|
||||||
- Only these eight details can be set. The confirmations stay questions that
|
- `PROJECT_LICENSE` is never asked. When set, that license is put on the Gitea
|
||||||
|
repository with or without GitHub, and `none` means no license. When absent,
|
||||||
|
AGPL-3.0 is applied only if GitHub is used **and** the project is public;
|
||||||
|
a private project, or one without GitHub, gets no license. The Gitea server
|
||||||
|
must offer the license, or the run stops before anything is created.
|
||||||
|
- Only these nine details can be set. The confirmations stay questions that
|
||||||
default to no: create now, reusing an existing repository, an existing
|
default to no: create now, reusing an existing repository, an existing
|
||||||
directory, `core.hooksPath` and replacing a template file.
|
directory, `core.hooksPath` and replacing a template file.
|
||||||
- These keys are accepted in `config.env` only, never in `.env`.
|
- These keys are accepted in `config.env` only, never in `.env`.
|
||||||
@@ -119,7 +125,7 @@ A detail that is set is used and not asked; the summary marks it with
|
|||||||
value there. Put a description that contains ` #` in double quotes, for
|
value there. Put a description that contains ` #` in double quotes, for
|
||||||
example `PROJECT_DESCRIPTION="Tool for #mirrors"`.
|
example `PROJECT_DESCRIPTION="Tool for #mirrors"`.
|
||||||
|
|
||||||
With all eight set, a run asks only the confirmations:
|
With all of them set, a run asks only the confirmations:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
src/create-project.sh --apply # asks only "Create these now (y/n) [n]"
|
src/create-project.sh --apply # asks only "Create these now (y/n) [n]"
|
||||||
@@ -153,8 +159,8 @@ with read-only requests and prints a plan:
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
Plan:
|
Plan:
|
||||||
Gitea repository : create (private) with the AGPL-3.0 license https://git.example.org/Team/my-app
|
Gitea repository : create (public) with the AGPL-3.0 license (default: GitHub and a public project) https://git.example.org/Team/my-app
|
||||||
GitHub repository : create (private), empty https://github.com/acme/my-app
|
GitHub repository : create (public), empty https://github.com/acme/my-app
|
||||||
Push mirror : Gitea -> GitHub every 10m0s
|
Push mirror : Gitea -> GitHub every 10m0s
|
||||||
Local project : create ./my-app (new directory), git on main, no commit
|
Local project : create ./my-app (new directory), git on main, no commit
|
||||||
Local origin : will use SSH (the SSH test passed)
|
Local origin : will use SSH (the SSH test passed)
|
||||||
@@ -167,7 +173,7 @@ Without `--apply` that is all that happens. With `--apply` the script asks
|
|||||||
"Create these now" (default no) and then creates, in this order:
|
"Create these now" (default no) and then creates, in this order:
|
||||||
|
|
||||||
1. the GitHub repository (empty), if chosen;
|
1. the GitHub repository (empty), if chosen;
|
||||||
2. the Gitea repository (with the AGPL-3.0 license if GitHub was chosen);
|
2. the Gitea repository (with the license that applies: `PROJECT_LICENSE`, or AGPL-3.0 for a public project with GitHub);
|
||||||
3. the push mirror Gitea -> GitHub, and a request for its first sync;
|
3. the push mirror Gitea -> GitHub, and a request for its first sync;
|
||||||
4. the local directory, `git init` on `main`, the `origin` remote (and `github`
|
4. the local directory, `git init` on `main`, the `origin` remote (and `github`
|
||||||
if chosen), and, if the Gitea repository holds the license commit, that
|
if chosen), and, if the Gitea repository holds the license commit, that
|
||||||
@@ -181,10 +187,11 @@ hooks refuse commits on `main`.
|
|||||||
|
|
||||||
### Choices
|
### Choices
|
||||||
|
|
||||||
- **GitHub or not.** Choosing GitHub also applies the AGPL-3.0 license to the
|
- **GitHub or not.** Choosing GitHub sets up the mirror. For a public project it
|
||||||
Gitea repository (so it is not empty) and sets up the mirror. Without GitHub
|
also applies the AGPL-3.0 license to the Gitea repository (so it is not
|
||||||
the Gitea repository is empty and has no license, and `GITHUB_PAT` is not
|
empty), unless `PROJECT_LICENSE` says otherwise. A private project with
|
||||||
needed.
|
GitHub gets no license by default. Without GitHub the Gitea repository has
|
||||||
|
no license unless `PROJECT_LICENSE` sets one, and `GITHUB_PAT` is not needed.
|
||||||
- **Owners.** The Gitea owner and the GitHub owner are chosen separately and
|
- **Owners.** The Gitea owner and the GitHub owner are chosen separately and
|
||||||
may be a user or an organization. `GITHUB_USER` is only the suggested default
|
may be a user or an organization. `GITHUB_USER` is only the suggested default
|
||||||
for the GitHub owner prompt; it identifies who authenticates.
|
for the GitHub owner prompt; it identifies who authenticates.
|
||||||
|
|||||||
@@ -46,6 +46,12 @@ GITEA_API_URL=https://<your gitea instance>/api/v1
|
|||||||
#PROJECT_DIRECTORY=./my-project
|
#PROJECT_DIRECTORY=./my-project
|
||||||
#ENABLE_PLAN_GATE=no # yes or no
|
#ENABLE_PLAN_GATE=no # yes or no
|
||||||
|
|
||||||
|
# Optional. The license of the project, as a Gitea license key (AGPL-3.0, MIT,
|
||||||
|
# ...), or none for no license. It is never asked. When absent, AGPL-3.0 is
|
||||||
|
# applied only if GitHub is used and the project is public; otherwise there
|
||||||
|
# is no license. The Gitea server must offer the license.
|
||||||
|
#PROJECT_LICENSE=AGPL-3.0
|
||||||
|
|
||||||
# Optional. OWNER/NAME of the SQA-QC-Framework repository on the Gitea server;
|
# Optional. OWNER/NAME of the SQA-QC-Framework repository on the Gitea server;
|
||||||
# it is added to the new project as a submodule over SSH.
|
# it is added to the new project as a submodule over SSH.
|
||||||
# Default: TirSystem/SQA-QC-Framework.
|
# Default: TirSystem/SQA-QC-Framework.
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
## Version History
|
## Version History
|
||||||
| Date | Status | Author | Reviewer | Change | Commit |
|
| Date | Status | Author | Reviewer | Change | Commit |
|
||||||
| --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- |
|
||||||
| 2026-10-07 | Proposed | Jens Tirsvad Nielsen | S02 | AGPL-3.0 default only when GitHub is chosen and the project is public (purpose, resolution order, criterion 3, tasks 1 and 4) | [1cd27f7] |
|
| 2026-10-07 | Deprecated | Jens Tirsvad Nielsen | S02 | AGPL-3.0 default only when GitHub is chosen and the project is public (purpose, resolution order, criterion 3, tasks 1 and 4) | [1cd27f7] |
|
||||||
| 2026-10-07 | Proposed | Jens Tirsvad Nielsen | S02 | Task 4 renamed so its issue title is unique (the sync matches issues by title) | [be759e3] |
|
| 2026-10-07 | Accepted | Jens Tirsvad Nielsen | S02 | Task 4 renamed so its issue title is unique (the sync matches issues by title) | [be759e3] |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,9 @@
|
|||||||
# repositories and the mirror, then the local project: its directory, git
|
# repositories and the mirror, then the local project: its directory, git
|
||||||
# repository, remotes (no credential in any address), the framework as a
|
# repository, remotes (no credential in any address), the framework as a
|
||||||
# submodule, the framework's skills and git hooks (and the plan gate if
|
# submodule, the framework's skills and git hooks (and the plan gate if
|
||||||
# chosen) and its templates. Choosing GitHub also applies the AGPL-3.0
|
# chosen) and its templates. The license of the Gitea repository is
|
||||||
# license to the Gitea repository. No commit is made in the new project.
|
# PROJECT_LICENSE in config.env (none means no license); without it AGPL-3.0
|
||||||
|
# applies only when GitHub is chosen and the project is public. No commit is made in the new project.
|
||||||
#
|
#
|
||||||
# Dry run by default
|
# Dry run by default
|
||||||
# Without --apply the script only reads from GitHub and Gitea (GET
|
# Without --apply the script only reads from GitHub and Gitea (GET
|
||||||
|
|||||||
+2
-2
@@ -47,9 +47,9 @@ confirm_reuse() {
|
|||||||
die "stopped: choose another name or remove the existing repository"
|
die "stopped: choose another name or remove the existing repository"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
if ((${STATE[reuse_gitea]:-0})) && ((PROJECT[has_github])) &&
|
if ((${STATE[reuse_gitea]:-0})) && [[ -n ${PROJECT[license]} ]] &&
|
||||||
[[ ${STATE[gitea_repo]} == empty ]]; then
|
[[ ${STATE[gitea_repo]} == empty ]]; then
|
||||||
warn "the empty Gitea repository is reused as it is: the $AGPL_LICENSE_KEY license is not added to it"
|
warn "the empty Gitea repository is reused as it is: the ${PROJECT[license]} license is not added to it"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ validate_project_presets() {
|
|||||||
check_preset GITHUB_OWNER is_valid_github_owner "$HINT_GITHUB_OWNER"
|
check_preset GITHUB_OWNER is_valid_github_owner "$HINT_GITHUB_OWNER"
|
||||||
check_preset PROJECT_DIRECTORY is_valid_directory "$HINT_DIRECTORY"
|
check_preset PROJECT_DIRECTORY is_valid_directory "$HINT_DIRECTORY"
|
||||||
check_preset_choice ENABLE_PLAN_GATE yes no
|
check_preset_choice ENABLE_PLAN_GATE yes no
|
||||||
|
check_preset PROJECT_LICENSE is_valid_license "$HINT_LICENSE"
|
||||||
}
|
}
|
||||||
|
|
||||||
validate_credentials() {
|
validate_credentials() {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ readonly DEFAULT_MIRROR_INTERVAL="10m0s"
|
|||||||
readonly DEFAULT_SSH_PORT=10022
|
readonly DEFAULT_SSH_PORT=10022
|
||||||
readonly DEFAULT_FRAMEWORK_REPO="TirSystem/SQA-QC-Framework"
|
readonly DEFAULT_FRAMEWORK_REPO="TirSystem/SQA-QC-Framework"
|
||||||
readonly AGPL_LICENSE_KEY="AGPL-3.0"
|
readonly AGPL_LICENSE_KEY="AGPL-3.0"
|
||||||
|
readonly NO_LICENSE_WORD="none"
|
||||||
readonly DEFAULT_BRANCH="main"
|
readonly DEFAULT_BRANCH="main"
|
||||||
# What the prompts and the preset keys in config.env both tell the Maintainer
|
# What the prompts and the preset keys in config.env both tell the Maintainer
|
||||||
# when a value is refused.
|
# when a value is refused.
|
||||||
@@ -25,6 +26,7 @@ readonly HINT_REPO_NAME="use letters, digits, '.', '_' or '-' (at most 100), not
|
|||||||
readonly HINT_DESCRIPTION="at most $MAX_DESCRIPTION_LENGTH characters and no control characters"
|
readonly HINT_DESCRIPTION="at most $MAX_DESCRIPTION_LENGTH characters and no control characters"
|
||||||
readonly HINT_GITEA_OWNER="use letters, digits, '.', '_' or '-' (at most 39)"
|
readonly HINT_GITEA_OWNER="use letters, digits, '.', '_' or '-' (at most 39)"
|
||||||
readonly HINT_GITHUB_OWNER="use letters, digits or '-' (at most 39)"
|
readonly HINT_GITHUB_OWNER="use letters, digits or '-' (at most 39)"
|
||||||
|
readonly HINT_LICENSE="use a Gitea license key (letters, digits, '.', '+' or '-', at most 64), such as AGPL-3.0 or MIT, or none"
|
||||||
readonly HINT_DIRECTORY="must not be empty, start with '-' or contain control characters"
|
readonly HINT_DIRECTORY="must not be empty, start with '-' or contain control characters"
|
||||||
readonly PLAN_STEPS=("GitHub repository" "Gitea repository" "Push mirror"
|
readonly PLAN_STEPS=("GitHub repository" "Gitea repository" "Push mirror"
|
||||||
"Local project" "Framework" "Skills and hooks" "Templates")
|
"Local project" "Framework" "Skills and hooks" "Templates")
|
||||||
@@ -32,7 +34,7 @@ readonly PLAN_STEPS=("GitHub repository" "Gitea repository" "Push mirror"
|
|||||||
readonly CONFIG_KEYS=(GITHUB_API_URL GITHUB_WEB_URL GITEA_URL GITEA_API_URL
|
readonly CONFIG_KEYS=(GITHUB_API_URL GITHUB_WEB_URL GITEA_URL GITEA_API_URL
|
||||||
GITEA_SSH_PORT MIRROR_INTERVAL FRAMEWORK_REPO
|
GITEA_SSH_PORT MIRROR_INTERVAL FRAMEWORK_REPO
|
||||||
PROJECT_NAME PROJECT_DESCRIPTION PROJECT_VISIBILITY GITEA_OWNER USE_GITHUB
|
PROJECT_NAME PROJECT_DESCRIPTION PROJECT_VISIBILITY GITEA_OWNER USE_GITHUB
|
||||||
GITHUB_OWNER PROJECT_DIRECTORY ENABLE_PLAN_GATE)
|
GITHUB_OWNER PROJECT_DIRECTORY ENABLE_PLAN_GATE PROJECT_LICENSE)
|
||||||
readonly CREDENTIAL_KEYS=(GITHUB_PAT GITHUB_USER GITEA_TOKEN)
|
readonly CREDENTIAL_KEYS=(GITHUB_PAT GITHUB_USER GITEA_TOKEN)
|
||||||
|
|
||||||
CONFIG_FILE="$PROJECT_ROOT/config.env"
|
CONFIG_FILE="$PROJECT_ROOT/config.env"
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ checkout_gitea_history() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# create_local_project: the directory, the git repository on main, the
|
# create_local_project: the directory, the git repository on main, the
|
||||||
# remotes and, when GitHub is chosen, the license history. No commit is made.
|
# remotes and, when a license applies, the license history. No commit is made.
|
||||||
create_local_project() {
|
create_local_project() {
|
||||||
local label="Local project" dir="${PROJECT[directory]}"
|
local label="Local project" dir="${PROJECT[directory]}"
|
||||||
begin_step "$label"
|
begin_step "$label"
|
||||||
@@ -84,6 +84,8 @@ create_local_project() {
|
|||||||
ensure_remote "$dir" origin "$(origin_url)"
|
ensure_remote "$dir" origin "$(origin_url)"
|
||||||
if ((PROJECT[has_github])); then
|
if ((PROJECT[has_github])); then
|
||||||
ensure_remote "$dir" github "$(github_remote_url)"
|
ensure_remote "$dir" github "$(github_remote_url)"
|
||||||
|
fi
|
||||||
|
if [[ -n ${PROJECT[license]} ]]; then
|
||||||
checkout_gitea_history "$dir"
|
checkout_gitea_history "$dir"
|
||||||
fi
|
fi
|
||||||
finish_step "$label" "created" "$dir (origin over $(origin_protocol))"
|
finish_step "$label" "created" "$dir (origin over $(origin_protocol))"
|
||||||
|
|||||||
+2
-2
@@ -22,8 +22,8 @@ print_plan() {
|
|||||||
say "Plan:"
|
say "Plan:"
|
||||||
if ((STATE[reuse_gitea])); then
|
if ((STATE[reuse_gitea])); then
|
||||||
gitea_action="reuse the existing repository (you will be asked to confirm)"
|
gitea_action="reuse the existing repository (you will be asked to confirm)"
|
||||||
elif ((PROJECT[has_github])); then
|
elif [[ -n ${PROJECT[license]} ]]; then
|
||||||
gitea_action="create (${PROJECT[visibility]}) with the $AGPL_LICENSE_KEY license"
|
gitea_action="create (${PROJECT[visibility]}) with the ${PROJECT[license]} license$(license_note)"
|
||||||
else
|
else
|
||||||
gitea_action="create (${PROJECT[visibility]}), empty"
|
gitea_action="create (${PROJECT[visibility]}), empty"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ check_gitea_organization() {
|
|||||||
check_gitea_license() {
|
check_gitea_license() {
|
||||||
api_call gitea GET /licenses
|
api_call gitea GET /licenses
|
||||||
expect_status "cannot list the licenses of the Gitea server" 200
|
expect_status "cannot list the licenses of the Gitea server" 200
|
||||||
json_has_value "$HTTP_BODY_FILE" key "$AGPL_LICENSE_KEY" ||
|
json_has_value "$HTTP_BODY_FILE" key "${PROJECT[license]}" ||
|
||||||
die "the Gitea server does not offer the $AGPL_LICENSE_KEY license"
|
die "the Gitea server does not offer the ${PROJECT[license]} license"
|
||||||
}
|
}
|
||||||
|
|
||||||
# inspect_repository HOST: record in STATE[HOST_repo] whether the repository
|
# inspect_repository HOST: record in STATE[HOST_repo] whether the repository
|
||||||
@@ -70,7 +70,7 @@ preflight_gitea() {
|
|||||||
check_gitea_organization "$owner" "$login"
|
check_gitea_organization "$owner" "$login"
|
||||||
STATE[gitea_owner_kind]="organization"
|
STATE[gitea_owner_kind]="organization"
|
||||||
fi
|
fi
|
||||||
if ((PROJECT[has_github])); then
|
if [[ -n ${PROJECT[license]} ]]; then
|
||||||
check_gitea_license
|
check_gitea_license
|
||||||
fi
|
fi
|
||||||
inspect_repository gitea
|
inspect_repository gitea
|
||||||
@@ -143,7 +143,7 @@ decide_existing_repositories() {
|
|||||||
free) ;;
|
free) ;;
|
||||||
empty) STATE[reuse_$host]=1 ;;
|
empty) STATE[reuse_$host]=1 ;;
|
||||||
initial_only)
|
initial_only)
|
||||||
if [[ $host == gitea ]] && ((PROJECT[has_github])); then
|
if [[ $host == gitea && -n ${PROJECT[license]} ]]; then
|
||||||
STATE[reuse_$host]=1
|
STATE[reuse_$host]=1
|
||||||
else
|
else
|
||||||
die "the $(host_label "$host") repository $owner/${PROJECT[name]} already exists and has content; choose another name or remove it first"
|
die "the $(host_label "$host") repository $owner/${PROJECT[name]} already exists and has content; choose another name or remove it first"
|
||||||
|
|||||||
+32
-3
@@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# Part of create-project.sh: sourced by it, never run on its own.
|
# Part of create-project.sh: sourced by it, never run on its own.
|
||||||
#
|
#
|
||||||
# Provides: preset_detail, collect_project_details, collect_github_details, source_note, yes_no, credential_state, print_summary
|
# Provides: preset_detail, resolve_license, license_note, collect_project_details, collect_github_details, source_note, yes_no, credential_state, print_summary
|
||||||
|
|
||||||
# preset_detail KEY NAME: a detail set in config.env is used and not asked;
|
# preset_detail KEY NAME: a detail set in config.env is used and not asked;
|
||||||
# the value is returned in REPLY and marked in PRESET[NAME].
|
# the value is returned in REPLY and marked in PRESET[NAME].
|
||||||
@@ -14,6 +14,33 @@ preset_detail() {
|
|||||||
PRESET[$2]=1
|
PRESET[$2]=1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# resolve_license: the license that applies, in PROJECT[license] (empty means
|
||||||
|
# none). PROJECT_LICENSE in config.env decides, and "none" means no license;
|
||||||
|
# without it AGPL-3.0 applies only when GitHub is chosen and the project is
|
||||||
|
# public. The license is never asked.
|
||||||
|
resolve_license() {
|
||||||
|
PROJECT[license]=""
|
||||||
|
if [[ -n ${CONFIG[PROJECT_LICENSE]+set} ]]; then
|
||||||
|
PRESET[license]=1
|
||||||
|
if [[ ${CONFIG[PROJECT_LICENSE],,} != "$NO_LICENSE_WORD" ]]; then
|
||||||
|
PROJECT[license]="${CONFIG[PROJECT_LICENSE]}"
|
||||||
|
fi
|
||||||
|
elif ((PROJECT[has_github])) && [[ ${PROJECT[visibility]} == public ]]; then
|
||||||
|
PROJECT[license]="$AGPL_LICENSE_KEY"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# license_note: where the license on the Gitea repository comes from.
|
||||||
|
license_note() {
|
||||||
|
if [[ -n ${PRESET[license]:-} ]]; then
|
||||||
|
source_note license
|
||||||
|
elif [[ -n ${PROJECT[license]} ]]; then
|
||||||
|
printf ' (default: GitHub and a public project)'
|
||||||
|
elif ((PROJECT[has_github])); then
|
||||||
|
printf ' (no default for a private project)'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Ask for each project detail, except those set in config.env.
|
# Ask for each project detail, except those set in config.env.
|
||||||
collect_project_details() {
|
collect_project_details() {
|
||||||
preset_detail PROJECT_NAME name ||
|
preset_detail PROJECT_NAME name ||
|
||||||
@@ -29,6 +56,7 @@ collect_project_details() {
|
|||||||
prompt_value "Gitea owner (user or organization)" "" is_valid_gitea_owner "$HINT_GITEA_OWNER"
|
prompt_value "Gitea owner (user or organization)" "" is_valid_gitea_owner "$HINT_GITEA_OWNER"
|
||||||
PROJECT[gitea_owner]="$REPLY"
|
PROJECT[gitea_owner]="$REPLY"
|
||||||
collect_github_details
|
collect_github_details
|
||||||
|
resolve_license
|
||||||
preset_detail PROJECT_DIRECTORY directory ||
|
preset_detail PROJECT_DIRECTORY directory ||
|
||||||
prompt_value "Local directory" "./${PROJECT[name]}" is_valid_directory "$HINT_DIRECTORY"
|
prompt_value "Local directory" "./${PROJECT[name]}" is_valid_directory "$HINT_DIRECTORY"
|
||||||
PROJECT[directory]="$REPLY"
|
PROJECT[directory]="$REPLY"
|
||||||
@@ -46,7 +74,7 @@ collect_github_details() {
|
|||||||
if preset_detail USE_GITHUB has_github; then
|
if preset_detail USE_GITHUB has_github; then
|
||||||
[[ $REPLY == yes ]] && REPLY=1 || REPLY=0
|
[[ $REPLY == yes ]] && REPLY=1 || REPLY=0
|
||||||
else
|
else
|
||||||
prompt_yes_no "Also create a GitHub repository (applies the AGPL license)" y
|
prompt_yes_no "Also create a GitHub repository" y
|
||||||
fi
|
fi
|
||||||
PROJECT[has_github]="$REPLY"
|
PROJECT[has_github]="$REPLY"
|
||||||
PROJECT[github_owner]=""
|
PROJECT[github_owner]=""
|
||||||
@@ -90,10 +118,11 @@ print_summary() {
|
|||||||
say " Description : ${PROJECT[description]:-(none)}$(source_note description)"
|
say " Description : ${PROJECT[description]:-(none)}$(source_note description)"
|
||||||
say " Gitea : ${CONFIG[GITEA_URL]}/${PROJECT[gitea_owner]}/${PROJECT[name]}$(source_note gitea_owner)"
|
say " Gitea : ${CONFIG[GITEA_URL]}/${PROJECT[gitea_owner]}/${PROJECT[name]}$(source_note gitea_owner)"
|
||||||
if ((PROJECT[has_github])); then
|
if ((PROJECT[has_github])); then
|
||||||
say " GitHub : ${CONFIG[GITHUB_WEB_URL]}/${PROJECT[github_owner]}/${PROJECT[name]} (AGPL license applied)$(source_note github_owner)"
|
say " GitHub : ${CONFIG[GITHUB_WEB_URL]}/${PROJECT[github_owner]}/${PROJECT[name]}$(source_note github_owner)"
|
||||||
else
|
else
|
||||||
say " GitHub : not used$(source_note has_github)"
|
say " GitHub : not used$(source_note has_github)"
|
||||||
fi
|
fi
|
||||||
|
say " License : ${PROJECT[license]:-none}$(license_note)"
|
||||||
say " Directory : ${PROJECT[directory]}$(source_note directory)"
|
say " Directory : ${PROJECT[directory]}$(source_note directory)"
|
||||||
say " Plan gate : $(yes_no "${PROJECT[is_plan_gate_enabled]}")$(source_note is_plan_gate_enabled)"
|
say " Plan gate : $(yes_no "${PROJECT[is_plan_gate_enabled]}")$(source_note is_plan_gate_enabled)"
|
||||||
say "Credentials : GITEA_TOKEN $(credential_state GITEA_TOKEN)," \
|
say "Credentials : GITEA_TOKEN $(credential_state GITEA_TOKEN)," \
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ repo_body() {
|
|||||||
"${PROJECT[name]}" "$description" "$private"
|
"${PROJECT[name]}" "$description" "$private"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
if ((PROJECT[has_github])); then
|
if [[ -n ${PROJECT[license]} ]]; then
|
||||||
extra=',"auto_init":true,"license":"'"$AGPL_LICENSE_KEY"'"'
|
extra=',"auto_init":true,"license":"'"${PROJECT[license]}"'"'
|
||||||
else
|
else
|
||||||
extra=',"auto_init":false'
|
extra=',"auto_init":false'
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ is_valid_port() {
|
|||||||
[[ $1 =~ ^[0-9]{1,5}$ ]] && ((10#$1 >= 1 && 10#$1 <= 65535))
|
[[ $1 =~ ^[0-9]{1,5}$ ]] && ((10#$1 >= 1 && 10#$1 <= 65535))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# A Gitea license key such as AGPL-3.0 or MIT, or the word none.
|
||||||
|
is_valid_license() {
|
||||||
|
[[ -n $1 && ${#1} -le 64 && $1 =~ ^[A-Za-z0-9.+-]+$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
# A Go duration such as 10m0s or 8h0m0s, the form Gitea expects.
|
# A Go duration such as 10m0s or 8h0m0s, the form Gitea expects.
|
||||||
is_valid_interval() {
|
is_valid_interval() {
|
||||||
[[ -n $1 && $1 =~ ^([0-9]+h)?([0-9]+m)?([0-9]+s)?$ ]]
|
[[ -n $1 && $1 =~ ^([0-9]+h)?([0-9]+m)?([0-9]+s)?$ ]]
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ readonly FAKE_GITHUB_PAT="ghpFAKEtoken1234567890"
|
|||||||
# Answers to the prompts: name, description, visibility, Gitea owner, GitHub
|
# Answers to the prompts: name, description, visibility, Gitea owner, GitHub
|
||||||
# yes or no, GitHub owner, directory, plan gate.
|
# yes or no, GitHub owner, directory, plan gate.
|
||||||
readonly ANSWERS_GITHUB=$'my-app\nA test app\n\nTirSystem\ny\nacme-org\n\nn\n'
|
readonly ANSWERS_GITHUB=$'my-app\nA test app\n\nTirSystem\ny\nacme-org\n\nn\n'
|
||||||
|
# The same, for a public project (the AGPL-3.0 default applies with GitHub).
|
||||||
|
readonly ANSWERS_GITHUB_PUBLIC=$'my-app
|
||||||
|
A test app
|
||||||
|
public
|
||||||
|
TirSystem
|
||||||
|
y
|
||||||
|
acme-org
|
||||||
|
|
||||||
|
n
|
||||||
|
'
|
||||||
readonly ANSWERS_GITEA_ONLY=$'my-app\n\n\nTirSystem\nn\n\nn\n'
|
readonly ANSWERS_GITEA_ONLY=$'my-app\n\n\nTirSystem\nn\n\nn\n'
|
||||||
|
|
||||||
SHARED_REMOTES=""
|
SHARED_REMOTES=""
|
||||||
|
|||||||
+23
-9
@@ -31,7 +31,7 @@ test_dry_run_prints_the_plan_and_only_reads() {
|
|||||||
setup_hosts
|
setup_hosts
|
||||||
run_dry "$ANSWERS_GITHUB"
|
run_dry "$ANSWERS_GITHUB"
|
||||||
assert_status "dry run" 0 "$STATUS"
|
assert_status "dry run" 0 "$STATUS"
|
||||||
assert_contains "Gitea plan" "$OUT" "Gitea repository : create (private) with the AGPL-3.0 license https://git.example.test/TirSystem/my-app"
|
assert_contains "Gitea plan" "$OUT" "Gitea repository : create (private), empty https://git.example.test/TirSystem/my-app"
|
||||||
assert_contains "GitHub plan" "$OUT" "GitHub repository : create (private), empty https://github.com/acme-org/my-app"
|
assert_contains "GitHub plan" "$OUT" "GitHub repository : create (private), empty https://github.com/acme-org/my-app"
|
||||||
assert_contains "mirror plan" "$OUT" "Push mirror : Gitea -> GitHub every 10m0s"
|
assert_contains "mirror plan" "$OUT" "Push mirror : Gitea -> GitHub every 10m0s"
|
||||||
assert_contains "origin plan" "$OUT" "Local origin : will use SSH (the SSH test passed)"
|
assert_contains "origin plan" "$OUT" "Local origin : will use SSH (the SSH test passed)"
|
||||||
@@ -148,14 +148,18 @@ test_github_owner_must_be_a_member() {
|
|||||||
assert_contains "pending message" "$ERR" "membership of the GitHub organization 'acme-org' is not active"
|
assert_contains "pending message" "$ERR" "membership of the GitHub organization 'acme-org' is not active"
|
||||||
}
|
}
|
||||||
|
|
||||||
test_license_must_be_offered_when_github_is_chosen() {
|
test_license_must_be_offered_when_a_public_project_has_github() {
|
||||||
setup_hosts
|
setup_hosts
|
||||||
prepend_route 'GET|/api/v1/licenses|200|[{"key":"MIT","name":"MIT"}]'
|
prepend_route 'GET|/api/v1/licenses|200|[{"key":"MIT","name":"MIT"}]'
|
||||||
run_apply "$ANSWERS_GITHUB"
|
run_apply "$ANSWERS_GITHUB_PUBLIC"
|
||||||
assert_status "no AGPL" 1 "$STATUS"
|
assert_status "no AGPL" 1 "$STATUS"
|
||||||
assert_contains "message" "$ERR" "does not offer the AGPL-3.0 license"
|
assert_contains "message" "$ERR" "does not offer the AGPL-3.0 license"
|
||||||
assert_not_contains "nothing created" "$(calls)" "POST"
|
assert_not_contains "nothing created" "$(calls)" "POST"
|
||||||
# Without GitHub no license is needed, so the same server is fine.
|
# Without GitHub, or for a private project, no license is needed, so the same server is fine.
|
||||||
|
setup_hosts
|
||||||
|
prepend_route 'GET|/api/v1/licenses|200|[{"key":"MIT","name":"MIT"}]'
|
||||||
|
run_dry "$ANSWERS_GITHUB"
|
||||||
|
assert_status "private with GitHub" 0 "$STATUS"
|
||||||
setup_hosts
|
setup_hosts
|
||||||
prepend_route 'GET|/api/v1/licenses|200|[{"key":"MIT","name":"MIT"}]'
|
prepend_route 'GET|/api/v1/licenses|200|[{"key":"MIT","name":"MIT"}]'
|
||||||
printf 'GITEA_TOKEN=%s\n' "$FAKE_GITEA_TOKEN" >"$WORK/.env"
|
printf 'GITEA_TOKEN=%s\n' "$FAKE_GITEA_TOKEN" >"$WORK/.env"
|
||||||
@@ -215,8 +219,7 @@ test_apply_sends_the_right_request_bodies() {
|
|||||||
bodies="$(cat "$WORK/curl.bodies")"
|
bodies="$(cat "$WORK/curl.bodies")"
|
||||||
assert_contains "GitHub name" "$bodies" '"name":"my-app"'
|
assert_contains "GitHub name" "$bodies" '"name":"my-app"'
|
||||||
assert_contains "GitHub is created empty" "$bodies" '"private":true,"auto_init":false}'
|
assert_contains "GitHub is created empty" "$bodies" '"private":true,"auto_init":false}'
|
||||||
assert_contains "Gitea gets the license" "$bodies" '"license":"AGPL-3.0"'
|
assert_not_contains "a private project gets no license" "$bodies" '"license"'
|
||||||
assert_contains "Gitea is initialised with it" "$bodies" '"auto_init":true'
|
|
||||||
assert_contains "default branch" "$bodies" '"default_branch":"main"'
|
assert_contains "default branch" "$bodies" '"default_branch":"main"'
|
||||||
assert_contains "description" "$bodies" '"description":"A test app"'
|
assert_contains "description" "$bodies" '"description":"A test app"'
|
||||||
assert_contains "mirror target without credentials" "$bodies" '"remote_address":"https://github.com/acme-org/my-app.git"'
|
assert_contains "mirror target without credentials" "$bodies" '"remote_address":"https://github.com/acme-org/my-app.git"'
|
||||||
@@ -239,6 +242,17 @@ test_apply_never_prints_or_passes_a_token() {
|
|||||||
assert_contains "GitHub token in the private config" "$(cat "$WORK/curl.config")" "Authorization: Bearer $FAKE_GITHUB_PAT"
|
assert_contains "GitHub token in the private config" "$(cat "$WORK/curl.config")" "Authorization: Bearer $FAKE_GITHUB_PAT"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_apply_sends_the_license_for_a_public_project_with_github() {
|
||||||
|
setup_hosts
|
||||||
|
run_apply "$ANSWERS_GITHUB_PUBLIC"$'y\n'
|
||||||
|
local bodies
|
||||||
|
bodies="$(cat "$WORK/curl.bodies")"
|
||||||
|
assert_contains "Gitea gets the license" "$bodies" '"license":"AGPL-3.0"'
|
||||||
|
assert_contains "Gitea is initialised with it" "$bodies" '"auto_init":true'
|
||||||
|
assert_contains "public" "$bodies" '"private":false'
|
||||||
|
assert_contains "plan names the rule" "$OUT" "with the AGPL-3.0 license (default: GitHub and a public project)"
|
||||||
|
}
|
||||||
|
|
||||||
test_apply_with_gitea_only() {
|
test_apply_with_gitea_only() {
|
||||||
setup_hosts
|
setup_hosts
|
||||||
printf 'GITEA_TOKEN=%s\n' "$FAKE_GITEA_TOKEN" >"$WORK/.env"
|
printf 'GITEA_TOKEN=%s\n' "$FAKE_GITEA_TOKEN" >"$WORK/.env"
|
||||||
@@ -337,7 +351,7 @@ test_gitea_repository_with_only_the_license_can_be_reused() {
|
|||||||
setup_hosts
|
setup_hosts
|
||||||
prepend_route 'GET|/api/v1/repos/TirSystem/my-app|200|{"empty":false}'
|
prepend_route 'GET|/api/v1/repos/TirSystem/my-app|200|{"empty":false}'
|
||||||
prepend_route 'GET|/api/v1/repos/TirSystem/my-app/contents|200|[{"name":"LICENSE","type":"file","path":"LICENSE"}]'
|
prepend_route 'GET|/api/v1/repos/TirSystem/my-app/contents|200|[{"name":"LICENSE","type":"file","path":"LICENSE"}]'
|
||||||
run_apply "$ANSWERS_GITHUB"$'y\ny\n'
|
run_apply "$ANSWERS_GITHUB_PUBLIC"$'y\ny\n'
|
||||||
assert_status "license only" 0 "$STATUS"
|
assert_status "license only" 0 "$STATUS"
|
||||||
assert_not_contains "Gitea repository not created again" "$(calls)" "$GITEA_REPO_CALL"
|
assert_not_contains "Gitea repository not created again" "$(calls)" "$GITEA_REPO_CALL"
|
||||||
assert_eq "mirror created once" "1" "$(calls | grep -c -x -F "$MIRROR_CALL")"
|
assert_eq "mirror created once" "1" "$(calls | grep -c -x -F "$MIRROR_CALL")"
|
||||||
@@ -355,7 +369,7 @@ test_gitea_repository_with_only_the_license_can_be_reused() {
|
|||||||
test_reusing_an_empty_gitea_repository_warns_about_the_license() {
|
test_reusing_an_empty_gitea_repository_warns_about_the_license() {
|
||||||
setup_hosts
|
setup_hosts
|
||||||
prepend_route 'GET|/api/v1/repos/TirSystem/my-app|200|{"empty":true}'
|
prepend_route 'GET|/api/v1/repos/TirSystem/my-app|200|{"empty":true}'
|
||||||
run_apply "$ANSWERS_GITHUB"$'y\ny\n'
|
run_apply "$ANSWERS_GITHUB_PUBLIC"$'y\ny\n'
|
||||||
assert_status "reuse empty Gitea repository" 0 "$STATUS"
|
assert_status "reuse empty Gitea repository" 0 "$STATUS"
|
||||||
assert_contains "warning" "$ERR" "the AGPL-3.0 license is not added to it"
|
assert_contains "warning" "$ERR" "the AGPL-3.0 license is not added to it"
|
||||||
}
|
}
|
||||||
@@ -485,7 +499,7 @@ test_a_repository_this_script_created_earlier_can_be_reused() {
|
|||||||
setup_hosts
|
setup_hosts
|
||||||
prepend_route 'GET|/api/v1/repos/TirSystem/my-app|200|{"empty":false}'
|
prepend_route 'GET|/api/v1/repos/TirSystem/my-app|200|{"empty":false}'
|
||||||
prepend_route 'GET|/api/v1/repos/TirSystem/my-app/contents|200|[{"name":"README.md","type":"file"},{"name":"LICENSE","type":"file"}]'
|
prepend_route 'GET|/api/v1/repos/TirSystem/my-app/contents|200|[{"name":"README.md","type":"file"},{"name":"LICENSE","type":"file"}]'
|
||||||
run_apply "$ANSWERS_GITHUB"$'y\ny\n'
|
run_apply "$ANSWERS_GITHUB_PUBLIC"$'y\ny\n'
|
||||||
assert_status "LICENSE and README.md" 0 "$STATUS"
|
assert_status "LICENSE and README.md" 0 "$STATUS"
|
||||||
assert_not_contains "not created again" "$(calls)" "$GITEA_REPO_CALL"
|
assert_not_contains "not created again" "$(calls)" "$GITEA_REPO_CALL"
|
||||||
assert_contains "reported" "$OUT" "Gitea repository : reused"
|
assert_contains "reported" "$OUT" "Gitea repository : reused"
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# test-license.sh - tests for the project license (MIL-006): PROJECT_LICENSE
|
||||||
|
# in config.env, the default (AGPL-3.0 only for a public project with GitHub),
|
||||||
|
# "none", invalid values and a license the server does not offer. Sourced by
|
||||||
|
# run-tests.sh.
|
||||||
|
|
||||||
|
# shellcheck disable=SC2016 # snippet and fixture text is literal on purpose
|
||||||
|
|
||||||
|
readonly ANSWERS_GITEA_ONLY_PUBLIC=$'my-app\n\npublic\nTirSystem\nn\n\nn\n'
|
||||||
|
readonly MIT_ROUTE='GET|/api/v1/licenses|200|[{"key":"MIT","name":"MIT"},{"key":"AGPL-3.0","name":"AGPL-3.0"}]'
|
||||||
|
|
||||||
|
# use_license LINE: add a line to config.env and make the server offer MIT.
|
||||||
|
use_license() {
|
||||||
|
printf '%s\n' "$1" >>"$WORK/config.env"
|
||||||
|
prepend_route "$MIT_ROUTE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# gitea_only_env: a Gitea-only run needs no GitHub credentials.
|
||||||
|
gitea_only_env() {
|
||||||
|
printf 'GITEA_TOKEN=%s\n' "$FAKE_GITEA_TOKEN" >"$WORK/.env"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------- key is set
|
||||||
|
|
||||||
|
test_a_license_in_config_is_used_with_github_for_a_private_project() {
|
||||||
|
setup_hosts
|
||||||
|
use_license "PROJECT_LICENSE=MIT"
|
||||||
|
run_apply "$ANSWERS_GITHUB"$'y\n'
|
||||||
|
assert_status "apply" 0 "$STATUS"
|
||||||
|
assert_contains "Gitea gets MIT" "$(cat "$WORK/curl.bodies")" '"license":"MIT"'
|
||||||
|
assert_not_contains "no AGPL" "$(cat "$WORK/curl.bodies")" "AGPL"
|
||||||
|
assert_contains "plan" "$OUT" "create (private) with the MIT license (from config.env)"
|
||||||
|
assert_contains "summary" "$OUT" "License : MIT (from config.env)"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_a_license_in_config_is_used_without_github() {
|
||||||
|
setup_hosts
|
||||||
|
gitea_only_env
|
||||||
|
use_license "PROJECT_LICENSE=MIT"
|
||||||
|
run_apply "$ANSWERS_GITEA_ONLY"$'y\n'
|
||||||
|
assert_status "apply" 0 "$STATUS"
|
||||||
|
assert_contains "Gitea gets MIT" "$(cat "$WORK/curl.bodies")" '"license":"MIT"'
|
||||||
|
assert_contains "initialised with it" "$(cat "$WORK/curl.bodies")" '"auto_init":true'
|
||||||
|
assert_not_contains "no GitHub call" "$(calls)" "api.github.com"
|
||||||
|
assert_contains "the server is asked" "$(calls)" "/licenses"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_the_license_key_is_taken_in_any_case_for_none() {
|
||||||
|
setup_hosts
|
||||||
|
use_license "PROJECT_LICENSE=NONE"
|
||||||
|
run_apply "$ANSWERS_GITHUB_PUBLIC"$'y\n'
|
||||||
|
assert_status "apply" 0 "$STATUS"
|
||||||
|
assert_not_contains "no license" "$(cat "$WORK/curl.bodies")" '"license"'
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------- none
|
||||||
|
|
||||||
|
test_none_gives_no_license_even_for_a_public_project_with_github() {
|
||||||
|
setup_hosts
|
||||||
|
use_license "PROJECT_LICENSE=none"
|
||||||
|
run_apply "$ANSWERS_GITHUB_PUBLIC"$'y\n'
|
||||||
|
assert_status "apply" 0 "$STATUS"
|
||||||
|
assert_not_contains "no license" "$(cat "$WORK/curl.bodies")" '"license"'
|
||||||
|
assert_not_contains "no license lookup" "$(calls)" "/licenses"
|
||||||
|
assert_contains "plan" "$OUT" "create (public), empty"
|
||||||
|
assert_contains "summary" "$OUT" "License : none (from config.env)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------- absent
|
||||||
|
|
||||||
|
test_without_the_key_a_public_project_with_github_gets_agpl() {
|
||||||
|
setup_hosts
|
||||||
|
run_dry "$ANSWERS_GITHUB_PUBLIC"
|
||||||
|
assert_status "dry run" 0 "$STATUS"
|
||||||
|
assert_contains "plan" "$OUT" "with the AGPL-3.0 license (default: GitHub and a public project)"
|
||||||
|
assert_contains "summary" "$OUT" "License : AGPL-3.0 (default: GitHub and a public project)"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_without_the_key_a_private_project_with_github_gets_no_license() {
|
||||||
|
setup_hosts
|
||||||
|
run_dry "$ANSWERS_GITHUB"
|
||||||
|
assert_status "dry run" 0 "$STATUS"
|
||||||
|
assert_contains "summary" "$OUT" "License : none (no default for a private project)"
|
||||||
|
assert_not_contains "no license lookup" "$(calls)" "/licenses"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_without_the_key_a_project_without_github_gets_no_license() {
|
||||||
|
setup_hosts
|
||||||
|
gitea_only_env
|
||||||
|
run_dry "$ANSWERS_GITEA_ONLY_PUBLIC"
|
||||||
|
assert_status "dry run" 0 "$STATUS"
|
||||||
|
assert_contains "summary" "$OUT" "License : none"
|
||||||
|
assert_not_contains "no marker" "$OUT" "License : none ("
|
||||||
|
assert_not_contains "no license lookup" "$(calls)" "/licenses"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------- empty and invalid
|
||||||
|
|
||||||
|
test_an_empty_license_stops_before_any_request() {
|
||||||
|
setup_hosts
|
||||||
|
printf 'PROJECT_LICENSE=\n' >>"$WORK/config.env"
|
||||||
|
run_dry "$ANSWERS_GITHUB"
|
||||||
|
assert_status "empty" 1 "$STATUS"
|
||||||
|
assert_contains "key named" "$ERR" "PROJECT_LICENSE in"
|
||||||
|
assert_contains "says empty" "$ERR" "is empty"
|
||||||
|
assert_eq "no request to any host" "" "$(calls)"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_an_invalid_license_stops_before_any_request_and_is_never_asked() {
|
||||||
|
local value
|
||||||
|
for value in 'bad license' 'MIT/2' 'MIT;rm' "$(printf 'a%.0s' {1..65})"; do
|
||||||
|
remove_workdir
|
||||||
|
new_workdir
|
||||||
|
setup_hosts
|
||||||
|
printf 'PROJECT_LICENSE=%s\n' "$value" >>"$WORK/config.env"
|
||||||
|
run_dry "$ANSWERS_GITHUB"
|
||||||
|
assert_status "invalid '$value'" 1 "$STATUS"
|
||||||
|
assert_contains "key named" "$ERR" "PROJECT_LICENSE in"
|
||||||
|
assert_eq "no request to any host" "" "$(calls)"
|
||||||
|
assert_not_contains "never asked" "$ERR" "License ("
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------ not offered
|
||||||
|
|
||||||
|
test_a_license_the_server_does_not_offer_stops_before_anything_is_created() {
|
||||||
|
setup_hosts
|
||||||
|
use_license "PROJECT_LICENSE=Zlib"
|
||||||
|
run_apply "$ANSWERS_GITHUB"$'y\n'
|
||||||
|
assert_status "not offered" 1 "$STATUS"
|
||||||
|
assert_contains "license named" "$ERR" "does not offer the Zlib license"
|
||||||
|
assert_not_contains "nothing created" "$(calls)" "POST"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------- never asked
|
||||||
|
|
||||||
|
test_the_license_is_never_asked() {
|
||||||
|
setup_hosts
|
||||||
|
run_dry "$ANSWERS_GITHUB_PUBLIC"
|
||||||
|
assert_not_contains "no license prompt" "$ERR" "icense ("
|
||||||
|
assert_not_contains "no license prompt, any case" "$ERR" "License:"
|
||||||
|
remove_workdir
|
||||||
|
new_workdir
|
||||||
|
setup_hosts
|
||||||
|
use_license "PROJECT_LICENSE=MIT"
|
||||||
|
run_dry "$ANSWERS_GITHUB"
|
||||||
|
assert_not_contains "no license prompt with the key" "$ERR" "icense ("
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------- mirror and local history
|
||||||
|
|
||||||
|
test_the_license_file_reaches_the_local_project_without_github() {
|
||||||
|
setup_hosts
|
||||||
|
gitea_only_env
|
||||||
|
use_license "PROJECT_LICENSE=MIT"
|
||||||
|
local dir="$WORK/project" answers
|
||||||
|
printf -v answers 'my-app\n\n\nTirSystem\nn\n%s\nn\n' "$dir"
|
||||||
|
run_apply "$answers"$'y\n'
|
||||||
|
assert_status "apply" 0 "$STATUS"
|
||||||
|
assert_eq "the Gitea license commit is the whole history" "1" "$(GIT_CONFIG_GLOBAL="$WORK/gitconfig" GIT_CONFIG_NOSYSTEM=1 git -C "$dir" rev-list --count HEAD)"
|
||||||
|
assert_file_exists "LICENSE from Gitea" "$dir/LICENSE"
|
||||||
|
}
|
||||||
+1
-1
@@ -12,7 +12,7 @@
|
|||||||
# LOCAL_ANSWERS (kept in a variable because $(...) would drop the last newline).
|
# LOCAL_ANSWERS (kept in a variable because $(...) would drop the last newline).
|
||||||
local_answers() {
|
local_answers() {
|
||||||
if [[ $2 == y ]]; then
|
if [[ $2 == y ]]; then
|
||||||
printf -v LOCAL_ANSWERS 'my-app\nA test app\n\nTirSystem\ny\nacme-org\n%s\n%s\n' "$1" "$3"
|
printf -v LOCAL_ANSWERS 'my-app\nA test app\npublic\nTirSystem\ny\nacme-org\n%s\n%s\n' "$1" "$3"
|
||||||
else
|
else
|
||||||
printf -v LOCAL_ANSWERS 'my-app\n\n\nTirSystem\nn\n%s\n%s\n' "$1" "$3"
|
printf -v LOCAL_ANSWERS 'my-app\n\n\nTirSystem\nn\n%s\n%s\n' "$1" "$3"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ test_summary_marks_the_values_from_config_env() {
|
|||||||
assert_contains "name" "$OUT" "Repository : my-app (from config.env) (private (from config.env))"
|
assert_contains "name" "$OUT" "Repository : my-app (from config.env) (private (from config.env))"
|
||||||
assert_contains "description" "$OUT" "Description : A test app (from config.env)"
|
assert_contains "description" "$OUT" "Description : A test app (from config.env)"
|
||||||
assert_contains "Gitea" "$OUT" "/TirSystem/my-app (from config.env)"
|
assert_contains "Gitea" "$OUT" "/TirSystem/my-app (from config.env)"
|
||||||
assert_contains "GitHub" "$OUT" "(AGPL license applied) (from config.env)"
|
assert_contains "GitHub" "$OUT" "/acme-org/my-app (from config.env)"
|
||||||
assert_contains "directory" "$OUT" "Directory : ./my-app (from config.env)"
|
assert_contains "directory" "$OUT" "Directory : ./my-app (from config.env)"
|
||||||
assert_contains "plan gate" "$OUT" "Plan gate : no (from config.env)"
|
assert_contains "plan gate" "$OUT" "Plan gate : no (from config.env)"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ test_full_run_with_github() {
|
|||||||
after="$(listing)"
|
after="$(listing)"
|
||||||
assert_status "full run" 0 "$STATUS"
|
assert_status "full run" 0 "$STATUS"
|
||||||
assert_contains "dry run" "$OUT" "Dry run: nothing was created"
|
assert_contains "dry run" "$OUT" "Dry run: nothing was created"
|
||||||
assert_contains "plan" "$OUT" "create (private) with the AGPL-3.0 license"
|
assert_contains "plan" "$OUT" "create (private), empty"
|
||||||
assert_contains "Gitea link derived from config" "$OUT" "https://git.example.test/TirSystem/my-app"
|
assert_contains "Gitea link derived from config" "$OUT" "https://git.example.test/TirSystem/my-app"
|
||||||
assert_contains "GitHub link uses the chosen organization" "$OUT" "https://github.com/acme-org/my-app"
|
assert_contains "GitHub link uses the chosen organization" "$OUT" "https://github.com/acme-org/my-app"
|
||||||
assert_contains "AGPL noted" "$OUT" "AGPL license applied"
|
assert_contains "no default license for a private project" "$OUT" "License : none (no default for a private project)"
|
||||||
assert_contains "credential state" "$OUT" "GITEA_TOKEN set, GITHUB_PAT set"
|
assert_contains "credential state" "$OUT" "GITEA_TOKEN set, GITHUB_PAT set"
|
||||||
assert_not_contains "no Gitea token in output" "$OUT$ERR" "$FAKE_GITEA_TOKEN"
|
assert_not_contains "no Gitea token in output" "$OUT$ERR" "$FAKE_GITEA_TOKEN"
|
||||||
assert_not_contains "no GitHub token in output" "$OUT$ERR" "$FAKE_GITHUB_PAT"
|
assert_not_contains "no GitHub token in output" "$OUT$ERR" "$FAKE_GITHUB_PAT"
|
||||||
|
|||||||
Reference in New Issue
Block a user