mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-21 07:47:40 +00:00
Merge branch 'master' into feat/windows/13566/check-metered-connection
This commit is contained in:
commit
cc8b4d2426
17 changed files with 154 additions and 18 deletions
|
|
@ -119,7 +119,7 @@ jobs:
|
|||
- name: Install meson
|
||||
shell: bash
|
||||
run: |
|
||||
pip3 install --user meson==1.10.1
|
||||
pip3 install --user meson==1.11.0
|
||||
|
||||
- name: Run test
|
||||
shell: bash
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
# Keyman Version History
|
||||
|
||||
## 19.0.246 alpha 2026-06-15
|
||||
|
||||
* feat(developer): run project validation from IDE (#16076)
|
||||
* fix(core): use meson subsystem and needs_exe_wrapper for cross builds on Windows (#16088)
|
||||
* docs(windows): add context documentation for additional Advanced options (#16089)
|
||||
|
||||
## 19.0.245 alpha 2026-06-10
|
||||
|
||||
* chore(web): hide KMX keyboard test page (#16083)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
19.0.246
|
||||
19.0.247
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
[host_machine]
|
||||
system = 'windows'
|
||||
subsystem = 'windows'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'arm64'
|
||||
endian = 'little'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
[host_machine]
|
||||
system = 'windows'
|
||||
subsystem = 'windows'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
|
|
@ -11,3 +12,6 @@ ar = 'lib'
|
|||
ld = 'link'
|
||||
strip = 'llvm-strip'
|
||||
pkgconfig = 'pkg-config'
|
||||
|
||||
[properties]
|
||||
needs_exe_wrapper = false
|
||||
|
|
|
|||
|
|
@ -198,6 +198,13 @@ The following parameters are available:
|
|||
project (which can also be controlled at a project level with the
|
||||
`skipMetadataFiles` option). This option is only valid for compiling projects.
|
||||
|
||||
`--publish-only`
|
||||
|
||||
: Skip building component files within a project, and only run the validation
|
||||
step. Must be combined with `--for-publishing` in order to have an effect.
|
||||
This option is only valid for compiling projects, and is mostly intended for
|
||||
use by the IDE. Will fail if build artifacts for components are not present.
|
||||
|
||||
### Examples
|
||||
|
||||
```shell
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ export function declareBuild(program: Command) {
|
|||
buildCommand.command('file [infile...]', {isDefault: true})
|
||||
.description(`Compile one or more source files or projects ('file' subcommand is default).`)
|
||||
.option('--for-publishing', 'Verify that project meets @keymanapp repository requirements')
|
||||
.option('--publish-only', 'Only run the for-publishing validation, skip all other build steps')
|
||||
.addHelpText('after', `
|
||||
Supported file types:
|
||||
* folder: Keyman project in folder
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export class BuildKeyboardInfo extends BuildActivity {
|
|||
sourcePath: calculateSourcePath(infile),
|
||||
lastCommitDate,
|
||||
forPublishing: !!options.forPublishing,
|
||||
publishOnly: !!options.publishOnly,
|
||||
};
|
||||
// Note: should we always ignore the passed-in output filename for .keyboard_info?
|
||||
const outputFilename = project.getOutputFilePath(KeymanFileTypes.Binary.KeyboardInfo);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export class BuildModelInfo extends BuildActivity {
|
|||
kpsFilename: project.resolveInputFilePath(kps),
|
||||
lastCommitDate,
|
||||
forPublishing: !!options.forPublishing,
|
||||
publishOnly: !!options.publishOnly,
|
||||
};
|
||||
|
||||
// Note: should we always ignore the passed-in output filename for .model_info?
|
||||
|
|
|
|||
|
|
@ -51,15 +51,17 @@ class ProjectBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
// Go through the various file types and build them
|
||||
for(const builder of buildActivities) {
|
||||
if(builder.sourceExtension == KeymanFileTypes.Source.Project) {
|
||||
// We don't support nested projects
|
||||
continue;
|
||||
}
|
||||
if(!this.options.publishOnly) {
|
||||
// Go through the various file types and build them
|
||||
for(const builder of buildActivities) {
|
||||
if(builder.sourceExtension == KeymanFileTypes.Source.Project) {
|
||||
// We don't support nested projects
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!await this.buildProjectTargets(builder)) {
|
||||
return false;
|
||||
if(!await this.buildProjectTargets(builder)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +115,11 @@ class ProjectBuilder {
|
|||
|
||||
const buildFilename = path.relative(process.cwd(), infile).replace(/\\/g, '/');
|
||||
const callbacks = new CompilerFileCallbacks(buildFilename, options, this.callbacks);
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_BuildingFile({filename: infile, relativeFilename:buildFilename}));
|
||||
if(activity.sourceExtension == KeymanFileTypes.Source.Project) {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_ValidatingProject({filename: infile, relativeFilename:buildFilename}));
|
||||
} else {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_BuildingFile({filename: infile, relativeFilename:buildFilename}));
|
||||
}
|
||||
|
||||
fs.mkdirSync(path.dirname(outfile), {recursive:true});
|
||||
|
||||
|
|
@ -123,12 +129,19 @@ class ProjectBuilder {
|
|||
// note: command line option here, if set, overrides project setting
|
||||
result = result && !callbacks.hasFailureMessage(this.options.compilerWarningsAsErrors ?? this.project.options.compilerWarningsAsErrors);
|
||||
|
||||
if(result) {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_FileBuiltSuccessfully({filename: infile, relativeFilename:buildFilename}));
|
||||
if(activity.sourceExtension == KeymanFileTypes.Source.Project) {
|
||||
if(result) {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_ProjectValidatedSuccessfully({filename: infile, relativeFilename:buildFilename}));
|
||||
} else {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_ProjectNotValidatedSuccessfully({filename: infile, relativeFilename:buildFilename}));
|
||||
}
|
||||
} else {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_FileNotBuiltSuccessfully({filename: infile, relativeFilename: buildFilename}));
|
||||
if(result) {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_FileBuiltSuccessfully({filename: infile, relativeFilename:buildFilename}));
|
||||
} else {
|
||||
callbacks.reportMessage(InfrastructureMessages.Info_FileNotBuiltSuccessfully({filename: infile, relativeFilename: buildFilename}));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,5 +197,26 @@ export class InfrastructureMessages {
|
|||
`Failed to generate new project '${def(o.id)}'.`,
|
||||
)});
|
||||
|
||||
// For this message, we override the filename with the passed-in file. A bit of a hack but does the job
|
||||
static INFO_ValidatingProject = SevInfo | 0x0029;
|
||||
static Info_ValidatingProject = (o:{filename:string,relativeFilename:string}) => ({filename:o.filename, ...m(
|
||||
this.INFO_ValidatingProject,
|
||||
`Validating ${def(o.relativeFilename)}`,
|
||||
)});
|
||||
|
||||
// For this message, we override the filename with the passed-in file. A bit of a hack but does the job
|
||||
static INFO_ProjectValidatedSuccessfully = SevInfo | 0x002A;
|
||||
static Info_ProjectValidatedSuccessfully = (o:{filename:string,relativeFilename:string}) => ({filename:o.filename, ...m(
|
||||
this.INFO_ProjectValidatedSuccessfully,
|
||||
`${def(o.relativeFilename)} validated successfully.`,
|
||||
)});
|
||||
|
||||
// For this message, we override the filename with the passed-in file. A bit of a hack but does the job
|
||||
static INFO_ProjectNotValidatedSuccessfully = SevInfo | 0x002B;
|
||||
static Info_ProjectNotValidatedSuccessfully = (o:{filename:string,relativeFilename:string}) => ({filename:o.filename, ...m(
|
||||
this.INFO_ProjectNotValidatedSuccessfully,
|
||||
`${def(o.relativeFilename)} failed to validate.`
|
||||
)});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -242,22 +242,26 @@ export class NodeCompilerCallbacks implements CompilerCallbacks {
|
|||
* We treat a few certain infrastructure messages with special colours
|
||||
* @param event
|
||||
* @returns
|
||||
* Keep in sync with: UfrmMessages.pas, TfrmMessages.Add
|
||||
*/
|
||||
messageSpecialColor(event: CompilerEvent) {
|
||||
switch(event.code) {
|
||||
case InfrastructureMessages.INFO_BuildingFile:
|
||||
case InfrastructureMessages.INFO_CopyingProject:
|
||||
case InfrastructureMessages.INFO_GeneratingProject:
|
||||
case InfrastructureMessages.INFO_ValidatingProject:
|
||||
return color.whiteBright;
|
||||
case InfrastructureMessages.INFO_FileNotBuiltSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectNotBuiltSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectNotCopiedSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectNotGeneratedSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectNotValidatedSuccessfully:
|
||||
return color.red;
|
||||
case InfrastructureMessages.INFO_FileBuiltSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectBuiltSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectCopiedSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectGeneratedSuccessfully:
|
||||
case InfrastructureMessages.INFO_ProjectValidatedSuccessfully:
|
||||
return color.green;
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ export interface ExtendedCompilerOptions extends CompilerOptions {
|
|||
* MIT
|
||||
*/
|
||||
forPublishing?: boolean;
|
||||
/**
|
||||
* Do not build components, just do the publish phase for the project. This is
|
||||
* used mostly by Keyman Developer IDE, which will run the .keyboard_info /
|
||||
* .package_info validation and compilation step if skipMetadataFiles is true.
|
||||
*/
|
||||
publishOnly?: boolean;
|
||||
/**
|
||||
* Overrides for message reporting
|
||||
*/
|
||||
|
|
@ -198,6 +204,7 @@ export function commanderOptionsToCompilerOptions(options: any, callbacks: Compi
|
|||
warnDeprecatedCode: options.warnDeprecatedCode,
|
||||
// ExtendedOptions
|
||||
forPublishing: options.forPublishing,
|
||||
publishOnly: options.publishOnly,
|
||||
messageOverrides: overrides,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ type
|
|||
function Run(const parameters: TArray<string>; const path, logFilename: string; Callback: TUtilExecuteCallbackEvent): Boolean;
|
||||
public
|
||||
function Compile(ProjectFile: TProjectFile; const infile, outfile: string; debug: Boolean; Callback: TUtilExecuteCallbackEvent = nil): Boolean;
|
||||
function CompileForPublishing(ProjectFile: TProjectFile; const projectFilename: string; debug: Boolean; Callback: TUtilExecuteCallbackEvent = nil): Boolean;
|
||||
function Copy(const source, dest, cwd: string; relocateExternal: Boolean; Callback: TUtilExecuteCallbackEvent = nil): Boolean;
|
||||
end;
|
||||
|
||||
|
|
@ -39,6 +40,39 @@ uses
|
|||
|
||||
{ TKmcWrapper }
|
||||
|
||||
function TKmcWrapper.CompileForPublishing(
|
||||
ProjectFile: TProjectFile;
|
||||
const projectFilename: string;
|
||||
debug: Boolean;
|
||||
Callback: TUtilExecuteCallbackEvent
|
||||
): Boolean;
|
||||
var
|
||||
cmdline: TArray<string>;
|
||||
begin
|
||||
cmdline := [
|
||||
'build',
|
||||
'--log-format', 'tsv',
|
||||
'--log-level', 'info',
|
||||
'--for-publishing',
|
||||
'--publish-only',
|
||||
projectFilename
|
||||
];
|
||||
|
||||
if Assigned(FGlobalProject) and (FGlobalProject.Options.CompilerWarningsAsErrors) then
|
||||
cmdline := cmdline + ['--compiler-warnings-as-errors']
|
||||
else
|
||||
cmdline := cmdline + ['--no-compiler-warnings-as-errors'];
|
||||
|
||||
if Assigned(FGlobalProject) and (not FGlobalProject.Options.WarnDeprecatedCode) then
|
||||
cmdline := cmdline + ['--no-warn-deprecated-code'];
|
||||
|
||||
if debug then
|
||||
cmdline := cmdline + ['--debug'];
|
||||
|
||||
Result := Run(cmdline, ExtractFileDir(projectFilename), projectFilename, Callback);
|
||||
end;
|
||||
|
||||
|
||||
function TKmcWrapper.Compile(
|
||||
ProjectFile: TProjectFile;
|
||||
const infile: string;
|
||||
|
|
|
|||
|
|
@ -170,6 +170,12 @@ const // ABGR - text on white bg, Colors similar to Light+ VSCode color theme
|
|||
INFO_FileNotBuiltSuccessfully = NAMESPACE_Infrastructure or $0007;
|
||||
INFO_ProjectBuiltSuccessfully = NAMESPACE_Infrastructure or $000B;
|
||||
INFO_ProjectNotBuiltSuccessfully = NAMESPACE_Infrastructure or $000C;
|
||||
INFO_ProjectCopiedSuccessfully = NAMESPACE_Infrastructure or $0024;
|
||||
INFO_ProjectNotCopiedSuccessfully = NAMESPACE_Infrastructure or $0025;
|
||||
INFO_ProjectGeneratedSuccessfully = NAMESPACE_Infrastructure or $0027;
|
||||
INFO_ProjectNotGeneratedSuccessfully = NAMESPACE_Infrastructure or $0028;
|
||||
INFO_ProjectValidatedSuccessfully = NAMESPACE_Infrastructure or $002A;
|
||||
INFO_ProjectNotValidatedSuccessfully = NAMESPACE_Infrastructure or $002B;
|
||||
|
||||
Segment_Filename = 0;
|
||||
Segment_Filename_Separator = 1;
|
||||
|
|
@ -254,12 +260,18 @@ begin
|
|||
FColor := clBlack;
|
||||
FTextColor := Color_Text;
|
||||
|
||||
// Override formatting for 4 known messages
|
||||
// Override formatting for known messages -- keep in sync with messageSpecialColor() in NodeCompilerCallbacks.ts
|
||||
if (MsgCode = INFO_FileBuiltSuccessfully) or
|
||||
(MsgCode = INFO_ProjectBuiltSuccessfully) then
|
||||
(MsgCode = INFO_ProjectBuiltSuccessfully) or
|
||||
(MsgCode = INFO_ProjectCopiedSuccessfully) or
|
||||
(MsgCode = INFO_ProjectGeneratedSuccessfully) or
|
||||
(MsgCode = INFO_ProjectValidatedSuccessfully) then
|
||||
state := plsSuccess
|
||||
else if (MsgCode = INFO_FileNotBuiltSuccessfully) or
|
||||
(MsgCode = INFO_ProjectNotBuiltSuccessfully) then
|
||||
(MsgCode = INFO_ProjectNotBuiltSuccessfully) or
|
||||
(MsgCode = INFO_ProjectNotCopiedSuccessfully) or
|
||||
(MsgCode = INFO_ProjectNotGeneratedSuccessfully) or
|
||||
(MsgCode = INFO_ProjectNotValidatedSuccessfully) then
|
||||
state := plsFailure;
|
||||
|
||||
case state of
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ begin
|
|||
w := TKmcWrapper.Create;
|
||||
try
|
||||
Result := w.Compile(Self, FileName, TargetFilename, False);
|
||||
if not OwnerProject.Options.SkipMetadataFiles then
|
||||
Result := Result and w.CompileForPublishing(Self, OwnerProject.FileName, False);
|
||||
// TODO(lowpri): FDebug flag
|
||||
finally
|
||||
w.Free;
|
||||
|
|
|
|||
|
|
@ -180,6 +180,28 @@ To open the Options tab of Keyman Configuration:
|
|||
log on for short and isolated tests as specifically requested by
|
||||
Keyman Technical Support.
|
||||
|
||||
- Proxy Settings
|
||||
|
||||
In some environments, you may need to configure proxy settings in
|
||||
order to download keyboards or updates for Keyman. Check with your
|
||||
network administrator. More information is available in the
|
||||
[Proxy Configuration](../../advanced/proxy_config) documentation.
|
||||
|
||||
- Keyman System Settings
|
||||
|
||||
The Keyman System Settings dialog provides access to various low-level
|
||||
Keyman configuration settings. Generally, these settings do not need
|
||||
to be changed, unless you instructed to do so by Keyman support staff.
|
||||
|
||||
- Base Keyboard
|
||||
|
||||
The Base Keyboard dialog allows you to select the physical Latin-script
|
||||
layout of your keyboard, which will allow certain Keyman keyboards to remap
|
||||
themselves dynamically to match your key caps.
|
||||
|
||||
[Base Keyboard dialog](../../context/base-keyboard)
|
||||
|
||||
|
||||
## Related Topics
|
||||
|
||||
- [Keyman Configuration](../config/)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue