Compare commits
74 Commits
valid_set.
...
valid_set.
Author | SHA1 | Date | |
---|---|---|---|
13595b7d83 | |||
7630ff3cb9 | |||
b0e8a7e463 | |||
daffbf4def | |||
b7469e8fc5 | |||
6198e5a746 | |||
50ad227bd5 | |||
801cba845f | |||
7208719d05 | |||
|
421015ae2d | ||
|
9d6ddf6e25 | ||
|
e0c1ad7e03 | ||
|
6fe5481363 | ||
98878bd6b6 | |||
9ac05f338b | |||
54620edeb8 | |||
3a2e419d27 | |||
c47f7d4ae8 | |||
8b72846275 | |||
4c889c28ce | |||
5f5c28b033 | |||
78d8b60f59 | |||
f0e5056de6 | |||
85803e95f1 | |||
f83c6b7988 | |||
112b745a45 | |||
d665e1f12e | |||
1e341a353a | |||
4c5d5867c7 | |||
|
06f0f40964 | ||
|
5940937f6e | ||
5916053780 | |||
ef9b330685 | |||
|
fc377e3a44 | ||
|
2b1714ed9b | ||
ac38241629 | |||
8c446eeb4b | |||
6d0a52a5df | |||
798f6de969 | |||
afb0e16596 | |||
ce3ffa7e6a | |||
ff65f260d0 | |||
a7c5db924d | |||
16abe31b34 | |||
6cae40e2e8 | |||
d32e075d3d | |||
bd71602b0a | |||
774b52e3e8 | |||
b349fe729a | |||
67f2a9f474 | |||
69ec0da893 | |||
116aae9465 | |||
|
ed57c7ec28 | ||
659237211d | |||
933fb8d435 | |||
910c6bcf2d | |||
7a3ea5ad67 | |||
e815627197 | |||
d234291a5c | |||
f4a46241cd | |||
6cd74ba294 | |||
b5aeabc813 | |||
c1a221bd8a | |||
429acc65c2 | |||
277a153a90 | |||
444efdb279 | |||
70fbe935b6 | |||
16ae62c21b | |||
a5f83748d6 | |||
6bb20f6d2d | |||
2d0e5429df | |||
3977fc4c13 | |||
4b5ae81dae | |||
03cce7edee |
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
# Ignore node_module
|
||||
**/node_modules/
|
||||
|
||||
# Ignore python stuff
|
||||
**/__pycache__
|
||||
**/.pytest_cache
|
106
.gitlab-ci.yml
Normal file
106
.gitlab-ci.yml
Normal file
@@ -0,0 +1,106 @@
|
||||
include:
|
||||
- .gitlab/*.yml
|
||||
|
||||
stages:
|
||||
- Manifest
|
||||
- Test
|
||||
- Bundle
|
||||
- Distribute
|
||||
- Release
|
||||
|
||||
variables:
|
||||
ENTRY_FOLDER: $CI_PROJECT_DIR/test # test directory for testing CI/CD, or assets directory for normal operations
|
||||
RELEASE_VERSION: v0.$CI_PIPELINE_IID
|
||||
PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE_NAME}/${RELEASE_VERSION}"
|
||||
|
||||
# Jobs from here run on Merge Requests as prerequisite for merging.
|
||||
.manifest-job:
|
||||
stage: Manifest
|
||||
image: node:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: never
|
||||
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "cicd"
|
||||
- changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- cd src/
|
||||
- npm install
|
||||
- npm run start
|
||||
- cat ${ENTRY_FOLDER}/${PACKAGE_NAME}/theme.json
|
||||
- npm run test
|
||||
artifacts:
|
||||
paths:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/theme.json
|
||||
when: on_success
|
||||
expire_in: "1 hour"
|
||||
|
||||
.test-job:
|
||||
stage: Test
|
||||
image: python:latest
|
||||
rules:
|
||||
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "cicd"
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- pip install -U pytest pillow iteration_utilities
|
||||
- python -m pytest src/test_images.py --tb=line -rA --color=yes
|
||||
allow_failure: true
|
||||
|
||||
# Jobs from here run Merged_results or Push/Merge Commits to the main branch. Tag is created on release so no run with tag creation
|
||||
.bundle-job:
|
||||
stage: Bundle
|
||||
image: javieraviles/zip:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: never
|
||||
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "cicd"
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- zip -j ${PACKAGE_NAME}.zip ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
artifacts:
|
||||
paths:
|
||||
- ${PACKAGE_NAME}.zip
|
||||
when: on_success
|
||||
expire_in: "1 hour"
|
||||
|
||||
.upload-job:
|
||||
stage: Distribute
|
||||
image: curlimages/curl:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: never
|
||||
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "cicd"
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- |
|
||||
curl --fail \
|
||||
--header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
|
||||
--upload-file ${PACKAGE_NAME}.zip "${PACKAGE_REGISTRY_URL}/${PACKAGE_NAME}.zip?select=package_file"
|
||||
|
||||
.release-job:
|
||||
stage: Release
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: never
|
||||
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "cicd"
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- echo "Releasing assets for $PACKAGE_NAME"
|
||||
release:
|
||||
name: "Release $PACKAGE_NAME $RELEASE_VERSION"
|
||||
tag_name: "$PACKAGE_NAME.$RELEASE_VERSION"
|
||||
description: "Version $RELEASE_VERSION"
|
||||
ref: "$CI_COMMIT_SHA"
|
||||
assets:
|
||||
links:
|
||||
- name: ${PACKAGE_NAME}
|
||||
url: "${PACKAGE_REGISTRY_URL}/${PACKAGE_NAME}.zip"
|
@@ -1,165 +0,0 @@
|
||||
stages:
|
||||
- Manifest
|
||||
- Test
|
||||
- Bundle
|
||||
- Distribute
|
||||
- Release
|
||||
|
||||
variables:
|
||||
ENTRY_FOLDER: "test" # test directory for testing CI/CD, or assets directory for normal operations
|
||||
RELEASE_VERSION: v0.$CI_PIPELINE_IID
|
||||
PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE_NAME}/${RELEASE_VERSION}"
|
||||
|
||||
# TODO: to reenable later
|
||||
# Jobs from here run on Merge Requests as prerequisite for merging.
|
||||
.manifest-job: &manifest
|
||||
stage: Manifest
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
changes:
|
||||
# TODO: refacto this (as Reference or something else)
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- echo generating manifest for ${ENTRY_FOLDER}/${PACKAGE_NAME}
|
||||
|
||||
# manifest-job/valid_set:
|
||||
# variables:
|
||||
# PACKAGE_NAME: "valid_set"
|
||||
# <<: *gen-manifest
|
||||
|
||||
.test-images-job: &test-images
|
||||
stage: Test
|
||||
image: python:latest
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- pip install -U pytest pillow iteration_utilities
|
||||
- python -m pytest src/test_images_job/test_wpp.py --tb=line -rA --color=yes --code-highlight=yes -q
|
||||
allow_failure: true
|
||||
|
||||
test-images-job/valid_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
<<: *test-images
|
||||
|
||||
test-images-job/missing_tag_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
<<: *test-images
|
||||
|
||||
.test-manifest-job: &test-manifest
|
||||
stage: Test
|
||||
image: node:latest
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- cd src/test_manifest_job
|
||||
- npm install ajv ajv-errors mocha mocha-steps chai
|
||||
- cd ../..
|
||||
- node src/test_manifest_job/node_modules/mocha/bin/_mocha --require mocha-steps --colors src/test_manifest_job/wpp_checker.js
|
||||
|
||||
test-manifest-job/valid_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
<<: *test-manifest
|
||||
|
||||
test-manifest-job/missing_tag_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
<<: *test-manifest
|
||||
|
||||
# Jobs from here run Merged_results or Push/Merge Commits to the main branch. Tag is created on release so no run with tag creation
|
||||
.bundle-job: &bundle
|
||||
stage: Bundle
|
||||
image: javieraviles/zip:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: never # Do not run this job when a tag is created manually
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- zip -j ${PACKAGE_NAME}.zip ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
artifacts:
|
||||
paths:
|
||||
- ${PACKAGE_NAME}.zip
|
||||
when: on_success
|
||||
expire_in: "1 hour"
|
||||
|
||||
bundle-job/valid_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
<<: *bundle
|
||||
|
||||
bundle-job/missing_tag_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
<<: *bundle
|
||||
|
||||
.upload-job: &upload
|
||||
stage: Distribute
|
||||
image: curlimages/curl:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: never # Do not run this job when a tag is created manually
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- |
|
||||
curl --fail \
|
||||
--header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
|
||||
--upload-file ${PACKAGE_NAME}.zip "${PACKAGE_REGISTRY_URL}/${PACKAGE_NAME}.zip?select=package_file"
|
||||
|
||||
upload-job/valid_set:
|
||||
needs:
|
||||
- bundle-job/valid_set
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
<<: *upload
|
||||
|
||||
upload-job/missing_tag_set:
|
||||
needs:
|
||||
- bundle-job/missing_tag_set
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
<<: *upload
|
||||
|
||||
.release-job: &release
|
||||
stage: Release
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: never # Do not run this job when a tag is created manually
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
changes:
|
||||
- ${ENTRY_FOLDER}/${PACKAGE_NAME}/*
|
||||
script:
|
||||
- echo "Releasing assets for $PACKAGE_NAME"
|
||||
release:
|
||||
name: "Release $PACKAGE_NAME $RELEASE_VERSION"
|
||||
tag_name: "$PACKAGE_NAME.$RELEASE_VERSION"
|
||||
description: "Version $RELEASE_VERSION"
|
||||
ref: "$CI_COMMIT_SHA"
|
||||
assets:
|
||||
links:
|
||||
- name: ${PACKAGE_NAME}
|
||||
url: "${PACKAGE_REGISTRY_URL}/${PACKAGE_NAME}.zip"
|
||||
|
||||
release-job/valid_set:
|
||||
needs:
|
||||
- upload-job/valid_set
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
<<: *release
|
||||
|
||||
release-job/missing_tag_set:
|
||||
needs:
|
||||
- upload-job/missing_tag_set
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
<<: *release
|
32
.gitlab/existing_valid_theme_set.yml
Normal file
32
.gitlab/existing_valid_theme_set.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
manifest-job/existing_valid_theme_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "existing_valid_theme_set"
|
||||
extends: .manifest-job
|
||||
|
||||
test-images-job/existing_valid_theme_set:
|
||||
needs:
|
||||
- manifest-job/existing_valid_theme_set
|
||||
variables:
|
||||
PACKAGE_NAME: "existing_valid_theme_set"
|
||||
extends: .test-job
|
||||
|
||||
bundle-job/existing_valid_theme_set:
|
||||
needs:
|
||||
- manifest-job/existing_valid_theme_set
|
||||
variables:
|
||||
PACKAGE_NAME: "existing_valid_theme_set"
|
||||
extends: .bundle-job
|
||||
|
||||
upload-job/existing_valid_theme_set:
|
||||
needs:
|
||||
- bundle-job/existing_valid_theme_set
|
||||
variables:
|
||||
PACKAGE_NAME: "existing_valid_theme_set"
|
||||
extends: .upload-job
|
||||
|
||||
release-job/existing_valid_theme_set:
|
||||
needs:
|
||||
- upload-job/existing_valid_theme_set
|
||||
variables:
|
||||
PACKAGE_NAME: "existing_valid_theme_set"
|
||||
extends: .release-job
|
32
.gitlab/missing_tag_set.yml
Normal file
32
.gitlab/missing_tag_set.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
manifest-job/missing_tag_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
extends: .manifest-job
|
||||
|
||||
test-images-job/missing_tag_set:
|
||||
needs:
|
||||
- manifest-job/missing_tag_set
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
extends: .test-job
|
||||
|
||||
bundle-job/missing_tag_set:
|
||||
needs:
|
||||
- manifest-job/missing_tag_set
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
extends: .bundle-job
|
||||
|
||||
upload-job/missing_tag_set:
|
||||
needs:
|
||||
- bundle-job/missing_tag_set
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
extends: .upload-job
|
||||
|
||||
release-job/missing_tag_set:
|
||||
needs:
|
||||
- upload-job/missing_tag_set
|
||||
variables:
|
||||
PACKAGE_NAME: "missing_tag_set"
|
||||
extends: .release-job
|
32
.gitlab/unbalanced_set.yml
Normal file
32
.gitlab/unbalanced_set.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
manifest-job/unbalanced_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "unbalanced_set"
|
||||
extends: .manifest-job
|
||||
|
||||
test-images-job/unbalanced_set:
|
||||
needs:
|
||||
- manifest-job/unbalanced_set
|
||||
variables:
|
||||
PACKAGE_NAME: "unbalanced_set"
|
||||
extends: .test-job
|
||||
|
||||
bundle-job/unbalanced_set:
|
||||
needs:
|
||||
- manifest-job/unbalanced_set
|
||||
variables:
|
||||
PACKAGE_NAME: "unbalanced_set"
|
||||
extends: .bundle-job
|
||||
|
||||
upload-job/unbalanced_set:
|
||||
needs:
|
||||
- bundle-job/unbalanced_set
|
||||
variables:
|
||||
PACKAGE_NAME: "unbalanced_set"
|
||||
extends: .upload-job
|
||||
|
||||
release-job/unbalanced_set:
|
||||
needs:
|
||||
- upload-job/unbalanced_set
|
||||
variables:
|
||||
PACKAGE_NAME: "unbalanced_set"
|
||||
extends: .release-job
|
32
.gitlab/valid_set.yml
Normal file
32
.gitlab/valid_set.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
manifest-job/valid_set:
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
extends: .manifest-job
|
||||
|
||||
test-images-job/valid_set:
|
||||
needs:
|
||||
- manifest-job/valid_set
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
extends: .test-job
|
||||
|
||||
bundle-job/valid_set:
|
||||
needs:
|
||||
- manifest-job/valid_set
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
extends: .bundle-job
|
||||
|
||||
upload-job/valid_set:
|
||||
needs:
|
||||
- bundle-job/valid_set
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
extends: .upload-job
|
||||
|
||||
release-job/valid_set:
|
||||
needs:
|
||||
- upload-job/valid_set
|
||||
variables:
|
||||
PACKAGE_NAME: "valid_set"
|
||||
extends: .release-job
|
115
.vscode/launch.json
vendored
Normal file
115
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Gen-Manifest Valid_set",
|
||||
"cwd": "${workspaceFolder}/src",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": [
|
||||
"run",
|
||||
"start"
|
||||
],
|
||||
"env": {
|
||||
"ENTRY_FOLDER": "${workspaceFolder}/test",
|
||||
"PACKAGE_NAME": "valid_set"
|
||||
},
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Test-Manifest Valid_set",
|
||||
"cwd": "${workspaceFolder}/src",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": [
|
||||
"run",
|
||||
"test"
|
||||
],
|
||||
"env": {
|
||||
"ENTRY_FOLDER": "${workspaceFolder}/test",
|
||||
"PACKAGE_NAME": "valid_set"
|
||||
},
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Test-Images Valid_set",
|
||||
"cwd": "${workspaceFolder}/src",
|
||||
"console": "internalConsole",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "pytest",
|
||||
"args": [
|
||||
"test_images.py",
|
||||
"-rA",
|
||||
"--tb=line",
|
||||
"--color=yes"
|
||||
],
|
||||
"env": {
|
||||
"ENTRY_FOLDER": "${workspaceFolder}/test",
|
||||
"PACKAGE_NAME": "valid_set"
|
||||
},
|
||||
"justMyCode": true
|
||||
},
|
||||
{
|
||||
"name": "Gen-Manifest existing_valid_theme_set",
|
||||
"cwd": "${workspaceFolder}/src",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": [
|
||||
"run",
|
||||
"start"
|
||||
],
|
||||
"env": {
|
||||
"ENTRY_FOLDER": "${workspaceFolder}/test",
|
||||
"PACKAGE_NAME": "existing_valid_theme_set"
|
||||
},
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Test-Manifest existing_valid_theme_set",
|
||||
"cwd": "${workspaceFolder}/src",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": [
|
||||
"run",
|
||||
"test"
|
||||
],
|
||||
"env": {
|
||||
"ENTRY_FOLDER": "${workspaceFolder}/test",
|
||||
"PACKAGE_NAME": "existing_valid_theme_set"
|
||||
},
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Test-Images existing_valid_theme_set",
|
||||
"cwd": "${workspaceFolder}/src",
|
||||
"console": "internalConsole",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "pytest",
|
||||
"args": [
|
||||
"test_images.py",
|
||||
"-rA",
|
||||
"--tb=line",
|
||||
"--color=yes"
|
||||
],
|
||||
"env": {
|
||||
"ENTRY_FOLDER": "${workspaceFolder}/test",
|
||||
"PACKAGE_NAME": "existing_valid_theme_set"
|
||||
},
|
||||
"justMyCode": true
|
||||
},
|
||||
]
|
||||
}
|
77
src/build-manifest.js
Normal file
77
src/build-manifest.js
Normal file
@@ -0,0 +1,77 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const iptc = require("node-iptc");
|
||||
const { exit } = require("process");
|
||||
|
||||
|
||||
// Fetch envs to target the right folder
|
||||
const slug = process.env["PACKAGE_NAME"];
|
||||
const root = process.env["ENTRY_FOLDER"];
|
||||
if (!slug || !root) exit(1);
|
||||
let workingDirectory = path.join(root, slug);
|
||||
|
||||
// extract metadata from them
|
||||
fs.readdir(workingDirectory, (err, files) => {
|
||||
if (err) { throw err }; // If IO error, exit with an error message
|
||||
|
||||
// If there is already a theme.json silentely exit and let mocha running afterwards
|
||||
if (files.find(file => path.extname(file) == '.json')) exit(0);
|
||||
|
||||
// construct a JSON object
|
||||
let theme = new Object();
|
||||
theme.dayImageList = [];
|
||||
theme.nightImageList = [];
|
||||
theme.sunsetImageList = [];
|
||||
theme.sunriseImageList = [];
|
||||
|
||||
// iterate each files
|
||||
files.filter(file => path.extname(file) == '.jpg').forEach(image => {
|
||||
buffer = fs.readFileSync(path.join(workingDirectory, image));
|
||||
// extract metadata
|
||||
let metadata = iptc(buffer);
|
||||
theme.imageFilename ||= metadata.special_instructions + "_*" + path.extname(image);
|
||||
theme.imageCredits ||= metadata.copyright_notice;
|
||||
theme.displayName ||= metadata.headline;
|
||||
// explore categories to find if image is dayHighlight or nightHighlight
|
||||
metadata.supplemental_categories?.forEach(cat => {
|
||||
switch (cat) {
|
||||
case "dayHighlight":
|
||||
theme.dayHighlight ||= parseInt(metadata.original_transmission_reference);
|
||||
break;
|
||||
case "nightHighlight":
|
||||
theme.nightHighlight ||= parseInt(metadata.original_transmission_reference);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
switch (metadata.category) {
|
||||
case "day":
|
||||
theme.dayImageList.push(parseInt(metadata.original_transmission_reference));
|
||||
break;
|
||||
case "night":
|
||||
case "nig":
|
||||
theme.nightImageList.push(parseInt(metadata.original_transmission_reference));
|
||||
break;
|
||||
case "sunset":
|
||||
case "twilight":
|
||||
case "twi":
|
||||
theme.sunsetImageList.push(parseInt(metadata.original_transmission_reference));
|
||||
break;
|
||||
case "sunrise":
|
||||
case "dawn":
|
||||
case "daw":
|
||||
theme.sunriseImageList.push(parseInt(metadata.original_transmission_reference));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
// make it the theme.json
|
||||
fs.writeFileSync(path.join(workingDirectory, 'theme.json'), JSON.stringify(theme));
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
86
src/json_theme_schema.jsonc
Normal file
86
src/json_theme_schema.jsonc
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"imageFilename",
|
||||
"imageCredits",
|
||||
"displayName",
|
||||
"dayImageList",
|
||||
"nightImageList"
|
||||
],
|
||||
"properties": {
|
||||
"imageFilename": {
|
||||
"type": "string"
|
||||
},
|
||||
"imageCredits": {
|
||||
"type": "string"
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string"
|
||||
},
|
||||
"dayHighlight": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"nightHighlight": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"sunriseImageList": {
|
||||
"type": "array",
|
||||
"minItems": 0,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"dayImageList": {
|
||||
"type": "array",
|
||||
"minItems": 0,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"sunsetImageList": {
|
||||
"type": "array",
|
||||
"minItems": 0,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"nightImageList": {
|
||||
"type": "array",
|
||||
"minItems": 0,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"errorMessage": {
|
||||
"required": {
|
||||
"imageFilename": "The ‘imageFilename’ property is missing.",
|
||||
"imageCredits": "The ‘imageCredits’ property is missing.",
|
||||
"displayName": "The ‘displayName’ property is missing.",
|
||||
"dayImageList": "The ‘dayImageList’ property is missing.",
|
||||
"nightImageList": "The ‘nightImageList’ property is missing."
|
||||
},
|
||||
"properties": {
|
||||
"imageFilename": "The ‘imageFilename’ property must be of type ‘string’.",
|
||||
"imageCredits": "The ‘imageCredits’ property must be of type ‘string’.",
|
||||
"displayName": "The ‘displayName’ property must be of type ‘string’.",
|
||||
"dayHighlight": "The ‘dayHighlight’ property must be a counting number.",
|
||||
"nightHighlight": "The ‘nightHighlight’ property must be a counting number.",
|
||||
"sunriseImageList": "The ‘sunriseImageList’ property must be a list of counting numbers.",
|
||||
"dayImageList": "The ‘dayImageList’ property must be a list of counting numbers.",
|
||||
"sunsetImageList": "The ‘sunsetImageList’ property must be a list of counting numbers.",
|
||||
"nightImageList": "The ‘nightImageList’ property must be a list of counting numbers."
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,19 +1,15 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { env, exit } = require("process");
|
||||
const expect = require("chai").expect;
|
||||
const Ajv = require("ajv").default;
|
||||
const ajv = new Ajv({ allErrors: true });
|
||||
require("ajv-errors")(ajv);
|
||||
|
||||
//let root, slug;
|
||||
//let workingDirectory = path.join(root, slug);
|
||||
//console.log(`👷♂️ Working with ‘${slug}’ slug.`);
|
||||
|
||||
const themeSchemaFile = "src/test_manifest_job/json_theme_schema.jsonc";
|
||||
let wppManifest;
|
||||
const themeSchemaFile = "json_theme_schema.jsonc";
|
||||
let manifest;
|
||||
let validator;
|
||||
let files;
|
||||
let workingDirectory;
|
||||
|
||||
function leftOuterJoin(leftArray, rightArray) {
|
||||
return leftArray.filter(function (el) {
|
||||
@@ -21,25 +17,25 @@ function leftOuterJoin(leftArray, rightArray) {
|
||||
}, rightArray);
|
||||
}
|
||||
|
||||
function flatReferences(wppManifest) {
|
||||
function flatReferences(manifest) {
|
||||
allImageIds = [
|
||||
wppManifest.dayHighlight,
|
||||
wppManifest.nightHighlight,
|
||||
...wppManifest.dayImageList,
|
||||
...wppManifest.nightImageList,
|
||||
...(wppManifest.sunsetImageList || []),
|
||||
...(wppManifest.sunriseImageList || [])
|
||||
manifest.dayHighlight,
|
||||
manifest.nightHighlight,
|
||||
...manifest.dayImageList,
|
||||
...manifest.nightImageList,
|
||||
...(manifest.sunsetImageList || []),
|
||||
...(manifest.sunriseImageList || [])
|
||||
];
|
||||
return allImageIds.filter(el => el !== undefined).map(el => {
|
||||
return wppManifest.imageFilename.replace("*", el);
|
||||
return manifest.imageFilename.replace("*", el);
|
||||
});
|
||||
}
|
||||
|
||||
describe('Mandatory Checks', function () {
|
||||
before(function () {
|
||||
slug = env.PACKAGE_NAME;
|
||||
const slug = process.env["PACKAGE_NAME"];
|
||||
expect(slug).to.be.a("string").that.is.not.empty;
|
||||
root = env.ENTRY_FOLDER;
|
||||
const root = process.env["ENTRY_FOLDER"];
|
||||
expect(root).to.be.a("string").that.is.not.empty;
|
||||
workingDirectory = path.join(root, slug);
|
||||
files = fs.readdirSync(workingDirectory);
|
||||
@@ -48,26 +44,26 @@ describe('Mandatory Checks', function () {
|
||||
});
|
||||
|
||||
step('Manifest is an existing json file', function () {
|
||||
wppManifest = JSON.parse(fs.readFileSync(path.join(workingDirectory, "theme.json"), "utf8"));
|
||||
manifest = JSON.parse(fs.readFileSync(path.join(workingDirectory, "theme.json"), "utf8"));
|
||||
});
|
||||
|
||||
step('Manifest passes the schema', function () {
|
||||
const isValid = validator(wppManifest);
|
||||
const isValid = validator(manifest);
|
||||
if (!isValid) expect.fail(`\n\t• ${validator.errors.map(el => { return el.message; }).join('\n\t• ')}`);
|
||||
});
|
||||
|
||||
step('There are no missing files', function () {
|
||||
let references = flatReferences(wppManifest);
|
||||
let references = flatReferences(manifest);
|
||||
references.push("theme.json");
|
||||
missings = leftOuterJoin(references, files);
|
||||
let missings = leftOuterJoin(references, files);
|
||||
expect(missings,
|
||||
`The following reference${(missings.length > 1) ? "s" : ""} from theme.json ${(missings.length > 1) ? "are" : "is"} missing in the pack. Consider adding ${(missings.length > 1) ? "them" : " it"} to the pack or removing the reference${(missings.length > 1) ? "s" : ""} from the theme.json:\n\t• ${missings.join('\n\t• ')}\n`
|
||||
).to.be.lengthOf(0,);
|
||||
});
|
||||
|
||||
step('There are no orphan files', function () {
|
||||
let references = flatReferences(wppManifest);
|
||||
orphans = leftOuterJoin(files.filter(x => x !== "theme.json"), references);
|
||||
let references = flatReferences(manifest);
|
||||
let orphans = leftOuterJoin(files.filter(x => x !== "theme.json"), references);
|
||||
expect(orphans,
|
||||
`The following orphan file${(orphans.length > 1) ? "s are" : " is"} not referenced in this theme.json. Consider removing the file${(orphans.length > 1) ? "s" : ""} or referencing ${(orphans.length > 1) ? "them" : "it"} in the theme.json:\n\t• ${orphans.join('\n\t• ')}\n`
|
||||
).to.be.lengthOf(0);
|
1066
src/package-lock.json
generated
Normal file
1066
src/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
src/package.json
Normal file
20
src/package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "build-manifest",
|
||||
"version": "1.0.0",
|
||||
"description": "Generate the manifest file of the project, based on metadata contained in the pictures.",
|
||||
"main": "build-manifest.js",
|
||||
"scripts": {
|
||||
"start": "node build-manifest.js",
|
||||
"test": "mocha --require mocha-steps --timeout 0 --colors manifest.spec.js"
|
||||
},
|
||||
"author": "Simon",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"ajv": "^8.5.0",
|
||||
"ajv-errors": "^3.0.0",
|
||||
"chai": "^4.3.4",
|
||||
"mocha": "^10.2.0",
|
||||
"mocha-steps": "^1.3.0",
|
||||
"node-iptc": "^1.0.5"
|
||||
}
|
||||
}
|
@@ -1,6 +1,5 @@
|
||||
import glob
|
||||
from PIL import Image, ImageStat
|
||||
# from _pytest.outcomes import skip
|
||||
from iteration_utilities import duplicates
|
||||
from pathlib import Path
|
||||
import json
|
||||
@@ -8,18 +7,15 @@ import os
|
||||
import pytest
|
||||
|
||||
|
||||
def validate_brightness_image(working_path, theme_config, high_light, image_list, brightness_way):
|
||||
# get a dict<filename:string, mean:int> of all images to scan them
|
||||
def _validate_brightness_image(working_path, theme_config, high_light, image_list, brightness_way):
|
||||
image_pattern = theme_config.get("imageFilename")
|
||||
|
||||
# if image_filenames is None:
|
||||
image_filenames = {}.fromkeys(glob.glob(str(Path(working_path, image_pattern))))
|
||||
|
||||
# generate an image statistics for each images
|
||||
for an_imagefile in image_filenames:
|
||||
this_image = Image.open(an_imagefile).convert("L")
|
||||
this_image_stats = ImageStat.Stat(this_image)
|
||||
image_filenames[an_imagefile] = this_image_stats.mean[0]
|
||||
#print(f'{an_imagefile} : {image_filenames[an_imagefile]}')
|
||||
|
||||
# get the brightest observed image from the list
|
||||
if high_light == "dayHighlight":
|
||||
@@ -32,7 +28,6 @@ def validate_brightness_image(working_path, theme_config, high_light, image_list
|
||||
an_image = image_pattern.replace("*", str(theme_config.get(high_light)))
|
||||
ref_est_file = str(Path(working_path, an_image))
|
||||
assert actual_est_image == ref_est_file, f"✖ {brightness_way} image is {actual_est_image}, but the {high_light} image is {ref_est_file}."
|
||||
|
||||
else:
|
||||
# if not highlight is given in theme.json, we suppose that brightest images are in the daylist
|
||||
ref_est_files = []
|
||||
@@ -40,7 +35,6 @@ def validate_brightness_image(working_path, theme_config, high_light, image_list
|
||||
an_image = image_pattern.replace('*', str(an_id))
|
||||
ref_est_files.append(str(Path(working_path, an_image)))
|
||||
assert actual_est_image in ref_est_files, f"✖ {brightness_way} image {actual_est_image} was not found in the '{image_list}' attribute."
|
||||
# print(f"✔ {brightness_way} image is {actual_est_image}, as expected.")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -61,20 +55,18 @@ def manifest(working_path):
|
||||
|
||||
|
||||
def test_brightest_image(working_path, manifest):
|
||||
validate_brightness_image(working_path, manifest, "dayHighlight", "dayImageList", "Brightest")
|
||||
_validate_brightness_image(working_path, manifest, "dayHighlight", "dayImageList", "Brightest")
|
||||
|
||||
|
||||
def test_darkest_image(working_path, manifest):
|
||||
validate_brightness_image(working_path, manifest, "nightHighlight", "nightImageList", "Darkest")
|
||||
_validate_brightness_image(working_path, manifest, "nightHighlight", "nightImageList", "Darkest")
|
||||
|
||||
|
||||
def test_image_size(working_path, manifest):
|
||||
image_filename = manifest["imageFilename"].replace("*", str(manifest["dayImageList"][0]))
|
||||
img = Image.open(Path(working_path, image_filename))
|
||||
w, h = img.size
|
||||
w, h = Image.open(Path(working_path, image_filename)).size
|
||||
assert w >= 1920 and h >= 1080, f"✖ Image size is too small (must be at least 1920×1080, is {w}×{h})"
|
||||
assert w >= h, "✖ Image orientation is portrait (must be landscape or square)"
|
||||
# print(f"✔ Images are big enough ({w}×{h}) and landscape.")
|
||||
|
||||
def test_overlapping_images(manifest):
|
||||
jointed_lists = manifest.get("dayImageList")
|
||||
@@ -86,5 +78,4 @@ def test_overlapping_images(manifest):
|
||||
str_dup_refs = [manifest["imageFilename"].replace("*", str(int)) for int in dup_refs]
|
||||
separator = ", "
|
||||
|
||||
assert not dup_refs, f"✖ Some images are referenced twice or more times: {separator.join(str_dup_refs)}."
|
||||
# print("✔ There is no overlapping references of images in the theme.json.")
|
||||
assert not dup_refs, f"✖ Some images are referenced twice or more: {separator.join(str_dup_refs)}."
|
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"required": ["imageFilename","imageCredits","displayName","dayImageList","nightImageList"],
|
||||
"properties": {
|
||||
"imageFilename": {"type": "string"},
|
||||
"imageCredits": {"type": "string"},
|
||||
"displayName": {"type": "string"},
|
||||
"dayHighlight": {"type": "integer", "minimum": 0},
|
||||
"nightHighlight": {"type": "integer", "minimum": 0},
|
||||
"sunriseImageList": {
|
||||
"type": "array",
|
||||
"minItems" : 0,
|
||||
"uniqueItems" : true,
|
||||
"items": {"type": "integer", "minimum": 0}
|
||||
},
|
||||
"dayImageList": {
|
||||
"type": "array",
|
||||
"minItems" : 0,
|
||||
"uniqueItems" : true,
|
||||
"items": {"type": "integer", "minimum": 0}
|
||||
},
|
||||
"sunsetImageList": {
|
||||
"type": "array",
|
||||
"minItems" : 0,
|
||||
"uniqueItems" : true,
|
||||
"items": {"type": "integer", "minimum": 0}
|
||||
},
|
||||
"nightImageList": {
|
||||
"type": "array",
|
||||
"minItems" : 0,
|
||||
"uniqueItems" : true,
|
||||
"items": {"type": "integer", "minimum": 0}
|
||||
}
|
||||
},
|
||||
"errorMessage": {
|
||||
"required": {
|
||||
"imageFilename":"The ‘imageFilename’ property is missing. Consider adding it.",
|
||||
"imageCredits":"The ‘imageCredits’ property is missing. Consider adding it.",
|
||||
"displayName":"The ‘displayName’ property is missing. Consider adding it.",
|
||||
"dayImageList":"The ‘dayImageList’ property is missing. Consider adding it.",
|
||||
"nightImageList":"The ‘nightImageList’ property is missing. Consider adding it."
|
||||
},
|
||||
"properties": {
|
||||
"imageFilename": "The ‘imageFilename’ property must be of type ‘string’ and reflect a glob of an image, i.e.: ‘myWallpaper_*.jpg’.",
|
||||
"imageCredits": "The ‘imageCredits’ property must be of type ‘string’.",
|
||||
"displayName": "The ‘displayName’ property must be of type ‘string’.",
|
||||
"dayHighlight": "The ‘dayHighlight’ property must be a counting number referencing an image, i.e.: ‘5’ in ‘myWallpaper_5.jpg’.",
|
||||
"nightHighlight": "The ‘nightHighlight’ property must be a counting number referencing an image, i.e.: ‘13’ in ‘myWallpaper_13.jpg’.",
|
||||
"sunriseImageList": "The ‘sunriseImageList’ property must be a list of counting numbers referencing images, i.e.: ‘[1, 2, 3, 4].’",
|
||||
"dayImageList": "The ‘dayImageList’ property must be a list of counting numbers referencing images, i.e.: ‘[1, 2, 3, 4]’.",
|
||||
"sunsetImageList": "The ‘sunsetImageList’ property must be a list of counting numbers referencing images, i.e.: ‘[1, 2, 3, 4]’.",
|
||||
"nightImageList": "The ‘nightImageList’ property must be a list of counting numbers referencing images, i.e.: ‘[1, 2, 3, 4]’."
|
||||
}
|
||||
}
|
||||
}
|
1853
src/test_manifest_job/package-lock.json
generated
1853
src/test_manifest_job/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "wppchecker",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "wppChecker.js",
|
||||
"scripts": {
|
||||
"test": "mocha wppChecker.js --require mocha-step --colors"
|
||||
},
|
||||
"author": "PtiSimon",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"ajv": "^8.5.0",
|
||||
"ajv-errors": "^3.0.0",
|
||||
"chai": "^4.3.4",
|
||||
"mocha": "^8.4.0",
|
||||
"mocha-steps": "^1.3.0"
|
||||
}
|
||||
}
|
BIN
test/existing_valid_theme_set/stray__1.jpg
Normal file
BIN
test/existing_valid_theme_set/stray__1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 346 KiB |
BIN
test/existing_valid_theme_set/stray__2.jpg
Normal file
BIN
test/existing_valid_theme_set/stray__2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 422 KiB |
13
test/existing_valid_theme_set/theme.json
Normal file
13
test/existing_valid_theme_set/theme.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"dayImageList": [
|
||||
1
|
||||
],
|
||||
"nightImageList": [
|
||||
2
|
||||
],
|
||||
"sunsetImageList": [],
|
||||
"sunriseImageList": [],
|
||||
"imageFilename": "stray__*.jpg",
|
||||
"imageCredits": "©Thoscellen, ©BlueTwelve",
|
||||
"displayName": "Stray"
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"imageFilename": "bl3_landscape_*.jpg",
|
||||
"imageCredits": "© Gearbox",
|
||||
"displayName": "",
|
||||
"displayName": "BL3",
|
||||
"dayImageList": [
|
||||
2
|
||||
],
|
||||
|
BIN
test/unbalanced_set/unbalanced_set_1.jpg
Normal file
BIN
test/unbalanced_set/unbalanced_set_1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
BIN
test/unbalanced_set/unbalanced_set_2.jpg
Normal file
BIN
test/unbalanced_set/unbalanced_set_2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 191 KiB |
BIN
test/unbalanced_set/unbalanced_set_3.jpg
Normal file
BIN
test/unbalanced_set/unbalanced_set_3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 158 KiB |
@@ -1,4 +0,0 @@
|
||||
# some descriptions
|
||||
|
||||
Introducting change for testing.
|
||||
Pipeline still won't trigger.
|
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"imageFilename": "bl2_eridum_badlands_*.jpg",
|
||||
"imageCredits": "Gearbox",
|
||||
"displayName": "",
|
||||
"dayHighlight": 1,
|
||||
"nightHighlight": 3,
|
||||
"sunriseImageList": [
|
||||
4
|
||||
],
|
||||
"dayImageList": [
|
||||
1
|
||||
],
|
||||
"sunsetImageList": [
|
||||
2
|
||||
],
|
||||
"nightImageList": [
|
||||
3
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user