Merge branch 'epic/web-core' into maint/web/build-script-perf

This commit is contained in:
Marc Durdin 2025-11-10 14:50:59 +01:00 committed by GitHub
commit a8339bd565
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
158 changed files with 1561 additions and 2686 deletions

View file

@ -13,7 +13,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
if: ${{ github.repository == 'keymanapp/keyman' && github.actor == 'keyman-server' && startsWith(github.event.pull_request.title, 'auto:') }}
if: ${{ github.repository == 'keymanapp/keyman' && github.actor == 'keyman-server' && startsWith(github.head_ref, 'auto/') }}
steps:
- name: auto approve PR from keyman-server
shell: bash
@ -23,7 +23,6 @@ jobs:
gh pr review -R keymanapp/keyman --approve ${{ github.event.pull_request.number }}
- name: mark PR for auto-merge from keyman-server
shell: bash
if: contains(github.event.pull_request.labels.*.name, 'automerge')
env:
GH_TOKEN: "${{ secrets.AUTOINC_GITHUB_TOKEN }}"
run: |

153
.github/workflows/npm-publish.yml vendored Normal file
View file

@ -0,0 +1,153 @@
#
# Keyman is copyright (C) SIL Global. MIT License.
#
# Created by mcdurdin on 2025-10-27
#
# This workflow publishes all our npm packages using Trusted Publishers OIDC
# permissions. It is triggered by a repository_dispatch event with the types
# `npm-publish:*`, from the trigger-builds infrastructure. For test builds, this
# does a `npm pack` only.
#
# Inputs:
# buildSha: The SHA of the commit to build, e.g. of the branch or
# refs/pull/1234/head for PR
# user: The user that triggered the build or created the PR
# isTestBuild: false for Releases, otherwise true
name: "npm pack/publish"
run-name: "npm pack/publish - branch: ${{ github.event.client_payload.branch }} sha: ${{ github.event.client_payload.buildSha }}, user: @${{ github.event.client_payload.user }}, isTestBuild: ${{ github.event.client_payload.isTestBuild }}"
on:
repository_dispatch:
types: ['npm-publish:*']
permissions:
id-token: write # Required for OIDC
contents: read
statuses: write
env:
GH_TOKEN: ${{ github.token }}
STATUS_CONTEXT: 'npm pack/publish'
IS_TEST_BUILD: ${{ github.event.client_payload.isTestBuild }}
# This property causes node.inc.sh to skip invocation of nvm, as otherwise, we
# end up downgrading to node v20 as of Keyman 19. See #15040 and corresponding
# change in node.inc.sh; we should be able to remove this in Keyman 20.
KEYMAN_CI_SKIP_NVM: true
jobs:
npm_publish:
name: Publish or pack @keymanapp packages
if: github.repository == 'keymanapp/keyman' || github.event.client_payload.force
runs-on: ubuntu-24.04
steps:
- name: Set env var for pack vs publish
run: |
if [[ "$IS_TEST_BUILD" == true ]]; then
echo "NPM_ACTION=pack" >> $GITHUB_ENV
else
echo "NPM_ACTION=publish" >> $GITHUB_ENV
fi
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
ref: '${{ github.event.client_payload.buildSha }}'
- name: Set pending status
id: set_status
if: github.event.client_payload.isTestBuild == 'true'
shell: bash
run: |
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
/repos/$GITHUB_REPOSITORY/statuses/${{ github.event.client_payload.buildSha }} \
-f state='pending' \
-f target_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \
-f description="npm $NPM_ACTION started" \
-f context="$STATUS_CONTEXT"
- name: Report initial npm/node versions
run: |
echo "Initial npm/node versions"
npm -v
node -v
- uses: actions/setup-node@v6
with:
node-version: '24.10'
- name: Report current npm/node versions
run: |
echo "Current npm/node versions"
npm -v
node -v
- name: Configure build environment
run: |
./resources/build/ci/npm-publish.sh configure
- name: npm pack/publish
run: |
export KEYMAN_TIER=$(cat TIER.md)
export GHA_TEST_BUILD="${{ github.event.client_payload.isTestBuild }}"
export GHA_BRANCH="${{ github.event.client_payload.branch }}"
echo "KEYMAN_TIER=$KEYMAN_TIER" >> $GITHUB_ENV
echo "GHA_TEST_BUILD=${GHA_TEST_BUILD}" >> $GITHUB_ENV
echo "GHA_BRANCH=${GHA_BRANCH}" >> $GITHUB_ENV
echo "KEYMAN_TIER: $KEYMAN_TIER"
echo "GHA_TEST_BUILD: $GHA_TEST_BUILD"
echo "GHA_BRANCH: $GHA_BRANCH"
if [[ -f ./resources/build/ci/npm-publish.sh ]]; then
./resources/build/ci/npm-publish.sh $NPM_ACTION
else
echo WARNING: npm-publish.sh is not yet available
fi
set_status:
name: Set result status on PR builds
needs: [npm_publish]
runs-on: ubuntu-latest
if: ${{ always() }}
steps:
- name: Set env var for pack vs publish
run: |
if [[ "$IS_TEST_BUILD" == true ]]; then
echo "NPM_ACTION=pack" >> $GITHUB_ENV
else
echo "NPM_ACTION=publish" >> $GITHUB_ENV
fi
- name: Set success
if: needs.npm_publish.result == 'success'
run: |
echo "RESULT=success" >> $GITHUB_ENV
echo "MSG=npm $NPM_ACTION succeeded" >> $GITHUB_ENV
- name: Set cancelled
if: needs.npm_publish.result == 'cancelled'
run: |
echo "RESULT=error" >> $GITHUB_ENV
echo "MSG=npm $NPM_ACTION cancelled" >> $GITHUB_ENV
- name: Set failure
if: needs.npm_publish.result == 'failure'
run: |
echo "RESULT=failure" >> $GITHUB_ENV
echo "MSG=npm $NPM_ACTION failed" >> $GITHUB_ENV
- name: Set final status
if: github.event.client_payload.isTestBuild == 'true'
run: |
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
/repos/$GITHUB_REPOSITORY/statuses/${{ github.event.client_payload.buildSha }} \
-f state="$RESULT" \
-f target_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \
-f description="$MSG" \
-f context="$STATUS_CONTEXT"

View file

@ -80,6 +80,8 @@ jobs:
summary += addStatus(o, 'check', status.context, status.state);
} else if(status.context == 'Ubuntu Packaging') {
summary += addStatus(o, 'build', status.context, status.state);
} else if(status.context == 'npm pack/publish') {
summary += addStatus(o, 'build', status.context, status.state);
} else if(status.context == 'check/web/file-size') {
// Ignore check/web/file-size -- we won't block automerge for this at this point
summary += addLog(`Skipping ${status.context}`);

View file

@ -1,5 +1,78 @@
# Keyman Version History
## 19.0.157 alpha 2025-11-06
* chore(common): Consolidate platformtest.js keyboard to `/common/test/keyboards/` (#15034)
* chore(common): Consolidate test9469.js keyboard to `/common/test/keyboards/` (#15053)
## 19.0.156 alpha 2025-11-05
* chore(linux): Update debian changelog (#14965)
* maint(resources): Docker container changes permissions to match the file owner uid and gid (#14900)
* fix(developer): remove package version if FollowKeyboardVersion is set in Package Editor (#15088)
* maint(windows): new timestamp server for test signing (#15091)
## 19.0.155 alpha 2025-11-03
* maint(resources): auto merge on branch name rather than label (#15084)
* change(developer): remove kmlmc and kmlmp (#15083)
## 19.0.154 alpha 2025-10-31
* chore(developer): further debugging for assertion failure (#15056)
* chore(developer): add breadcrumbs to trace sporadic crashes on exit (#15058)
* fix(developer): handle exceptions loading .keyman-touch-layout files (#15060)
* chore(developer): fix always-false nullish coalescing (#15061)
* chore(windows): upgrade VC++ projects to v143 (VS2022) (#15062)
## 19.0.153 alpha 2025-10-30
* test(developer): add kmc-analyze tests for AnalyzeOskCharacterUse output formats (#15030)
## 19.0.152 alpha 2025-10-30
* maint(resources): include sourcemaps in npm publish (#15051)
## 19.0.151 alpha 2025-10-29
* maint(resources): add repository record for all published packages (#15049)
## 19.0.150 alpha 2025-10-29
* maint(resources): set build flags for npm-publish (#15047)
## 19.0.149 alpha 2025-10-29
* maint(resources): don't report status check on release builds for npm-publish (#15045)
## 19.0.148 alpha 2025-10-29
* chore(web,android): Consolidate chirality.js test keyboard to `/common/test/resources/keyboards/` (#14989)
* maint(resources): npm publish - build all packages first (#15042)
## 19.0.147 alpha 2025-10-28
* maint(resources): move npm package publishing to GitHub Actions (#15029)
* maint(resources): use actions/setup-node to upgrade npm (#15035)
* maint(resources): use a string for version, rather than number (#15036)
* maint(resources): set env variables in npm publish GHA (#15037)
* maint(mac): minor tweaks to mac setup, using build.sh (#15028)
* maint(resources): add build and test for npm packaging and add status check results (#15038)
* maint(resources): add write permission for statuses for npm-publish (#15039)
* maint(resources): skip nvm in npm-publish script (#15041)
## 19.0.146 alpha 2025-10-27
* fix(mac): ignore non-Unicode key caps when preparing OSK (#15008)
* fix(developer): prevent ANSI keyboards crashing debugger (#15022)
* test(developer): add coverage tests for warning messages in kmc-analyze/AnalyzeOskCharacterUse (#15021)
## 19.0.145 alpha 2025-10-24
* fix(developer): do not treat backslash as a string escape in syntax highlighting (#15001)
* fix(developer): handle missing `begin Unicode` in KMW compiler (#15002)
* test(developer): add test to kmc-analyze for Warn_PreviousMapFileCouldNotBeLoaded (#14038)
## 19.0.144 alpha 2025-10-23
* chore(deps-dev): bump playwright from 1.46.1 to 1.56.1 (#14984)
@ -889,6 +962,17 @@
* refactor(windows): rename `TKeymanMutex.MutexOwned` to `TakeOwnership` and add `ReleaseOwnership` (#13168)
* chore: increment to alpha 19.0 (#13187)
## 18.0.244 stable 2025-10-31
* fix(linux): use `ibus` command to restart ibus (#14975)
* fix(android): Set the main app background white (#14982)
* fix(developer): do not treat backslash as a string escape in syntax highlighting (#15005)
* fix(developer): handle missing `begin Unicode` in KMW compiler (#15006)
* fix(mac): ignore non-Unicode key caps when preparing OSK (#15009)
* maint(resources): move NPM package publishing to GitHub Actions (#15054)
* chore(developer): add breadcrumbs to trace sporadic crashes on exit (#15059)
* chore(developer): further debugging for assertion failure (#15057)
## 18.0.243 stable 2025-10-15
* chore(linux): Update debian changelog (#14855)

View file

@ -1 +1 @@
19.0.145
19.0.158

View file

@ -1,56 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<KeymanDeveloperProject>
<Options>
<Version>2.0</Version>
<BuildPath>$PROJECTPATH</BuildPath>
<SourcePath>$PROJECTPATH\</SourcePath>
<CompilerWarningsAsErrors>True</CompilerWarningsAsErrors>
<WarnDeprecatedCode>True</WarnDeprecatedCode>
<CheckFilenameConventions>True</CheckFilenameConventions>
<SkipMetadataFiles>True</SkipMetadataFiles>
<ProjectType>lexicalmodel</ProjectType>
</Options>
<Files>
<File>
<ID>id_165fd1598b940efe4a973aeb6eb61aba</ID>
<Filename>keyboardharness.kps</Filename>
<Filepath>keyboardharness.kps</Filepath>
<FileVersion>1.0</FileVersion>
<FileType>.kps</FileType>
<Details>
<Name>keyboardharness</Name>
<Copyright>©2020 SIL International</Copyright>
<Version>1.0</Version>
</Details>
</File>
<File>
<ID>id_f9b1213d4e83cb32ce1ead1ee852d618</ID>
<Filename>chirality.js</Filename>
<Filepath>..\..\..\..\..\..\..\web\testing\chirality\chirality.js</Filepath>
<FileVersion></FileVersion>
<FileType>.js</FileType>
<ParentFileID>id_165fd1598b940efe4a973aeb6eb61aba</ParentFileID>
</File>
<File>
<ID>id_e01841691fa129428aea555142873f69</ID>
<Filename>platformtest.js</Filename>
<Filepath>..\..\..\..\..\..\..\web\testing\platform\platformtest.js</Filepath>
<FileVersion></FileVersion>
<FileType>.js</FileType>
<ParentFileID>id_165fd1598b940efe4a973aeb6eb61aba</ParentFileID>
</File>
<File>
<ID>id_03df89bb84a1aa6cab40dfebf3a04c5b</ID>
<Filename>code2001.ttf</Filename>
<Filepath>code2001.ttf</Filepath>
<FileVersion></FileVersion>
<FileType>.ttf</FileType>
<ParentFileID>id_165fd1598b940efe4a973aeb6eb61aba</ParentFileID>
</File>
<File>
<ID>id_2d07bd2b8c94e9600ac1a920c8cb9e0a</ID>
<Filename>longpress.js</Filename>
<Filepath>longpress.js</Filepath>
<FileVersion></FileVersion>
<FileType>.js</FileType>
<ParentFileID>id_165fd1598b940efe4a973aeb6eb61aba</ParentFileID>
</File>
</Files>
</KeymanDeveloperProject>

View file

@ -20,17 +20,23 @@
</Info>
<Files>
<File>
<Name>..\..\..\..\..\..\..\web\src\test\manual\web\chirality\chirality.js</Name>
<Name>../../../../../../../common/test/resources/keyboards/chirality.js</Name>
<Description>File chirality.js</Description>
<CopyLocation>0</CopyLocation>
<FileType>.js</FileType>
</File>
<File>
<Name>..\..\..\..\..\..\..\web\src\test\manual\web\platform\platformtest.js</Name>
<Name>../../../../../../../common/test/keyboards/platform-rules/platformtest.js</Name>
<Description>File platformtest.js</Description>
<CopyLocation>0</CopyLocation>
<FileType>.js</FileType>
</File>
<File>
<Name>../../../../../../../common/test/keyboards/test9469/build/test9469.js</Name>
<Description>File test9469.js</Description>
<CopyLocation>0</CopyLocation>
<FileType>.js</FileType>
</File>
<File>
<Name>code2001.ttf</Name>
<Description>Font Code2001</Description>
@ -61,6 +67,14 @@
<Language ID="en">English</Language>
</Languages>
</Keyboard>
<Keyboard>
<Name>Test9469</Name>
<ID>test9469</ID>
<Version>1.0</Version>
<Languages>
<Language ID="en">English</Language>
</Languages>
</Keyboard>
<Keyboard>
<Name>longpress '"\|5% +</Name>
<ID>longpress</ID>

View file

@ -89,6 +89,21 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
KMManager.KMDefault_KeyboardFont);
KMManager.addKeyboard(this, platformtestKBbInfo);
// Issue #9469 Verify special characters in keyamnweb-osk.ttf keyboard
Keyboard specialKBInfo = new Keyboard(
"keyboardharness",
"test9469",
"test9469 Keyboard",
"en",
"English",
"1.0",
"",
"",
true,
KMManager.KMDefault_KeyboardFont,
KMManager.KMDefault_KeyboardFont);
KMManager.addKeyboard(this, specialKBInfo);
// Final K_ENTER test keyboard
Keyboard finalKBInfo = new Keyboard(
"final",
@ -103,21 +118,6 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
KMManager.KMDefault_KeyboardFont,
KMManager.KMDefault_KeyboardFont);
KMManager.addKeyboard(this, finalKBInfo);
// Issue #9469 Verify special characters in keyamnweb-osk.ttf keyboard
Keyboard specialKBInfo = new Keyboard(
"test9469",
"test9469",
"test9469 Keyboard",
"en",
"English",
"1.0",
"",
"",
true,
KMManager.KMDefault_KeyboardFont,
KMManager.KMDefault_KeyboardFont);
KMManager.addKeyboard(this, specialKBInfo);
}
@Override

View file

@ -0,0 +1,499 @@
if (typeof keyman === 'undefined') {
console.log('Keyboard requires KeymanWeb 10.0 or later');
if (typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later");
} else {
KeymanWeb.KR(new Keyboard_platformtest());
}
function Keyboard_platformtest() {
this._v = (typeof keyman != "undefined" && typeof keyman.version == "string") ? parseInt(keyman.version, 10) : 9;
this.KI = "Keyboard_platformtest";
this.KN = "PlatformTest";
this.KMINVER = "10.0";
this.KV = null;
this.KDU = 0;
this.KH = '';
this.KM = 0;
this.KBVER = "1.0";
this.KMBM = 0x0;
this.s20 = "touch";
this.s21 = "hardware";
this.s24 = "windows";
this.s25 = "android";
this.s26 = "ios";
this.s27 = "macosx";
this.s28 = "linux";
this.s31 = "desktop";
this.s32 = "tablet";
this.s33 = "phone";
this.s36 = "native";
this.s37 = "web";
this.s40 = "ie";
this.s41 = "chrome";
this.s42 = "edge";
this.s43 = "firefox";
this.s44 = "safari";
this.s45 = "opera";
this.s48 = "touch";
this.s49 = "hardware";
this.s52 = "platform-x";
this.s55 = "WinDOWS";
this.s56 = "ANDroid";
this.s57 = "iOS";
this.s58 = "macOSX";
this.s59 = "LINUX";
this.s61 = "touch";
this.s62 = "hardware";
this.s63 = "windows";
this.s64 = "android";
this.s65 = "ios";
this.s66 = "macosx";
this.s67 = "linux";
this.s68 = "desktop";
this.s69 = "tablet";
this.s70 = "phone";
this.s71 = "native";
this.s72 = "web";
this.s73 = "ie";
this.s74 = "chrome";
this.s75 = "edge";
this.s76 = "firefox";
this.s77 = "safari";
this.s78 = "opera";
this.s79 = "touch";
this.s80 = "hardware";
this.s81 = "platform-x";
this.s82 = "WinDOWS";
this.s83 = "ANDroid";
this.s84 = "iOS";
this.s85 = "macOSX";
this.s86 = "LINUX";
this.KVER = "18.0.241.0";
this.KVS = [];
this.gs = function(t, e) {
return this.g0(t, e);
};
this.gs = function(t, e) {
return this.g0(t, e);
};
this.g0 = function(t, e) {
var k = KeymanWeb,
r = 0,
m = 0;
if (k.KKM(e, 16384, 65)) {
if (1) {
r = m = 1;
k.KDC(0, t);
r = this.g1(t, e);
m = 2;
}
}
if (!m && k.KIK(e)) {
r = 1;
k.KDC(-1, t);
r = this.g9(t, e);
m = 2;
}
return r;
};
this.g1 = function(t, e) {
var k = KeymanWeb,
r = 1,
m = 0;
if (k.KIFS(31, this.s20, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, "touch");
} else if (k.KIFS(31, this.s21, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, "hardware");
}
if (m == 1) {
k.KDC(-1, t);
r = this.g2(t, e);
m = 2;
}
if (!m) {
k.KDC(-1, t);
k.KO(-1, t, "undefined");
r = this.g2(t, e);
m = 2;
}
return r;
};
this.g2 = function(t, e) {
var k = KeymanWeb,
r = 1,
m = 0;
if (k.KIFS(31, this.s24, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " windows");
} else if (k.KIFS(31, this.s25, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " android");
} else if (k.KIFS(31, this.s26, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " ios");
} else if (k.KIFS(31, this.s27, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " macosx");
} else if (k.KIFS(31, this.s28, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " linux");
}
if (m == 1) {
k.KDC(-1, t);
r = this.g3(t, e);
m = 2;
}
if (!m) {
k.KDC(-1, t);
k.KO(-1, t, " undefined");
r = this.g3(t, e);
m = 2;
}
return r;
};
this.g3 = function(t, e) {
var k = KeymanWeb,
r = 1,
m = 0;
if (k.KIFS(31, this.s31, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " desktop");
} else if (k.KIFS(31, this.s32, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " tablet");
} else if (k.KIFS(31, this.s33, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " phone");
}
if (m == 1) {
k.KDC(-1, t);
r = this.g4(t, e);
m = 2;
}
if (!m) {
k.KDC(-1, t);
k.KO(-1, t, " undefined");
r = this.g4(t, e);
m = 2;
}
return r;
};
this.g4 = function(t, e) {
var k = KeymanWeb,
r = 1,
m = 0;
if (k.KIFS(31, this.s36, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " native");
} else if (k.KIFS(31, this.s37, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " web");
}
if (m == 1) {
k.KDC(-1, t);
r = this.g5(t, e);
m = 2;
}
if (!m) {
k.KDC(-1, t);
k.KO(-1, t, " undefined");
r = this.g5(t, e);
m = 2;
}
return r;
};
this.g5 = function(t, e) {
var k = KeymanWeb,
r = 1,
m = 0;
if (k.KIFS(31, this.s40, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " ie");
} else if (k.KIFS(31, this.s41, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " chrome");
} else if (k.KIFS(31, this.s42, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " edge");
} else if (k.KIFS(31, this.s43, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " firefox");
} else if (k.KIFS(31, this.s44, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " safari");
} else if (k.KIFS(31, this.s45, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " opera");
}
if (m == 1) {
k.KDC(-1, t);
r = this.g6(t, e);
m = 2;
}
if (!m) {
k.KDC(-1, t);
k.KO(-1, t, " undefined");
r = this.g6(t, e);
m = 2;
}
return r;
};
this.g6 = function(t, e) {
var k = KeymanWeb,
r = 1,
m = 0;
if (!k.KIFS(31, this.s48, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " !touch");
} else if (!k.KIFS(31, this.s49, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " !hardware");
}
if (m == 1) {
k.KDC(-1, t);
r = this.g7(t, e);
m = 2;
}
if (!m) {
k.KDC(-1, t);
k.KO(-1, t, " undefined");
r = this.g7(t, e);
m = 2;
}
return r;
};
this.g7 = function(t, e) {
var k = KeymanWeb,
r = 1,
m = 0;
if (k.KIFS(31, this.s52, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " platform-x");
}
if (m == 1) {
k.KDC(-1, t);
r = this.g8(t, e);
m = 2;
}
if (!m) {
k.KDC(-1, t);
k.KO(-1, t, " undefined");
r = this.g8(t, e);
m = 2;
}
return r;
};
this.g8 = function(t, e) {
var k = KeymanWeb,
r = 1,
m = 0;
if (k.KIFS(31, this.s55, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " windows");
} else if (k.KIFS(31, this.s56, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " android");
} else if (k.KIFS(31, this.s57, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " ios");
} else if (k.KIFS(31, this.s58, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " macosx");
} else if (k.KIFS(31, this.s59, t)) {
m = 1;
k.KDC(0, t);
k.KO(-1, t, " linux");
}
if (!m) {
k.KDC(-1, t);
k.KO(-1, t, " undefined");
}
return r;
};
this.g9 = function(t, e) {
var k = KeymanWeb,
r = 0,
m = 0;
if (k.KKM(e, 16384, 69)) {
if (k.KIFS(31, this.s82, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Windows");
} else if (k.KIFS(31, this.s83, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Android");
} else if (k.KIFS(31, this.s84, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " iOS");
} else if (k.KIFS(31, this.s85, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " macOS");
} else if (k.KIFS(31, this.s86, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Linux");
} else if (1) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " [OS Undefined (case insensitive test)]");
}
} else if (k.KKM(e, 16384, 73)) {
if (k.KIFS(31, this.s68, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Desktop");
} else if (k.KIFS(31, this.s69, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Tablet");
} else if (k.KIFS(31, this.s70, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Phone");
} else if (1) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " [FF Undefined]");
}
} else if (k.KKM(e, 16384, 79)) {
if (k.KIFS(31, this.s63, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Windows");
} else if (k.KIFS(31, this.s64, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Android");
} else if (k.KIFS(31, this.s65, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " iOS");
} else if (k.KIFS(31, this.s66, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " OSX");
} else if (k.KIFS(31, this.s67, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Linux");
} else if (1) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " [OS Undefined]");
}
} else if (k.KKM(e, 16384, 80)) {
if (k.KIFS(31, this.s61, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, "Touch");
} else if (k.KIFS(31, this.s62, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, "Hardware");
} else if (1) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, "[UI Undefined]");
}
} else if (k.KKM(e, 16384, 82)) {
if (k.KIFS(31, this.s81, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Platform-X");
} else if (1) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " [Platform-X Undefined]");
}
} else if (k.KKM(e, 16384, 84)) {
if (!k.KIFS(31, this.s79, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " !Touch");
} else if (!k.KIFS(31, this.s80, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " !Hardware");
} else if (1) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " [Inverted OS Undefined]");
}
} else if (k.KKM(e, 16384, 85)) {
if (k.KIFS(31, this.s71, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Native");
} else if (k.KIFS(31, this.s72, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Web");
} else if (1) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " [Nativeness Undefined]");
}
} else if (k.KKM(e, 16384, 89)) {
if (k.KIFS(31, this.s73, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " IE");
} else if (k.KIFS(31, this.s74, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Chrome");
} else if (k.KIFS(31, this.s75, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Edge");
} else if (k.KIFS(31, this.s76, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Firefox");
} else if (k.KIFS(31, this.s77, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Safari");
} else if (k.KIFS(31, this.s78, t)) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " Opera");
} else if (1) {
r = m = 1;
k.KDC(0, t);
k.KO(-1, t, " [Browser Undefined]");
}
}
return r;
};
}

Binary file not shown.

Binary file not shown.

View file

@ -4,22 +4,25 @@
<BuildPath></BuildPath>
<CompilerWarningsAsErrors>False</CompilerWarningsAsErrors>
<WarnDeprecatedCode>True</WarnDeprecatedCode>
<CheckFilenameConventions>True</CheckFilenameConventions>
<ProjectType>keyboard</ProjectType>
</Options>
<Files>
<File>
<ID>id_c1593d698cb624690005787147089dab</ID>
<Filename>platformtest.kmn</Filename>
<Filepath>platformtest.kmn</Filepath>
<Filepath>source/platformtest.kmn</Filepath>
<FileVersion>1.0</FileVersion>
<FileType>.kmn</FileType>
<Details>
<Name>PlatformTest</Name>
<Copyright>© SIL Global</Copyright>
</Details>
</File>
<File>
<ID>id_18e336f9ad890bf821ff56e1a7764478</ID>
<Filename>platformtest.kps</Filename>
<Filepath>platformtest.kps</Filepath>
<Filepath>source/platformtest.kps</Filepath>
<FileVersion></FileVersion>
<FileType>.kps</FileType>
<Details>
@ -28,8 +31,8 @@
</File>
<File>
<ID>id_61f04814d427ce02953436f3ea7d7a65</ID>
<Filename>PlatformTest.kmx</Filename>
<Filepath>PlatformTest.kmx</Filepath>
<Filename>platformtest.kmx</Filename>
<Filepath>platformtest.kmx</Filepath>
<FileVersion></FileVersion>
<FileType>.kmx</FileType>
<ParentFileID>id_18e336f9ad890bf821ff56e1a7764478</ParentFileID>

View file

@ -1,5 +1,8 @@
store(&TARGETS) 'any'
store(&VERSION) '10.0'
store(&TARGETS) 'any'
store(&NAME) 'PlatformTest'
store(&KEYBOARDVERSION) '1.0'
store(&COPYRIGHT) '© SIL Global'
begin Unicode > use(main)
group(main) using keys

View file

@ -17,16 +17,17 @@
<Info>
<Version URL=""></Version>
<Name URL="">PlatformTest</Name>
<Description URL="">Test keyboard for displaying platform information.</Description>
</Info>
<Files>
<File>
<Name>PlatformTest.kmx</Name>
<Description>Keyboard PlatformTest</Description>
<Name>../platformtest.kmx</Name>
<Description>Keyboard Platformtest</Description>
<CopyLocation>0</CopyLocation>
<FileType>.kmx</FileType>
</File>
<File>
<Name>platformtest.js</Name>
<Name>../platformtest.js</Name>
<Description>File platformtest.js</Description>
<CopyLocation>0</CopyLocation>
<FileType>.js</FileType>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,6 +1,6 @@
c test9469 generated from template at 2023-08-17 19:34:17
c with name "test9469"
store(&VERSION) '10.0'
store(&VERSION) '14.0'
store(&NAME) 'test9469'
store(&COPYRIGHT) '© 2023 SIL International'
store(&KEYBOARDVERSION) '1.1'

View file

@ -20,6 +20,7 @@
<Copyright URL="">© 2023 SIL International</Copyright>
<Author URL="">SIL International</Author>
<Version URL=""></Version>
<Description URL="">Test keyboard for displaying special characters rendered with keymanweb-osk.ttf</Description>
</Info>
<Files>
<File>

View file

@ -7,7 +7,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
################################ Main script ################################
@ -15,10 +14,7 @@ builder_describe "Build the include script for current Keyman version" \
configure \
clean \
build \
test \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
test
builder_describe_outputs \
configure "/node_modules" \
@ -56,4 +52,3 @@ export default KEYMAN_VERSION;
builder_run_action clean rm -rf version.inc.ts keyman-version.mts build/
builder_run_action configure node_select_version_and_npm_ci
builder_run_action build do_build
builder_run_action publish ci_publish_npm

View file

@ -1,5 +1,10 @@
{
"name": "@keymanapp/keyman-version",
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "common/web/keyman-version"
},
"description": "Keyman global version data",
"exports": {
".": {

View file

@ -7,16 +7,12 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Build Keyman langtags.js common module" \
"clean" \
"configure" \
"build" \
"test" \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"test"
builder_describe_outputs \
configure /common/web/langtags/src/imports/langtags.js \
@ -43,4 +39,3 @@ builder_run_action clean rm -rf ./build ./src/imports ./node_modules
builder_run_action configure do_configure
builder_run_action build tsc --build
builder_run_action test echo 'no tests for langtags'
builder_run_action publish ci_publish_npm

View file

@ -33,7 +33,8 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "common/web/langtags"
},
"sideEffects": false
}

View file

@ -8,7 +8,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/typescript.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Build Keyman common file types module" \
"@/core/include/ldml" \
@ -16,10 +15,7 @@ builder_describe "Build Keyman common file types module" \
"configure" \
"build" \
"clean" \
"test" \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"test"
builder_describe_outputs \
configure /common/web/types/src/schemas/kpj.schema.ts \
@ -87,4 +83,3 @@ builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo ./src/schem
builder_run_action configure do_configure
builder_run_action build tsc --build
builder_run_action test typescript_run_eslint_mocha_tests 60
builder_run_action publish ci_publish_npm

View file

@ -54,7 +54,8 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "common/web/types"
},
"c8": {
"all": true,

View file

@ -455,6 +455,7 @@ type
procedure DoSaveJSON(ARoot: TJSONObject); virtual;
procedure DoLoadIni(ini: TIniFile); virtual;
procedure DoSaveIni(ini: TIniFile); virtual;
procedure Cleanup; virtual;
public
Options: TPackageOptions;
StartMenu: TPackageStartMenu;
@ -1889,11 +1890,18 @@ begin
end;
end;
procedure TPackage.Cleanup;
begin
// No op in basic package
end;
procedure TPackage.SaveXML;
var
doc: IXMLDocument;
root: IXMLNode;
begin
Cleanup;
doc := NewXMLDocument;
doc.Encoding := 'utf-8';
@ -1914,6 +1922,8 @@ var
doc: IXMLDocument;
root: IXMLNode;
begin
Cleanup;
doc := NewXMLDocument;
doc.Encoding := 'utf-8';

View file

@ -4,8 +4,8 @@ rem Build agents have a separate signtime script. We don't use 'call' here so
rem executing that script will terminate this one.
if exist c:\codesign\signtime.bat c:\codesign\signtime.bat %1 %2 %3 %4 %5 %6 %7 %8
set SERVERLIST=(http://timestamp.comodoca.com/authenticode http://timestamp.verisign.com/scripts/timstamp.dll http://timestamp.globalsign.com/scripts/timestamp.dll http://tsa.starfieldtech.com)
set RFC3161SERVERLIST=(http://timestamp.comodoca.com/rfc3161)
set SERVERLIST=(http://timestamp.digicert.com http://timestamp.sectigo.com)
set RFC3161SERVERLIST=(http://timestamp.digicert.com http://timestamp.sectigo.com)
set SIGNTOOL=%1
set PFX_SHA1=%2
set PFX_SHA256=%3

View file

@ -10,17 +10,13 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Keyman ldml-keyboard-constants package" \
"@/common/web/keyman-version" \
"clean" \
"configure" \
"build" \
"test" \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"test"
builder_describe_outputs \
configure /node_modules \
@ -34,4 +30,3 @@ builder_run_action clean rm -rf ./build/
builder_run_action configure node_select_version_and_npm_ci
builder_run_action build tsc --build
# builder_run_action test # no tests at this time
builder_run_action publish ci_publish_npm

View file

@ -16,6 +16,7 @@
"scripts": {},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "core/include/ldml"
}
}

View file

@ -107,10 +107,14 @@ KMX_BOOL KMX_ProcessEvent::ProcessEvent(
if (kbd->StartGroup[BEGIN_UNICODE] == (KMX_DWORD) -1) {
DebugLog("Non-Unicode keyboards are not supported.");
DeleteInternalDebugItems();
state->debug_items().push_end(m_actions.Length(), 0);
m_core_state = nullptr;
return FALSE;
}
// TODO: what about debug_item state for all shortcut return paths below?
// TODO: this needs to be cleaned up; see #11909
switch (vkey) {
case KM_CORE_VKEY_CAPS:
if (KeyCapsLockPress(modifiers, isKeyDown))

View file

@ -42,12 +42,6 @@ title: Context Help
[kmc Command-line Options](kmc)
[kmlmc Command-line Options](kmlmc)
[kmlmi Command-line Options](kmlmi)
[kmlmp Command-line Options](kmlmp)
[Character Map](character-map)
[Message Window](messages)

View file

@ -1,5 +0,0 @@
---
title: kmlmc - Command Line Lexical Model Compiler (deprecated)
---
kmlmc has been replaced by [kmc](../reference/kmc).

View file

@ -1,5 +0,0 @@
---
title: kmlmi - Command Line Lexical Model model_info Compiler (deprecated)
---
kmlmi has been replaced by [kmc](../reference/kmc).

View file

@ -1,5 +0,0 @@
---
title: kmlmp - Command Line Lexical Model Package Compiler (deprecated)
---
kmlmp has been replaced by [kmc](../reference/kmc).

View file

@ -5,9 +5,8 @@ title: Migrating from kmcomp to kmc
`kmcomp` was the command-line compiler for Keyman Developer through version
16.0. Version 17.0 replaces `kmcomp` with `kmc`.
The lexical model command-line tooling, `kmlmc`, `kmlmp`, and `kmlmi`, are all
still present in version 17, but are deprecated, as the same tasks can be
performed with `kmc`.
The lexical model command-line tooling, `kmlmc`, `kmlmp`, and `kmlmi`, have
been removed in version 19.0; instead use `kmc`.
## Benefits
@ -99,21 +98,6 @@ kmcomp | kmc | notes
## Compiling a lexical model
`kmlmc` and `kmlmp` were separate tools in earlier versions of Keyman Developer,
for compiling lexical models and lexical model packages. They have both been
replaced with `kmc`.
Old method, using kmlmc and kmlmp:
```bash
kmlmc file.model.ts
# or specifying output filename
kmlmc -o output/path/file.model.js file.model.ts
kmlmp file.model.kps
```
New method, using kmc:
```bash
# recommended, build the model project:
kmc build .

View file

@ -84,7 +84,7 @@ in Keyman for Windows.
## kmc
node-based next generation compiler, hosts kmc, (and legacy kmlmc, kmlmp)
node-based next generation compiler, hosts kmc
### kmc-analyze - Analysis tools

View file

@ -6,8 +6,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
. "$KEYMAN_ROOT/developer/src/packages.inc.sh"
builder_describe \
"Keyman Developer" \
@ -17,7 +15,7 @@ builder_describe \
build \
test \
"api Analyze API and prepare API documentation" \
"publish Prepare files for distribution, publish symbols, publish or pack npm packages, and build installer" \
"publish Prepare files for distribution, publish symbols, and build installer" \
"install Install built programs locally" \
":common Developer common files" \
":ext Third party components" \
@ -42,9 +40,7 @@ builder_describe \
":setup Keyman Developer setup bootstrap" \
":test=test/auto Various older tests (others in each module)" \
":tike Keyman Developer IDE" \
":inst Bundled installers" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n+ Don't actually publish anything to external endpoints, just dry run"
":inst Bundled installers"
builder_describe_platform \
:ext win,delphi \
@ -76,25 +72,6 @@ fi
function do_prepublish() {
builder_heading "prepublish - verify environment before build"
#
# Make sure that package*.json have not been modified before
#
pushd "$KEYMAN_ROOT" >/dev/null
if git status --porcelain | grep -qP 'package(-lock)?\.json'; then
builder_echo "The following package.json files have been modified:"
git status --porcelain | grep -P 'package(-lock)?\.json'
builder_die "The publish action will not run until these files are checked in or reverted."
fi
popd
#
# To ensure that we cache the top-level package.json, we must call this before
# the global publish
#
ci_publish_cleanup
#
# Verify that the Delphi environment is correct for a release build
#
@ -138,44 +115,7 @@ builder_run_action api api-documenter markdown -i ../build/api -o ..
#-------------------------------------------------------------------------------------------------------------------
function do_publish() {
#--------------------------------------------------------
# TODO: Hard-coded calls to /common packages which need
# publishing; this should be able to be removed once we
# move the publish call to the top-level
local DRY_RUN= NPM_PUBLISH=
if builder_has_option --npm-publish; then
NPM_PUBLISH=--npm-publish
fi
if builder_has_option --dry-run; then
DRY_RUN=--dry-run
fi
./common/web/utils/build.sh publish $DRY_RUN $NPM_PUBLISH
../../common/web/keyman-version/build.sh publish $DRY_RUN $NPM_PUBLISH
../../common/web/langtags/build.sh publish $DRY_RUN $NPM_PUBLISH
../../common/web/types/build.sh publish $DRY_RUN $NPM_PUBLISH
../../core/include/ldml/build.sh publish $DRY_RUN $NPM_PUBLISH
# end TODO
#--------------------------------------------------------
builder_echo info "Cleaning up package.json after 'npm version'"
# And then cleanup the mess
ci_publish_cleanup
# Restore all the package.json files and package-lock.json files that
# were clobbered by 'npm version'
pushd "$KEYMAN_ROOT" >/dev/null
git checkout package.json package-lock.json '**/package.json'
popd
# TODO: Copy ../build/docs {from api action} to help.keyman.com and open PR
}
builder_run_child_actions publish
builder_run_action publish do_publish
#-------------------------------------------------------------------------------------------------------------------

View file

@ -36,6 +36,7 @@ type
TMemoSelection = record
Start, Finish: Integer;
Anchor: Integer;
function ToString: string;
end;
TKeymanDeveloperDebuggerMemo = class(TRichEdit41)
@ -107,6 +108,8 @@ end;
function TKeymanDeveloperDebuggerMemo.GetSelection: TMemoSelection;
begin
Result.Anchor := 0;
// EM_GETSEL doesn't tell us the anchor position, but we can figure
// it out with this kludge. I am not aware of side effects from this
// at this time.
@ -170,4 +173,11 @@ begin
RegisterComponents('Keyman', [TKeymanDeveloperDebuggerMemo]);
end;
{ TMemoSelection }
function TMemoSelection.ToString: string;
begin
Result := Format('%d %d %d', [Start, Finish, Anchor]);
end;
end.

View file

@ -70,6 +70,7 @@ type
procedure DoSaveJSON(ARoot: TJSONObject); override;
procedure DoLoadIni(ini: TIniFile); override;
procedure DoSaveIni(ini: TIniFile); override;
procedure Cleanup; override;
public
function KPSOptions: TKPSOptions;
@ -110,6 +111,15 @@ begin
FStrings.Assign((Source as TKPSFile).Strings);
end;
procedure TKPSFile.Cleanup;
begin
inherited;
if KPSOptions.FollowKeyboardVersion then
begin
Info.Desc[PackageInfo_Version] := '';
end;
end;
constructor TKPSFile.Create;
begin
FStrings := TStringList.Create;

View file

@ -8,7 +8,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/typescript.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Build Keyman Developer web utility module" \
"@/common/web/types" \
@ -16,10 +15,7 @@ builder_describe "Build Keyman Developer web utility module" \
"configure" \
"build" \
"api analyze API and prepare API documentation (no-op for now)" \
"test" \
publish \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"test"
builder_describe_outputs \
configure /node_modules \
@ -51,5 +47,4 @@ function do_build() {
builder_run_action clean rm -rf ./build/
builder_run_action configure node_select_version_and_npm_ci
builder_run_action build do_build
builder_run_action test typescript_run_eslint_mocha_tests 45
builder_run_action publish ci_publish_npm
builder_run_action test typescript_run_eslint_mocha_tests 40

View file

@ -43,6 +43,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/common/web/utils"
}
}

View file

@ -262,14 +262,6 @@
<File Name='README.md' Source="node\dist\README.md" />
</Component>
<Component Directory="INSTALLDIR">
<File Name='kmlmc.cmd' KeyPath="yes" Source="node\kmlmc.cmd" />
</Component>
<Component Directory="INSTALLDIR">
<File Name='kmlmp.cmd' KeyPath="yes" Source="node\kmlmp.cmd" />
</Component>
<Component Directory="INSTALLDIR">
<File Name='kmc.cmd' KeyPath="yes" Source="node\kmc.cmd" />
</Component>

View file

@ -1,4 +0,0 @@
@rem This script avoids path dependencies for node for distribution
@rem with Keyman Developer. When used on platforms other than Windows,
@rem node can be used directly with the compiler (`npm link` will setup).
@"%~dp0\node.js\node.exe" "%~dp0\kmc\kmlmc.mjs" %*

View file

@ -1,4 +0,0 @@
@rem This script avoids path dependencies for node for distribution
@rem with Keyman Developer. When used on platforms other than Windows,
@rem node can be used directly with the compiler (`npm link` will setup).
@"%~dp0\node.js\node.exe" "%~dp0\kmc\kmlmp.mjs" %*

View file

@ -8,15 +8,12 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/typescript.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Keyman Developer Compiler Analysis Tools" \
"@/common/web/types" \
"@/developer/src/kmc-kmn" \
"@/developer/src/common/web/utils" \
clean configure build api test publish \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
clean configure build api test
builder_describe_outputs \
configure /node_modules \
@ -32,4 +29,3 @@ builder_run_action configure node_select_version_and_npm_ci
builder_run_action build tsc --build
builder_run_action api api-extractor run --local --verbose
builder_run_action test typescript_run_eslint_mocha_tests 75
builder_run_action publish ci_publish_npm

View file

@ -43,6 +43,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc-analyze"
}
}

View file

@ -408,6 +408,8 @@ export class AnalyzeOskCharacterUse {
/** @internal */
public unitTestEndPoints = {
loadPreviousMap: this.loadPreviousMap.bind(this)
loadPreviousMap: this.loadPreviousMap.bind(this),
addStrings: this.addStrings.bind(this),
stringToUnicodeSequence: AnalyzeOskCharacterUse.stringToUnicodeSequence
};
}

View file

@ -0,0 +1,10 @@
{
"map": [
{
"usages": [
"U+1780",
"U+1781"
]
}
]
}

View file

@ -0,0 +1,12 @@
{
"map": [
{
"usages": [
{
"char": "U+1780",
"count": 2
}
]
}
]
}

View file

@ -0,0 +1,70 @@
/*
* Keyman is copyright (C) SIL Global. MIT License.
*/
import { assert } from 'chai';
import 'mocha';
import { AnalyzeOskCharacterUse } from '../src/osk-character-use/index.js';
import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers';
describe('AnalyzeOskCharacterUse output formats', function() {
const callbacks = new TestCompilerCallbacks();
const dummyStrings = {
'a': [{ filename: 'file1.kvks', count: 1 }],
'b': [{ filename: 'file2.kvks', count: 2 }]
};
this.beforeEach(function() {
callbacks.clear();
});
this.afterEach(function() {
if (this.currentTest?.isFailed()) {
callbacks.printMessages();
}
});
it('generates .txt format correctly', function() {
const a = new AnalyzeOskCharacterUse(callbacks, { includeCounts: true });
a.unitTestEndPoints.addStrings(['a', 'b'], 'testfile.kvks');
const txt = a.getStrings('.txt');
assert.isTrue(txt.some(line => line.includes('U+')));
assert.match(txt[0], /^U\+[A-F0-9]{4}/);
});
it('generates .md format correctly', function() {
const a = new AnalyzeOskCharacterUse(callbacks, { includeCounts: true });
(a as any)._strings = dummyStrings;
const md = a.getStrings('.md');
// test header
assert.match(md[0], /^PUA\s+\|\s+Code Points\s+\|\s+Key Caps$/);
// test data
assert.match(md[2], /^U\+[A-F0-9]{4}\s+\|\s+U\+[A-F0-9]{4}\s+\|\s+\S/);
});
it('generates .json format correctly', function() {
const a = new AnalyzeOskCharacterUse(callbacks, { includeCounts: true });
(a as any)._strings = dummyStrings;
const json = a.getStrings('.json').join('\n');
const parsed = JSON.parse(json);
assert.isArray(parsed.map);
assert.lengthOf(parsed.map, 2);
assert.equal(parsed.map[0].usages[0].filename, 'file1.kvks');
assert.equal(parsed.map[1].usages[0].filename, 'file2.kvks');
});
describe('unitTestEndPoints', function() {
it('converts BMP strings (U+0000U+FFFF) correctly', function() {
const a = new AnalyzeOskCharacterUse(callbacks);
const seq = a.unitTestEndPoints.stringToUnicodeSequence('ab');
assert.equal(seq, 'U+0061 U+0062');
});
it('converts supplementary characters (U+10000U+10FFFF) correctly', function() {
const a = new AnalyzeOskCharacterUse(callbacks);
// 😀 (U+1F600) and 🦊 (U+1F98A)
const seq = a.unitTestEndPoints.stringToUnicodeSequence('😀🦊');
assert.equal(seq, 'U+1F600 U+1F98A');
});
});
});

View file

@ -0,0 +1,60 @@
/*
* Keyman is copyright (C) SIL Global. MIT License.
*/
import { assert } from 'chai';
import 'mocha';
import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers';
import { AnalyzeOskCharacterUse } from '../src/osk-character-use/index.js';
import { AnalyzerMessages } from '../src/analyzer-messages.js';
import { makePathToFixture } from './helpers/index.js';
describe('AnalyzeOskCharacterUse warnings', function() {
const callbacks = new TestCompilerCallbacks();
const MOCK_MAP_NO_COUNTS = makePathToFixture(
'osk-character-use',
'mock-map-no-counts.json'
);
const MOCK_MAP_WITH_COUNTS = makePathToFixture(
'osk-character-use',
'mock-map-with-counts.json'
);
this.beforeEach(function() {
callbacks.clear();
});
this.afterEach(function() {
if (this.currentTest?.isFailed()) {
callbacks.printMessages();
}
});
it('warns if previous map did not include counts but includeCounts=true', function() {
const a = new AnalyzeOskCharacterUse(callbacks, {
includeCounts: true
});
const result = a.unitTestEndPoints.loadPreviousMap(MOCK_MAP_NO_COUNTS);
assert.isNotNull(result, 'Expected map to be loaded successfully');
assert.isTrue(
callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidNotIncludeCounts),
'Expected Warn_PreviousMapDidNotIncludeCounts warning'
);
});
it('warns if previous map did include counts but includeCounts=false', function() {
const a = new AnalyzeOskCharacterUse(callbacks, {
includeCounts: false
});
const result = a.unitTestEndPoints.loadPreviousMap(MOCK_MAP_WITH_COUNTS);
assert.isNotNull(result, 'Expected map to be loaded successfully');
assert.isTrue(
callbacks.hasMessage(AnalyzerMessages.WARN_PreviousMapDidIncludeCounts),
'Expected Warn_PreviousMapDidIncludeCounts warning'
);
});
});

View file

@ -11,16 +11,13 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/typescript.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Build Keyman kmc-copy module" \
"@/common/web/keyman-version" \
"@/common/web/types" \
"@/developer/src/common/web/test-helpers" \
"@/developer/src/common/web/utils" \
clean configure build api test publish \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
clean configure build api test
builder_describe_outputs \
configure /node_modules \
@ -42,5 +39,3 @@ builder_run_action api api-extractor run --local --verbose
# note: `export TEST_SAVE_FIXTURES=1` to get a copy of cloud-based fixtures saved to online/
# TODO: -skip-full
builder_run_action test typescript_run_eslint_mocha_tests 75
builder_run_action publish ci_publish_npm

View file

@ -58,6 +58,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc-copy"
}
}

View file

@ -11,7 +11,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/typescript.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Build Keyman kmc-generate module" \
"@/common/web/keyman-version" \
@ -19,9 +18,7 @@ builder_describe "Build Keyman kmc-generate module" \
"@/common/web/types" \
"@/developer/src/common/web/test-helpers" \
"@/developer/src/common/web/utils" \
clean configure build api test publish \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
clean configure build api test
builder_describe_outputs \
configure /node_modules \
@ -44,4 +41,3 @@ builder_run_action configure node_select_version_and_npm_ci
builder_run_action build do_build
builder_run_action api api-extractor run --local --verbose
builder_run_action test typescript_run_eslint_mocha_tests
builder_run_action publish ci_publish_npm

View file

@ -59,6 +59,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc-generate"
}
}

View file

@ -18,10 +18,7 @@ builder_describe "Build Keyman kmc keyboard-info Compiler module" \
"configure" \
"build" \
"api analyze API and prepare API documentation" \
"test" \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"test"
builder_describe_outputs \
configure /node_modules \
@ -39,7 +36,3 @@ builder_run_action api api-extractor run --local --verbose
builder_run_action test typescript_run_eslint_mocha_tests
#-------------------------------------------------------------------------------------------------------------------
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_run_action publish ci_publish_npm

View file

@ -43,6 +43,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc-keyboard-info"
}
}

View file

@ -11,7 +11,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/typescript.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Keyman Developer Compiler Module for .kmn to .kmx" \
"@/common/web/keyman-version" \
@ -23,10 +22,7 @@ builder_describe "Keyman Developer Compiler Module for .kmn to .kmx" \
"build" \
"clean" \
"api analyze API and prepare API documentation" \
"test" \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"test"
builder_describe_outputs \
configure /node_modules \
@ -71,7 +67,3 @@ function do_test() {
builder_run_action build do_build
builder_run_action api api-extractor run --local --verbose
builder_run_action test do_test
#-------------------------------------------------------------------------------------------------------------------
builder_run_action publish ci_publish_npm

View file

@ -61,6 +61,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc-kmn"
}
}

View file

@ -23,10 +23,7 @@ builder_describe "Keyman kmc Keyboard Compiler module" \
"api analyze API and prepare API documentation" \
"clean" \
"test" \
"build-fixtures builds test fixtures for manual examination" \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"build-fixtures builds test fixtures for manual examination"
builder_describe_outputs \
configure /developer/src/kmc-ldml/src/util/abnf/46/transform-from-required.js \
@ -90,9 +87,3 @@ builder_run_action build do_build
builder_run_action build-fixtures do_build_fixtures
builder_run_action api api-extractor run --local --verbose
builder_run_action test typescript_run_eslint_mocha_tests 90
#-------------------------------------------------------------------------------------------------------------------
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_run_action publish ci_publish_npm

View file

@ -65,6 +65,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc-ldml"
}
}

View file

@ -15,10 +15,7 @@ builder_describe "Build Keyman kmc Lexical Model model-info Compiler module" \
"configure" \
"build" \
"api analyze API and prepare API documentation" \
"test" \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"test"
builder_describe_outputs \
configure /node_modules \
@ -34,9 +31,3 @@ builder_run_action configure node_select_version_and_npm_ci
builder_run_action build tsc --build
builder_run_action api api-extractor run --local --verbose
builder_run_action test typescript_run_eslint_mocha_tests 55
#-------------------------------------------------------------------------------------------------------------------
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_run_action publish ci_publish_npm

View file

@ -48,6 +48,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc-model-info"
}
}

View file

@ -8,7 +8,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/typescript.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Keyman kmc Lexical Model Compiler module" \
"@/common/web/keyman-version" \
@ -18,10 +17,7 @@ builder_describe "Keyman kmc Lexical Model Compiler module" \
"configure" \
"build" \
"api analyze API and prepare API documentation" \
"test" \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"test"
builder_describe_outputs \
configure /node_modules \
@ -42,5 +38,3 @@ builder_run_action configure node_select_version_and_npm_ci
builder_run_action build do_build
builder_run_action api api-extractor run --local --verbose
builder_run_action test typescript_run_eslint_mocha_tests
builder_run_action publish ci_publish_npm

View file

@ -63,6 +63,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc-model"
}
}

View file

@ -11,7 +11,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/typescript.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Build Keyman kmc Package Compiler module" \
"@/common/web/keyman-version" \
@ -21,10 +20,8 @@ builder_describe "Build Keyman kmc Package Compiler module" \
"build" \
"api analyze API and prepare API documentation" \
"clean" \
"test" \
"publish publish to npm" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"test"
builder_describe_outputs \
configure /node_modules \
build /developer/src/kmc-package/build/src/main.js \
@ -39,4 +36,3 @@ builder_run_action configure node_select_version_and_npm_ci
builder_run_action build tsc --build
builder_run_action api api-extractor run --local --verbose
builder_run_action test typescript_run_eslint_mocha_tests
builder_run_action publish ci_publish_npm

View file

@ -61,6 +61,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc-package"
}
}

View file

@ -138,7 +138,7 @@ export class KmpInfWriter {
private saveKeyboards() {
// keyboards
for(let i = 0; i < this.data.keyboards?.length ?? 0; i++) {
for(let i = 0; i < (this.data.keyboards?.length ?? 0); i++) {
const keyboard = this.data.keyboards[i];
this.addSection('Keyboard'+i.toString());
this.addString('Name', keyboard.name);
@ -154,7 +154,7 @@ export class KmpInfWriter {
this.addString('DisplayFont', keyboard.displayFont);
}
for(let j = 0; j < keyboard.languages?.length ?? 0; j++) {
for(let j = 0; j < (keyboard.languages?.length ?? 0); j++) {
const language = keyboard.languages[j];
this.addString('Language'+j.toString(), language.id+','+language.name);
}

View file

@ -175,14 +175,6 @@ The temp_path must be a path outside the repository to avoid npm getting
confused by the root package.json. This is called by inst/download.in.mak
normally when building the Keyman Developer installer.
## Publishing to NPM
```shell
./build.sh publish [--dry-run]
```
Publishes the current release to NPM. This should only be run from CI.
[kmc]: https://help.keyman.com/developer/current-version/reference/kmc/cli
[file-layout]: https://help.keyman.com/developer/current-version/reference/file-layout

View file

@ -7,8 +7,6 @@ import esbuild from 'esbuild';
await esbuild.build({
entryPoints: [
'build/src/kmc.js',
'build/src/kmlmc.js',
'build/src/kmlmp.js',
],
bundle: true,
format: 'esm',

View file

@ -8,11 +8,10 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/typescript.inc.sh"
. "$KEYMAN_ROOT/developer/src/packages.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/npm-packages.inc.sh"
builder_describe "Build Keyman Keyboard Compiler kmc" \
"@/common/include" \
@ -35,10 +34,7 @@ builder_describe "Build Keyman Keyboard Compiler kmc" \
"bundle creates a bundled version of kmc" \
"api prepare compiler error documentation" \
"test run automated tests for kmc" \
publish \
"--build-path=BUILD_PATH build directory for bundle" \
"--npm-publish+ For publish, do a npm publish, not npm pack (only for CI)" \
"--dry-run,-n don't actually publish, just dry run"
"--build-path=BUILD_PATH build directory for bundle"
builder_describe_outputs \
configure /node_modules \
@ -114,4 +110,3 @@ builder_run_action build do_build
builder_run_action test do_test
builder_run_action api do_api
builder_run_action bundle do_bundle
builder_run_action publish ci_publish_npm

View file

@ -11,10 +11,8 @@
],
"scripts": {
"build": "tsc -b",
"bundle": "npm run bundle-kmc && npm run bundle-kmlmc && npm run bundle-kmlmp",
"bundle": "npm run bundle-kmc",
"bundle-kmc": "esbuild build/src/kmc.js --bundle --platform=node --target=es2022 > build/cjs-src/kmc.cjs",
"bundle-kmlmc": "esbuild build/src/kmlmc.js --bundle --platform=node --target=es2022 > build/cjs-src/kmlmc.cjs",
"bundle-kmlmp": "esbuild build/src/kmlmp.js --bundle --platform=node --target=es2022 > build/cjs-src/kmlmp.cjs",
"test": "eslint . && cd test && tsc -b && cd .. && mocha"
},
"type": "module",
@ -29,9 +27,7 @@
},
"main": "build/src/kmc.js",
"bin": {
"kmc": "build/src/kmc.js",
"kmlmc": "build/src/kmlmc.js",
"kmlmp": "build/src/kmlmp.js"
"kmc": "build/src/kmc.js"
},
"dependencies": {
"@keymanapp/common-types": "*",
@ -81,6 +77,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/keymanapp/keyman.git"
"url": "git+https://github.com/keymanapp/keyman.git",
"directory": "developer/src/kmc"
}
}

View file

@ -1,67 +0,0 @@
#!/usr/bin/env node
/**
* kmlmc - Keyman Lexical Model Compiler
*/
import { Command } from 'commander';
import { LexicalModelCompiler } from '@keymanapp/kmc-model';
import { SysExits } from './util/sysexits.js';
import KEYMAN_VERSION from "@keymanapp/keyman-version";
import { NodeCompilerCallbacks } from './util/NodeCompilerCallbacks.js';
let inputFilename: string;
const program = new Command();
/* Arguments */
program
.description('Compiles Keyman lexical models')
.version(KEYMAN_VERSION.VERSION_WITH_TAG)
.arguments('<infile>')
.action(infile => inputFilename = infile)
.option('-o, --outFile <filename>', 'where to save the resultant file');
program.parse(process.argv);
// Deal with input arguments:
if (!inputFilename) {
exitDueToUsageError('Must provide a lexical model source file.');
}
const callbacks = new NodeCompilerCallbacks({logLevel: 'info'});
const compiler = new LexicalModelCompiler();
if(!await compiler.init(callbacks, null)) {
console.error('Initialization failed.');
process.exit(SysExits.EX_DATAERR);
}
let code = null;
// Compile:
try {
code = await compiler.run(inputFilename, program.opts().outFile);
} catch(e) {
console.error(e);
process.exit(SysExits.EX_DATAERR);
}
if(!code) {
console.error('Compilation failed.')
process.exit(SysExits.EX_DATAERR);
}
// Output:
if (program.opts().outFile) {
compiler.write(code.artifacts);
} else {
// TODO(lowpri): if writing to console then log messages should all be to stderr?
const decoder = new TextDecoder();
const text = decoder.decode(code.artifacts.js.data);
console.log(text);
}
function exitDueToUsageError(message: string): never {
console.error(`${program.name()}: ${message}`);
console.error();
program.outputHelp();
return process.exit(SysExits.EX_USAGE);
}

View file

@ -1,60 +0,0 @@
#!/usr/bin/env node
/**
* kmlmp - Keyman Lexical Model Package Compiler
*/
// Note: this is a deprecated package and will be removed in Keyman 19.0
import { Command } from 'commander';
import { KmpCompiler } from '@keymanapp/kmc-package';
import { SysExits } from './util/sysexits.js';
import KEYMAN_VERSION from "@keymanapp/keyman-version";
import { NodeCompilerCallbacks } from './util/NodeCompilerCallbacks.js';
let inputFilename: string;
const program = new Command();
/* Arguments */
program
.description('Compiles Keyman lexical model packages\nDeprecated: use <kmc build> instead; will be removed in v18')
.version(KEYMAN_VERSION.VERSION_WITH_TAG)
.arguments('<infile>')
.action(infile => inputFilename = infile)
.option('-o, --outFile <filename>', 'where to save the resultant file');
program.parse(process.argv);
// Deal with input arguments:
if (!inputFilename) {
exitDueToUsageError('Must provide a lexical model package source file.');
}
const outputFilename: string = program.opts().outFile ? program.opts().outFile : inputFilename.replace(/\.kps$/, ".kmp");
//
// Run the compiler
//
const callbacks = new NodeCompilerCallbacks({logLevel: 'info'});
const kmpCompiler = new KmpCompiler();
if(!await kmpCompiler.init(callbacks, null)) {
process.exit(1);
}
const result = await kmpCompiler.run(inputFilename, outputFilename);
if(!result) {
process.exit(1);
}
if(!await kmpCompiler.write(result.artifacts)) {
console.error('Failed to write kmp file');
process.exit(1);
}
function exitDueToUsageError(message: string): never {
console.error(`${program.name()}: ${message}`);
console.error();
program.outputHelp();
return process.exit(SysExits.EX_USAGE);
}

View file

@ -1,3 +1,4 @@
import { execFileSync } from 'node:child_process';
import { assert } from 'chai';
import 'mocha';
import { makePathToFixture } from './helpers/index.js';
@ -17,8 +18,29 @@ describe('getLastGitCommitDate', function () {
assert.isNull(date);
});
function isShallowRepository() {
try {
const result = execFileSync('git', ['rev-parse', '--is-shallow-repository'], {
encoding: 'utf-8', // force a string result rather than Buffer
windowsHide: true, // on windows, we may need this to suppress a console window popup
stdio: ['pipe', 'pipe', 'pipe'] // all output via pipe, so we don't get git errors on console
});
return result.trim() == 'true';
} catch (e) {
return false;
}
}
it('should return a valid date for a specific file in the repo', async function() {
this.timeout(5000); // getLastGitCommitDate depends on git which can sometimes take longer
if(isShallowRepository()) {
// If we have a shallow clone, then the date will be the most recent
// commit date, and we'll just skip this test. For example, this happens
// on GHA checkouts by default with actions/checkout depth=1
this.skip();
}
const path = makePathToFixture('get-last-git-commit-date/README.md');
const date = getLastGitCommitDate(path);
// The expected date was manually extracted using the following command, with msec appended:

View file

@ -72,8 +72,6 @@ function do_build() {
tds2dbg "$WIN32_TARGET"
cp "$WIN32_TARGET" "$DEVELOPER_PROGRAM"
cp kmlmc.cmd "$DEVELOPER_PROGRAM"
cp kmlmp.cmd "$DEVELOPER_PROGRAM"
cp kmc.cmd "$DEVELOPER_PROGRAM"
cp "$KEYMAN_ROOT/core/build/x86/$TARGET_PATH/src/$KEYMANCORE_DLL" "$DEVELOPER_PROGRAM"
builder_if_release_build_level cp "$WIN32_TARGET_PATH/tike.dbg" "$DEVELOPER_DEBUGPATH"

View file

@ -109,7 +109,7 @@ type
procedure ResetEvents;
procedure ExecuteEvent(n: Integer);
procedure ExecuteEventAction(n: Integer);
procedure ExecuteEventAction(EventNumber: Integer);
procedure ExecuteEventRule(n: Integer);
procedure SetExecutionPointLine(ALine: Integer);
procedure SetUIStatus(const Value: TDebugUIStatus);
@ -210,6 +210,7 @@ uses
dmActionsMain,
Glossary,
Keyman.Developer.System.Project.ProjectLog,
Keyman.System.KeymanSentryClient,
Keyman.UI.Debug.CharacterGridRenderer,
KeyNames,
kmxfile,
@ -462,6 +463,10 @@ begin
modifier := modifier and not KM_CORE_MODIFIER_LCTRL;
end;
TKeymanSentryClient.Instance.Breadcrumb('default',
Format('ProcessKeyEvent: vk=%x mod=%x scan=%x beforeText="%s" beforeSelection=%s',[vkey, modifier, scan, Copy(memo.GetTextCR, 1, 256), memo.Selection.ToString]),
'debugger');
if not SetKeyEventContext then
Exit(False);
@ -598,8 +603,14 @@ end;
procedure TfrmDebug.ExecuteEvent(n: Integer);
begin
TKeymanSentryClient.Instance.Breadcrumb('default',
Format('ExecuteEvent(%d/%d): [%s]; b:%s; s:%s',
[n, FEvents.Count, FEvents[n].ToString, memo.Selection.ToString, FSavedSelection.ToString]),
'debugger');
memo.ReadOnly := False;
memo.Selection := FSavedSelection;
if FEvents[n].EventType = etAction
then ExecuteEventAction(n)
else ExecuteEventRule(n);
@ -667,7 +678,7 @@ begin
end;
procedure TfrmDebug.ExecuteEventAction(n: Integer);
procedure TfrmDebug.ExecuteEventAction(EventNumber: Integer);
type
TMemoSelectionState = record
Selection: TMemoSelection;
@ -711,24 +722,25 @@ procedure TfrmDebug.ExecuteEventAction(n: Integer);
procedure DoBackspace(BackspaceType: km_core_backspace_type; ExpectedValue: NativeUInt);
var
t: string;
m, n: Integer;
m, m1: Integer;
dk: TDeadKeyInfo;
state: TMemoSelectionState;
function AssertionMessage: string;
begin
Result := 'Assertion failed. Extra data: '+
'EventNumber='+IntToStr(EventNumber)+'; '+
'BackspaceType='+IntToStr(Ord(BackspaceType))+'; '+
'ExpectedValue=U+'+IntToHex(ExpectedValue, 4)+'; '+
'memo.SelStart='+IntToStr(memo.SelStart)+'; '+
'memo.SelLength='+IntToStr(memo.SelLength)+'; '+
'memo.Text='+Copy(memo.GetTextCR, 1, 256);
'memo.Text="'+Copy(memo.GetTextCR, 1, 256)+'"';
end;
begin
// Offset is zero-based, but string is 1-based. Beware!
state := SaveMemoSelectionState;
n := memo.SelStart;
m := n;
m1 := memo.SelStart;
m := m1;
if memo.SelLength > 0 then
begin
@ -800,7 +812,7 @@ procedure TfrmDebug.ExecuteEventAction(n: Integer);
memo.Lines.BeginUpdate;
try
memo.Text := Copy(t, 1, m) + Copy(t, n+1, MaxInt);
memo.Text := Copy(t, 1, m) + Copy(t, m1+1, MaxInt);
memo.SelStart := m;
finally
memo.Lines.EndUpdate;
@ -894,7 +906,7 @@ procedure TfrmDebug.ExecuteEventAction(n: Integer);
begin
DisableUI;
frmDebugStatus.Elements.UpdateStores(nil);
with FEvents[n].Action do
with FEvents[EventNumber].Action do
begin
case ActionType of
KM_CORE_IT_EMIT_KEYSTROKE: DoEmitKeystroke(dwData);

View file

@ -635,21 +635,21 @@ end;
procedure TfrmPackageEditor.editInfoNameChange(Sender: TObject);
begin
if FSetup > 0 then Exit;
pack.Info.Desc['Name'] := Trim(editInfoName.Text);
pack.Info.Desc[PackageInfo_Name] := Trim(editInfoName.Text);
Modified := True;
end;
procedure TfrmPackageEditor.editInfoVersionChange(Sender: TObject);
begin
if FSetup > 0 then Exit;
pack.Info.Desc['Version'] := Trim(editInfoVersion.Text);
pack.Info.Desc[PackageInfo_Version] := Trim(editInfoVersion.Text);
Modified := True;
end;
procedure TfrmPackageEditor.editInfoCopyrightChange(Sender: TObject);
begin
if FSetup > 0 then Exit;
pack.Info.Desc['Copyright'] := Trim(editInfoCopyright.Text);
pack.Info.Desc[PackageInfo_Copyright] := Trim(editInfoCopyright.Text);
Modified := True;
end;
@ -663,7 +663,7 @@ end;
procedure TfrmPackageEditor.editInfoAuthorChange(Sender: TObject);
begin
if FSetup > 0 then Exit;
pack.Info.Desc['Author'] := Trim(editInfoAuthor.Text);
pack.Info.Desc[PackageInfo_Author] := Trim(editInfoAuthor.Text);
Modified := True;
end;
@ -671,16 +671,16 @@ procedure TfrmPackageEditor.editInfoEmailChange(Sender: TObject);
begin
if FSetup > 0 then Exit;
if Trim(editInfoEmail.Text) = ''
then pack.Info.URL['Author'] := ''
else pack.Info.URL['Author'] := 'mailto:'+Trim(editInfoEmail.Text);
then pack.Info.URL[PackageInfo_Author] := ''
else pack.Info.URL[PackageInfo_Author] := 'mailto:'+Trim(editInfoEmail.Text);
Modified := True;
end;
procedure TfrmPackageEditor.editInfoWebSiteChange(Sender: TObject);
begin
if FSetup > 0 then Exit;
pack.Info.Desc['WebSite'] := Trim(editInfoWebSite.Text);
pack.Info.URL['WebSite'] := Trim(editInfoWebSite.Text);
pack.Info.Desc[PackageInfo_WebSite] := Trim(editInfoWebSite.Text);
pack.Info.URL[PackageInfo_WebSite] := Trim(editInfoWebSite.Text);
Modified := True;
end;
@ -734,7 +734,7 @@ begin
try
f.Description := 'Keyboard '+ki.KeyboardName;
// Fill in some info stuff as well...
if pack.Info.Desc[PackageInfo_Version] = '' then // I4690
if not pack.KPSOptions.FollowKeyboardVersion and (pack.Info.Desc[PackageInfo_Version] = '') then // I4690
begin
pack.Info.Desc[PackageInfo_Version] := ki.KeyboardVersion;
end;
@ -1021,6 +1021,11 @@ procedure TfrmPackageEditor.chkFollowKeyboardVersionClick(Sender: TObject);
begin
if FSetup > 0 then Exit;
pack.KPSOptions.FollowKeyboardVersion := chkFollowKeyboardVersion.Checked;
if chkFollowKeyboardVersion.Checked then
begin
editInfoVersion.Text := '';
pack.Info.Desc[PackageInfo_Version] := '';
end;
EnableDetailsTabControls;
Modified := True;
end;
@ -1082,7 +1087,7 @@ end;
procedure TfrmPackageEditor.memoInfoDescriptionChange(Sender: TObject);
begin
if FSetup > 0 then Exit;
pack.Info.Desc['Description'] := Trim(memoInfoDescription.Text);
pack.Info.Desc[PackageInfo_Description] := Trim(memoInfoDescription.Text);
Modified := True;
end;

View file

@ -62,6 +62,7 @@ type
public
constructor Create;
destructor Destroy; override;
function ToString: string; override;
property Action: TDebugEventActionData read FAction;
property Rule: TDebugEventRuleData read FRule;
property EventType: TDebugEventType read FEventType write SetEventType;
@ -94,6 +95,8 @@ type
vk: uint16_t;
modifier_state: uint16_t
): Boolean; overload;
function ToString: string; override;
end;
implementation
@ -134,6 +137,23 @@ begin
end;
end;
function TDebugEvent.ToString: string;
begin
// Debug string
if FEventType = etAction then
begin
Result := Format('A %d %d %d "%s"', [Ord(FAction.ActionType), FAction.dwData, FAction.nExpectedValue, FAction.Text]);
end
else if FEventType = etRuleMatch then
begin
Result := Format('R %d %x %x %d "%s"', [FRule.ItemType, FRule.Key.VirtualKey, FRule.Key.Modifiers, FRule.Line, FRule.Context]);
end
else
begin
Result := '?'+IntToStr(Ord(FEventType));
end;
end;
function TDebugEventList.AddActionItem(key: Word; action: pkm_core_action_item): Boolean;
begin
Result := True;
@ -330,6 +350,15 @@ begin
end;
end;
function TDebugEventList.ToString: string;
var
I: Integer;
begin
Result := '';
for I := 0 to Count - 1 do
Result := Result + '['+IntToStr(I)+': '+Items[I].ToString + '] ';
end;
function TDebugEventList.AddStateItems(
state: pkm_core_state;
vk: uint16_t;
@ -342,8 +371,18 @@ var
action_index: Integer;
begin
Result := True;
if not Assigned(state) then
raise Exception.Create('TDebugEventList.AddStateItems: expected state not to be nil');
debug := km_core_state_debug_items(state, nil);
if not Assigned(debug) then
raise Exception.Create('TDebugEventList.AddStateItems: expected debug not to be nil');
action := km_core_state_action_items(state, nil);
if not Assigned(action) then
raise Exception.Create('TDebugEventList.AddStateItems: expected action not to be nil');
action_index := 0;
while debug._type <> KM_CORE_DEBUG_END do
begin

View file

@ -56,6 +56,7 @@ uses
Xml.XMLDoc,
Xml.XMLIntf,
Keyman.System.KeymanSentryClient,
RedistFiles;
{ TAppSourceHttpResponder }
@ -145,6 +146,7 @@ begin
begin
AResponseInfo.ContentType := 'application/json';
AResponseInfo.Charset := 'UTF-8';
TKeymanSentryClient.Breadcrumb('default', Format('RespondTouchEditorState: Filename=%s[#state]', [AFilename]), 'AppSourceHttpResponder');
if TryGetSource(AFilename + '#state', FData)
then AResponseInfo.ContentText := FData
else AResponseInfo.ContentText := '{}';
@ -167,6 +169,7 @@ var
FData: string;
begin
// TODO: data will be passed separate call from touch editor later
TKeymanSentryClient.Breadcrumb('default', Format('RespondTouchEditor: Filename=%s', [AFilename]), 'AppSourceHttpResponder');
if not TryGetSource(AFilename, FData) then
begin
Respond404(AContext, ARequestInfo, AResponseInfo);
@ -216,6 +219,8 @@ var
begin
T := FSources.LockList;
try
TKeymanSentryClient.Breadcrumb('default', Format('TrySetSource: Filename=%s count=%d', [Filename, T.Count]), 'AppSourceHttpResponder');
for i := 0 to T.Count - 1 do
if T[i].Filename = Filename then
begin
@ -236,6 +241,7 @@ procedure TAppSourceHttpResponder.RespondGet(const AFilename: string;
var
FData: string;
begin
TKeymanSentryClient.Breadcrumb('default', Format('RespondGet: Filename=%s', [AFilename]), 'AppSourceHttpResponder');
if TryGetSource(AFilename, FData) then
begin
AResponseInfo.ContentType := 'application/json';
@ -267,6 +273,7 @@ var
begin
T := FSources.LockList;
try
TKeymanSentryClient.Breadcrumb('default', Format('TryGetSource: Filename=%s count=%d', [Filename, T.Count]), 'AppSourceHttpResponder');
for i := 0 to T.Count - 1 do
if T[i].Filename = Filename then
begin
@ -281,6 +288,7 @@ end;
function TAppSourceHttpResponder.GetSource(const Filename: string): string;
begin
TKeymanSentryClient.Breadcrumb('default', Format('GetSource: Filename=%s', [Filename]), 'AppSourceHttpResponder');
Assert(TryGetSource(Filename, Result),
'TAppSourceHttpResponder.GetSource was asked for a file that was not registered: '+Filename);
end;
@ -289,6 +297,7 @@ function TAppSourceHttpResponder.IsSourceRegistered(const Filename: string): Boo
var
Data: string;
begin
TKeymanSentryClient.Breadcrumb('default', Format('IsSourceRegistered: Filename=%s', [Filename]), 'AppSourceHttpResponder');
Result := TryGetSource(Filename, Data);
end;
@ -300,6 +309,8 @@ var
begin
T := FSources.LockList;
try
TKeymanSentryClient.Breadcrumb('default', Format('RegisterSource: Filename=%s Update=%s count=%d', [Filename, BoolToStr(Update,True), T.Count]), 'AppSourceHttpResponder');
S.Filename := Filename;
S.Data := Data;
@ -326,6 +337,7 @@ var
begin
T := FSources.LockList;
try
TKeymanSentryClient.Breadcrumb('default', Format('UnregisterSource: Filename=%s count=%d', [Filename, T.Count]), 'AppSourceHttpResponder');
for i := 0 to T.Count - 1 do
if T[i].Filename = Filename then
begin

View file

@ -1,20 +0,0 @@
@echo off
setlocal
rem This script is based on /developer/src/node/inst/kmlmc.cmd. It is stored here
rem in order to allow TIKE to call out to the compiler while debugging.
if exist "%~dp0..\inst\node\dist\node.exe" (
rem If running in developer/src/tike/:
set nodeexe="%~dp0..\inst\node\dist\node.exe"
set nodecli="%~dp0..\kmc\build\src\kmlmc.js"
) else if exist "%~dp0..\src\inst\node\dist\node.exe" (
rem If running in developer/bin/:
set nodeexe="%~dp0..\src\inst\node\dist\node.exe"
set nodecli="%~dp0..\src\kmc\build\src\kmlmc.js"
) else (
rem Cannot find node or kmlmc.js relative to execution path
echo Error: node.exe or kmlmc.js not found.
exit /b 1
)
%nodeexe% --enable-source-maps %nodecli% %*
exit /b %errorlevel%

View file

@ -1,20 +0,0 @@
@echo off
setlocal
rem This script is based on /developer/src/node/inst/kmlmp.cmd. It is stored here
rem in order to allow TIKE to call out to the compiler while debugging.
if exist "%~dp0..\inst\node\dist\node.exe" (
rem If running in developer/src/tike/:
set nodeexe="%~dp0..\inst\node\dist\node.exe"
set nodecli="%~dp0..\kmc\build\src\kmlmp.js"
) else if exist "%~dp0..\src\inst\node\dist\node.exe" (
rem If running in developer/bin/:
set nodeexe="%~dp0..\src\inst\node\dist\node.exe"
set nodecli="%~dp0..\src\kmc\build\src\kmlmp.js"
) else (
rem Cannot find node or kmlmp.js relative to execution path
echo Error: node.exe or kmlmp.js not found.
exit /b 1
)
%nodeexe% --enable-source-maps %nodecli% %*
exit /b %errorlevel%

View file

@ -355,8 +355,16 @@ begin
with TStringList.Create do
try
LoadFromFile(FBaseFileName, TEncoding.UTF8);
FNewLayoutJS := Text;
try
LoadFromFile(FBaseFileName, TEncoding.UTF8);
FNewLayoutJS := Text;
except
on E:Exception do
begin
ShowMessage(E.Message);
Exit(False);
end;
end;
finally
Free;
end;

Some files were not shown because too many files have changed in this diff Show more