@pi-r/android 0.12.4 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/google-maven-snapshot.json +1 -1
- package/data/google-maven.json +1 -1
- package/extensions/gradle/dependencies/index.js +113 -89
- package/package.json +4 -3
- package/project/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/template/java/static/build.gradle +2 -2
- package/template/java+kotlin/build.gradle +1 -1
- package/template/java+kotlin/libs.versions.toml +2 -2
- package/template/kotlin/build.gradle.kts +3 -1
- package/template/kotlin/libs.versions.toml +8 -4
- package/template/kotlin/static/build.gradle.kts +1 -0
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const fs = require('node:fs');
|
|
5
|
+
const toml = require('toml');
|
|
5
6
|
const Document = require('@e-mc/document');
|
|
6
7
|
const { escapePattern, isArray, isString } = require('@e-mc/types');
|
|
7
|
-
const { getIndent, getNewline, spliceString, trimQuote, wrapQuote } = require('@e-mc/document/util');
|
|
8
|
+
const { getIndent, getNewline, spliceMatch, spliceString, splitEnclosing, trimQuote, wrapQuote } = require('@e-mc/document/util');
|
|
8
9
|
const REGEXP_SEMVER = /^(?:(?:\s*,\s*)?(?:[([\]](?:(?:\s*,\s*)?\d+\.\d+(?:\s*,\s*)?)+[)[\]]|!!\d+\.\d+\.\d+|\d+\.\d+\.\d+!!))+$/;
|
|
9
10
|
const REGEXP_DEPENDENCIES = /dependencies\s+\{((?:{[^{]*{|{[^}]*}|}[^}]*}|\\}*?|[^{}+])+)\}/;
|
|
10
11
|
const REGEXP_DEPENDENCY = /([ \t]*)([A-Za-z_$][\w$]*)(?:\s*\(?\s*(?:module\(?\s*)?["']([^"']+)["']\s*\)?|\s+((?:\s*(?:group|name|version)\s*:\s*(?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')\s*,?){3}))?/g;
|
|
@@ -13,8 +14,7 @@ const REGEXP_LIBRARY = /([ \t]*)implementation\s+(?:(project|files)\(\s*("(?:[^"
|
|
|
13
14
|
const REGEXP_LIBRARY_KOTLIN = /([ \t]*)implementation\(\s*(?:(project|files)\(\s*"(.+)"\s*\)|(fileTree)\(\s*mapOf\(((?:\s*"(?:dir|include)"\s+to\s+(?:"(?:[^"]|(?<=\\)")+"|listOf\([^)]+\))\s*,?){2})\)\s*\))\s*\)[ \t\r]*\n/g;
|
|
14
15
|
const REGEXP_PLATFORM = /([ \t]*)implementation\s+platform\(\s*("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')\s*\)[ \t\r]*\n/g;
|
|
15
16
|
const REGEXP_PLATFORM_KOTLIN = /([ \t]*)implementation\(\s*platform\(\s*"(.+)"\s*\)\s*\)[ \t\r]*\n/g;
|
|
16
|
-
const
|
|
17
|
-
const REGEXP_VERSIONS_LIB = /(\S+)\s*=\s*(?:\{\s*(group|name|module|version(?:\.ref)?)\s*=\s*(?:"([^"]+)"|'([^']+)'|(\{[^}]+\}))\s*,\s*(group|name|module|version(?:\.ref)?)\s*=\s*(?:"([^"]+)"|'([^']+)'|(\{[^}]+\}))(?:\s*,\s*(group|name|module|version(?:\.ref)?)\s*=\s*(?:"([^"]+)"|'([^']+)')|(\{[^}]+\}))?\s*\}|(?:"([^:]+:[^"]+)"|'([^:]+:[^']+)'))/gd;
|
|
17
|
+
const REGEXP_VERSIONS_ATTR = /\b(group|name|module|version(?:\.ref)?)\s*=\s*(?:"([^"]+)"|'([^']+)'|(\{[^}]+\}))/gd;
|
|
18
18
|
function isUpgrade(version, pending) {
|
|
19
19
|
if (isSemVer(pending)) {
|
|
20
20
|
return true;
|
|
@@ -99,6 +99,21 @@ function writeMethod(kotlin, named, item, args = '', prefix = 'implementation')
|
|
|
99
99
|
}
|
|
100
100
|
return prefix + dependency;
|
|
101
101
|
}
|
|
102
|
+
function compareFileTree(from, orig) {
|
|
103
|
+
try {
|
|
104
|
+
return isArray(from) && from.sort().toString() === JSON.parse(`[${orig}]`).sort().toString();
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function removeGroup(items, id) {
|
|
111
|
+
for (let i = 0; i < items.length; ++i) {
|
|
112
|
+
if (items[i][0] === id) {
|
|
113
|
+
items.splice(i--, 1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
102
117
|
function valueFor(name, value, kotlin, quote = false) {
|
|
103
118
|
value = value.toString();
|
|
104
119
|
const q = quote ? kotlin && !value.includes('"') || value.includes("'") ? '"' : "'" : '';
|
|
@@ -107,8 +122,8 @@ function valueFor(name, value, kotlin, quote = false) {
|
|
|
107
122
|
const isLatest = (value) => value === '' || value.startsWith('latest.');
|
|
108
123
|
const isSemVer = (value) => isLatest(value) || REGEXP_SEMVER.test(value);
|
|
109
124
|
const updateOpts = (updateOnly = false) => ({ upgrade: true, updateOnly });
|
|
110
|
-
const writeOutput = (match, source, value) => spliceString(source, match.index, match.index + match[0].length, value);
|
|
111
125
|
const toCamelCase = (value) => value.replace(/-([a-z])/gi, (...capture) => capture[1].toUpperCase());
|
|
126
|
+
const createBoundary = (name) => new RegExp(`(?<=^|\\n[ \\t]*)\\[${name}\\]\\s*`);
|
|
112
127
|
function finalize(instance) {
|
|
113
128
|
const { profileable, dependencies, libraries, dataBinding, jvmToolchain, versionName, versionCode, namespace, applicationId, mainParentDir } = instance.config;
|
|
114
129
|
if (!profileable && !dependencies && !libraries && !dataBinding && !jvmToolchain && !versionName && !versionCode && !namespace && !applicationId) {
|
|
@@ -128,7 +143,7 @@ function finalize(instance) {
|
|
|
128
143
|
};
|
|
129
144
|
const setDependencies = (match, output) => {
|
|
130
145
|
if (modified || !existing) {
|
|
131
|
-
setModified(
|
|
146
|
+
setModified(spliceMatch(source, match, `dependencies {${output}}`));
|
|
132
147
|
}
|
|
133
148
|
};
|
|
134
149
|
if (dependencies) {
|
|
@@ -243,80 +258,101 @@ function finalize(instance) {
|
|
|
243
258
|
const newLine = getNewline(source);
|
|
244
259
|
const gradleDir = path.join(this.baseDirectory, 'gradle');
|
|
245
260
|
const template = instance.findTemplate(gradleDir, "libs.versions.toml", { detect: true, subDir: language, throwsDoesNotExist: false });
|
|
246
|
-
const removeGroup = (id) => {
|
|
247
|
-
for (let i = 0; i < items.length; ++i) {
|
|
248
|
-
if (items[i][0] === id) {
|
|
249
|
-
items.splice(i--, 1);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
261
|
let content = match[1], named = false, versioning = false, indent;
|
|
254
262
|
for (const platform of content.matchAll(kotlin ? REGEXP_PLATFORM_KOTLIN : REGEXP_PLATFORM)) {
|
|
255
263
|
const [group, name] = trimQuote(platform[1]).trim().split(':');
|
|
256
264
|
if (name.endsWith('-bom')) {
|
|
257
|
-
removeGroup(group);
|
|
265
|
+
removeGroup(items, group);
|
|
258
266
|
}
|
|
259
267
|
}
|
|
260
|
-
if (template.source && template.localUri && instance.canWrite(template.localUri, { ownPermissionOnly: true })) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
const versions = {};
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const inline = catalog[14] || catalog[15];
|
|
272
|
-
if (inline) {
|
|
273
|
-
[lib.group, lib.name] = inline.trim().split(':');
|
|
268
|
+
if (template.source && template.localUri && instance.canWrite(template.localUri, { ownPermissionOnly: true }) && (versioning = kotlin && versionCatalog !== false || !!versionCatalog)) {
|
|
269
|
+
const libs = {};
|
|
270
|
+
try {
|
|
271
|
+
let config = template.source;
|
|
272
|
+
const { versions = {}, libraries: packages = {} } = toml.parse(config);
|
|
273
|
+
if (Object.keys(packages).length > 0) {
|
|
274
|
+
const locations = ['versions', 'plugins', 'libraries'].map(name => createBoundary(name).exec(config)?.index ?? NaN).filter(value => !isNaN(value));
|
|
275
|
+
const lowerBound = locations.pop();
|
|
276
|
+
let upperBound = Infinity;
|
|
277
|
+
if (Math.min(lowerBound, ...locations) === lowerBound) {
|
|
278
|
+
upperBound = Math.min(...locations);
|
|
274
279
|
}
|
|
275
|
-
else {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
280
|
+
else if (Math.max(lowerBound, ...locations) !== lowerBound) {
|
|
281
|
+
upperBound = Math.max(...locations);
|
|
282
|
+
}
|
|
283
|
+
for (const key in packages) {
|
|
284
|
+
const pattern = new RegExp(`(\\n[ \\t]*${escapePattern(key)})\\s*=\\s*(?:(["'])(.+)\\2|\\{)`, 'gd');
|
|
285
|
+
pattern.lastIndex = lowerBound;
|
|
286
|
+
const catalog = pattern.exec(config);
|
|
287
|
+
const indices = catalog?.indices;
|
|
288
|
+
if (indices && catalog.index < upperBound) {
|
|
289
|
+
const lib = {};
|
|
290
|
+
let position;
|
|
291
|
+
if (catalog[3]) {
|
|
292
|
+
let version;
|
|
293
|
+
[lib.group, lib.name, version] = catalog[3].trim().split(':');
|
|
294
|
+
if (version && /^\d+\.\d+\.\d+$/.test(version) && (position = indices[3])) {
|
|
295
|
+
const start = position[0] + catalog[3].indexOf(version);
|
|
296
|
+
lib.version = version;
|
|
297
|
+
lib.version_indices = [start, start + version.length];
|
|
283
298
|
}
|
|
284
299
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
const index = items.findIndex(seg => seg[0] === group && seg[1] === name);
|
|
297
|
-
if (index !== -1) {
|
|
298
|
-
const item = items[index];
|
|
299
|
-
items.splice(index, 1);
|
|
300
|
-
const ref = lib['version.ref'];
|
|
301
|
-
const version = ref ? versions[ref] : lib.version;
|
|
302
|
-
if (version && checkVersion(item, version)) {
|
|
303
|
-
if (ref) {
|
|
304
|
-
if (versions[ref] !== item[2]) {
|
|
305
|
-
const target = new RegExp(`\\s${escapePattern(ref)}\\s*=\\s*(?:"([^"]+)"|'([^']+)')`, 'd').exec(config);
|
|
306
|
-
const indices = target?.indices;
|
|
307
|
-
if (indices) {
|
|
308
|
-
const [start, end] = indices[1] || indices[2];
|
|
309
|
-
config = spliceString(config, start, end, versions[ref] = item[2], REGEXP_VERSIONS_LIB);
|
|
300
|
+
else if (position = indices[1]) {
|
|
301
|
+
let start = position[1];
|
|
302
|
+
const [first, second] = splitEnclosing(config.slice(start), ['{', '}'], 1);
|
|
303
|
+
if (second.at(-1) === '}') {
|
|
304
|
+
let attr, i = 0;
|
|
305
|
+
while (attr = REGEXP_VERSIONS_ATTR.exec(second)) {
|
|
306
|
+
lib[attr[1]] = (attr[i = 2] || attr[i = 3] || attr[i = -1]).trim();
|
|
307
|
+
if (attr[1] === 'version' && (position = attr.indices?.[i])) {
|
|
308
|
+
start += first.length;
|
|
309
|
+
lib.version_indices = position.map(pos => start + pos);
|
|
310
310
|
}
|
|
311
311
|
}
|
|
312
|
+
REGEXP_VERSIONS_ATTR.lastIndex = 0;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
continue;
|
|
312
316
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
317
|
+
}
|
|
318
|
+
let { group, name } = lib;
|
|
319
|
+
if (lib.module) {
|
|
320
|
+
[group, name] = lib.module.split(':');
|
|
321
|
+
}
|
|
322
|
+
if (group && name) {
|
|
323
|
+
if (name.endsWith('-bom')) {
|
|
324
|
+
removeGroup(items, group);
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
const index = items.findIndex(seg => seg[0] === group && seg[1] === name);
|
|
328
|
+
if (index !== -1) {
|
|
329
|
+
const item = items[index];
|
|
330
|
+
items.splice(index, 1);
|
|
331
|
+
const ref = lib['version.ref'];
|
|
332
|
+
const version = ref ? versions[ref] : lib.version;
|
|
333
|
+
if (isString(version) && checkVersion(item, version)) {
|
|
334
|
+
if (ref) {
|
|
335
|
+
if (versions[ref] !== item[2]) {
|
|
336
|
+
const target = new RegExp(`\\n[ \\t]*${escapePattern(ref)}\\s*=\\s*(?:"([^"]+)"|'([^']+)')`, 'd').exec(config);
|
|
337
|
+
const found = target?.indices;
|
|
338
|
+
if (found) {
|
|
339
|
+
const [start, end] = found[1] || found[2];
|
|
340
|
+
config = spliceString(config, start, end, item[2]);
|
|
341
|
+
versions[ref] = item[2];
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
else if (lib.version_indices) {
|
|
346
|
+
const [start, end] = lib.version_indices;
|
|
347
|
+
config = spliceString(config, start, end, item[2]);
|
|
348
|
+
lib.version = item[2];
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
libs[key] = lib;
|
|
316
353
|
}
|
|
317
354
|
}
|
|
318
355
|
}
|
|
319
|
-
libs[catalog[1]] = lib;
|
|
320
356
|
}
|
|
321
357
|
}
|
|
322
358
|
if (versioning && items.length > 0) {
|
|
@@ -361,30 +397,26 @@ function finalize(instance) {
|
|
|
361
397
|
item[2] = '';
|
|
362
398
|
libs[key] = { group, name, "version.ref": versionRef };
|
|
363
399
|
}
|
|
364
|
-
const lib =
|
|
400
|
+
const lib = createBoundary('libraries').exec(config);
|
|
365
401
|
if (lib) {
|
|
366
|
-
config =
|
|
402
|
+
config = spliceMatch(config, lib, output);
|
|
367
403
|
}
|
|
368
404
|
else {
|
|
369
405
|
config += (config.endsWith(newLine) ? '' : newLine) + output;
|
|
370
406
|
}
|
|
371
407
|
if (outputVer) {
|
|
372
408
|
outputVer = '[versions]' + newLine + outputVer;
|
|
373
|
-
const ver =
|
|
374
|
-
config = ver ?
|
|
409
|
+
const ver = createBoundary('versions').exec(config);
|
|
410
|
+
config = ver ? spliceMatch(config, ver, outputVer) : outputVer + newLine + config;
|
|
375
411
|
}
|
|
376
|
-
REGEXP_VERSIONS.lastIndex = 0;
|
|
377
412
|
}
|
|
378
413
|
if (Document.createDir(gradleDir)) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
this.add(template.localUri);
|
|
382
|
-
}
|
|
383
|
-
catch (err) {
|
|
384
|
-
this.writeFail(["Unable to write file", path.basename(template.localUri)], err, 32);
|
|
385
|
-
}
|
|
414
|
+
fs.writeFileSync(template.localUri, config, 'utf8');
|
|
415
|
+
this.add(template.localUri);
|
|
386
416
|
}
|
|
387
|
-
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
this.writeFail([Object.keys(libs).length > 0 ? "Unable to write file" : "Unable to load configuration", path.basename(template.localUri)], err, 32);
|
|
388
420
|
}
|
|
389
421
|
}
|
|
390
422
|
if (items.length > 0) {
|
|
@@ -429,7 +461,7 @@ function finalize(instance) {
|
|
|
429
461
|
version = '';
|
|
430
462
|
}
|
|
431
463
|
if (checkVersion(item, version, method[0])) {
|
|
432
|
-
content =
|
|
464
|
+
content = spliceMatch(content, method, method[1] + writeMethod(kotlin, named, item, method[4], method[2]) + newLine, pattern);
|
|
433
465
|
modified = true;
|
|
434
466
|
}
|
|
435
467
|
}
|
|
@@ -469,19 +501,11 @@ function finalize(instance) {
|
|
|
469
501
|
}
|
|
470
502
|
case 'fileTree': {
|
|
471
503
|
const dir = (kotlin ? /"dir"\s+to\s+"(.+)"(?:\s*,|$)/ : /\bdir\s*:\s*["'](.+)["'](?:\s*,|$)/).exec(match[5])?.[1];
|
|
472
|
-
const include = (kotlin ? /"include"\s+to\s+listOf\(([^)]+)\)(?:\s*,|$)/ : /\binclude\s*:\s*\[(
|
|
504
|
+
const include = (kotlin ? /"include"\s+to\s+listOf\(([^)]+)\)(?:\s*,|$)/ : /\binclude\s*:\s*\[([^\]]+)\](?:\s*,|$)/).exec(match[5])?.[1];
|
|
473
505
|
if (dir && include) {
|
|
474
|
-
const compare = (from, orig) => {
|
|
475
|
-
try {
|
|
476
|
-
return isArray(from) && from.sort().toString() === JSON.parse(`[${orig}]`).sort().toString();
|
|
477
|
-
}
|
|
478
|
-
catch {
|
|
479
|
-
return false;
|
|
480
|
-
}
|
|
481
|
-
};
|
|
482
506
|
const target = libraries[attr];
|
|
483
507
|
for (let i = 0; i < target.length; ++i) {
|
|
484
|
-
if (target[i].dir === dir &&
|
|
508
|
+
if (target[i].dir === dir && compareFileTree(target[i].include, include)) {
|
|
485
509
|
index = i;
|
|
486
510
|
break;
|
|
487
511
|
}
|
|
@@ -645,7 +669,7 @@ function finalize(instance) {
|
|
|
645
669
|
fs.readdirSync(subDir, { withFileTypes: true }).forEach(item => {
|
|
646
670
|
const srcName = path.join(subDir, item.name);
|
|
647
671
|
if (item.isDirectory()) {
|
|
648
|
-
switch (/^\$\{(
|
|
672
|
+
switch (/^\$\{(.+)\}$/.exec(item.name)?.[1]) {
|
|
649
673
|
case 'app':
|
|
650
674
|
if (instance.config.mainParentDir) {
|
|
651
675
|
recurse.call(this, srcName, path.join(targetDir, instance.config.mainParentDir));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/android",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Android document constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@e-mc/document": "^0.14.
|
|
21
|
-
"@e-mc/types": "^0.14.
|
|
20
|
+
"@e-mc/document": "^0.14.6",
|
|
21
|
+
"@e-mc/types": "^0.14.6",
|
|
22
22
|
"dom-serializer": "^2.0.0",
|
|
23
23
|
"domhandler": "^5.0.3",
|
|
24
24
|
"domutils": "^3.2.2",
|
|
25
25
|
"htmlparser2": "^10.1.0",
|
|
26
|
+
"toml": "^4.3.0",
|
|
26
27
|
"which": "^4.0.0"
|
|
27
28
|
}
|
|
28
29
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
distributionBase=GRADLE_USER_HOME
|
|
2
2
|
distributionPath=wrapper/dists
|
|
3
|
-
distributionUrl=https\://services.gradle.org/distributions/gradle-9.
|
|
3
|
+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
|
|
4
4
|
zipStoreBase=GRADLE_USER_HOME
|
|
5
5
|
zipStorePath=wrapper/dists
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
plugins {
|
|
2
2
|
alias(libs.plugins.android.application)
|
|
3
3
|
alias(libs.plugins.kotlin.compose)
|
|
4
|
+
alias(libs.plugins.google.devtools.ksp)
|
|
4
5
|
}
|
|
5
6
|
|
|
6
7
|
android {
|
|
7
8
|
namespace = ""
|
|
8
9
|
compileSdk {
|
|
9
10
|
version = release(37) {
|
|
10
|
-
minorApiLevel =
|
|
11
|
+
minorApiLevel = 1
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -43,6 +44,7 @@ android {
|
|
|
43
44
|
dependencies {
|
|
44
45
|
implementation(libs.jetbrains.kotlin)
|
|
45
46
|
implementation(libs.androidx.core.ktx)
|
|
47
|
+
implementation(libs.androidx.navigation.fragment.ktx)
|
|
46
48
|
implementation(libs.androidx.appcompat)
|
|
47
49
|
implementation(libs.androidx.constraintlayout)
|
|
48
50
|
implementation(libs.android.material)
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
[versions]
|
|
2
|
-
agp = "9.2
|
|
2
|
+
agp = "9.3.2"
|
|
3
3
|
coreKtx = "1.19.0"
|
|
4
|
-
|
|
4
|
+
navigationFragmentKtx = "2.10.0"
|
|
5
|
+
kotlin = "2.4.10"
|
|
6
|
+
ksp = "2.3.11"
|
|
5
7
|
junit = "4.13.2"
|
|
6
8
|
junitVersion = "1.3.0"
|
|
7
9
|
espressoCore = "3.7.0"
|
|
8
|
-
appcompat = "1.
|
|
10
|
+
appcompat = "1.8.0"
|
|
9
11
|
material = "1.14.0"
|
|
10
|
-
constraintlayout = "2.2.
|
|
12
|
+
constraintlayout = "2.2.2"
|
|
11
13
|
|
|
12
14
|
[libraries]
|
|
13
15
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
|
16
|
+
androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigationFragmentKtx" }
|
|
14
17
|
jetbrains-kotlin = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
|
|
18
|
+
google-devtools-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
|
15
19
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
|
16
20
|
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
|
17
21
|
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|