[MRG] Experiment with different install mechanism to get code coverage stats again

(New comment from January 2020: https://github.com/jupyterhub/repo2docker/pull/982#issuecomment-765900791 if you like to skip ahead read that, for a historical perspective keep reading here.)

For some reason we report zero coverage from our tests.
For example here https://github.com/jupyterhub/repo2docker/runs/1297097310
All the files in repo2docker/... appear to have zero coverage and the file in /opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/... do have some coverage. However when you look at what arrives in codecov you are at zero percent https://codecov.io/github/jupyterhub/repo2docker/commit/30ef2209cc767826e2647886854fac12469a06c1

With this setup the classic uni tests generate coverage but all the tests that use our custom pytest discovery mechanism don't :-/

4f7e5e2 is based on finding an example in the pytest-cov docs that shows how to setup things when you have an "ad-hoc" source layout for your package. The key change is to run the tests from a directory that isn't the root of the repository so that the path in --cov repo2docker doesn't point to a directory that exists.

Rebooting this PR. I still don't fully understand why this broke and why this set of settings fixes it again. But as an experimental physicists I conclude "this must be correct because it works" :D
n.b. I also don't know what might newly be broken with this change but given that coverage calculations have been broken since about August 2020 I think getting something working again is better than nothing and if we break someone's workflow they might come here to complain (and then we can fix it).

Rebooting this PR. I still don't fully understand why this broke and why this set of settings fixes it again. But as an experimental physicists I conclude "this must be correct because it works" :D
n.b. I also don't know what might newly be broken with this change but given that coverage calculations have been broken since about August 2020 I think getting something working again is better than nothing and if we break someone's workflow they might come here to complain (and then we can fix it).

experience with configuring Codecov

I think this isn't a codecov thing but a coverage.py thing. But still mostly magic and mystery to me :-/

experience with configuring Codecov

I think this isn't a codecov thing but a coverage.py thing. But still mostly magic and mystery to me :-/

@manics merge time? I added you to this repo with "write" access because it is a mystery to me why you aren't on that list.

@manics merge time? I added you to this repo with "write" access because it is a mystery to me why you aren't on that list.

Doesn't look like this worked :-/

Doesn't look like this worked :-/

I've got codecov working in one of my repos:
https://github.com/manics/jupyterhub-ansiblespawner/blob/d0ef3d044e5c2ef6fb1552cd00e9aae995f9cf26/.github/workflows/workflow.yml#L62-L72
Example comment:
https://github.com/manics/jupyterhub-ansiblespawner/pull/56#issuecomment-766557470
Though that's using standard pytest tests, not a custom discovery mechanism, so I don't know if it'll work?

I've got codecov working in one of my repos:
https://github.com/manics/jupyterhub-ansiblespawner/blob/d0ef3d044e5c2ef6fb1552cd00e9aae995f9cf26/.github/workflows/workflow.yml#L62-L72
Example comment:
https://github.com/manics/jupyterhub-ansiblespawner/pull/56#issuecomment-766557470
Though that's using standard pytest tests, not a custom discovery mechanism, so I don't know if it'll work?

https://codecov.io/gh/jupyterhub/repo2docker/commit/ac41c201a3a7a1aaa898a46c81affe172f6bb93e
One of the possible problems is "File paths are not resolving"
Looking at cat coverage.xml from https://github.com/jupyterhub/repo2docker/runs/1764264201?check_suite_focus=true
<?xml version="1.0"?>
<coverage version="5.3.1" timestamp="1611603297625" lines-valid="1827" lines-covered="953" line-rate="0.5216" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
  <!-- Generated by coverage.py: https://coverage.readthedocs.io -->
  <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
  <sources>
    <source/>
  </sources>
  <packages>
    <package name=".opt.hostedtoolcache.Python.3.8.6.x64.lib.python3.8.site-packages.repo2docker" line-rate="0.5408" branch-rate="0" complexity="0">
      <classes>
        <class name="__init__.py" filename="/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/__init__.py" complexity="0" line-rate="1" branch-rate="0">
          <methods/>
          <lines>
            <line number="1" hits="1"/>
            <line number="3" hits="1"/>
            <line number="4" hits="1"/>
            <line number="6" hits="1"/>
          </lines>
        </class>
        <class name="__main__.py" filename="/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/__main__.py" complexity="0" line-rate="0.5827" branch-rate="0">
          <methods/>
          <lines>
            <line number="1" hits="1"/>
            <line number="2" hits="1"/>
            <line number="3" hits="1"/>
            <line number="4" hits="1"/>
            <line number="5" hits="1"/>
            <line number="6" hits="1"/>
            <line number="7" hits="1"/>
            <line number="8" hits="1"/>
            <line number="11" hits="1"/>
            <line number="32" hits="0"/>
            <line number="33" hits="0"/>
            <line number="38" hits="0"/>
            <line number="39" hits="0"/>
            <line number="43" hits="1"/>
            <line number="44" hits="1"/>
            <line number="49" hits="0"/>
            <line number="50" hits="0"/>
            <line number="51" hits="0"/>
            <line number="52" hits="0"/>
            <line number="54" hits="0"/>
            <line number="56" hits="0"/>
            <line number="60" hits="0"/>
            <line number="63" hits="1"/>
            <line number="65" hits="1"/>
            <line number="69" hits="1"/>
            <line number="75" hits="1"/>
            <line number="82" hits="1"/>
            <line number="90" hits="1"/>
            <line number="96" hits="1"/>
            <line number="104" hits="1"/>
            <line number="44" hits="0"/>
            <line number="45" hits="0"/>
            <line number="47" hits="0"/>
            <line number="48" hits="0"/>
            <line number="49" hits="0"/>
            <line number="50" hits="0"/>
            <line number="51" hits="0"/>
            <line number="52" hits="0"/>
            <line number="55" hits="0"/>
            <line number="56" hits="0"/>
            <line number="57" hits="0"/>
            <line number="62" hits="0"/>
            <line number="63" hits="0"/>
            <line number="64" hits="0"/>
            <line number="67" hits="0"/>
            <line number="69" hits="0"/>
            <line number="70" hits="0"/>
            <line number="71" hits="0"/>
            <line number="73" hits="1"/>
            <line number="74" hits="1"/>
            <line number="76" hits="0"/>
          </lines>
        </class>
        <class name="zenodo.py" filename="/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/contentproviders/zenodo.py" complexity="0" line-rate="0.4412" branch-rate="0">
          <methods/>
          <lines>
            <line number="1" hits="1"/>
            <line number="2" hits="1"/>
            <line number="3" hits="1"/>
            <line number="5" hits="1"/>
            <line number="6" hits="1"/>
            <line number="7" hits="1"/>
            <line number="8" hits="1"/>
            <line number="10" hits="1"/>
            <line number="11" hits="1"/>
            <line number="14" hits="1"/>
            <line number="17" hits="1"/>
            <line number="18" hits="0"/>
            <line number="22" hits="0"/>
            <line number="44" hits="1"/>
            <line number="46" hits="0"/>
            <line number="48" hits="0"/>
            <line number="49" hits="0"/>
            <line number="50" hits="0"/>
            <line number="51" hits="0"/>
            <line number="53" hits="1"/>
            <line number="55" hits="0"/>
            <line number="56" hits="0"/>
            <line number="58" hits="0"/>
            <line number="59" hits="0"/>
            <line number="64" hits="0"/>
            <line number="66" hits="0"/>
            <line number="67" hits="0"/>
            <line number="68" hits="0"/>
            <line number="69" hits="0"/>
            <line number="70" hits="0"/>
            <line number="73" hits="0"/>
            <line number="75" hits="1"/>
            <line number="76" hits="1"/>
            <line number="78" hits="0"/>
          </lines>
        </class>
      </classes>
    </package>
  </packages>
</coverage>

pytest is running the repo2docker files that have been installed (/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/__main__.py) instead of the local files in the working directory ./repo2docker/__main__.py, so maybe the paths need to be mapped?

https://codecov.io/gh/jupyterhub/repo2docker/commit/ac41c201a3a7a1aaa898a46c81affe172f6bb93e
One of the possible problems is "File paths are not resolving"
Looking at cat coverage.xml from https://github.com/jupyterhub/repo2docker/runs/1764264201?check_suite_focus=true
<?xml version="1.0"?>
<coverage version="5.3.1" timestamp="1611603297625" lines-valid="1827" lines-covered="953" line-rate="0.5216" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
  <!-- Generated by coverage.py: https://coverage.readthedocs.io -->
  <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
  <sources>
    <source/>
  </sources>
  <packages>
    <package name=".opt.hostedtoolcache.Python.3.8.6.x64.lib.python3.8.site-packages.repo2docker" line-rate="0.5408" branch-rate="0" complexity="0">
      <classes>
        <class name="__init__.py" filename="/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/__init__.py" complexity="0" line-rate="1" branch-rate="0">
          <methods/>
          <lines>
            <line number="1" hits="1"/>
            <line number="3" hits="1"/>
            <line number="4" hits="1"/>
            <line number="6" hits="1"/>
          </lines>
        </class>
        <class name="__main__.py" filename="/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/__main__.py" complexity="0" line-rate="0.5827" branch-rate="0">
          <methods/>
          <lines>
            <line number="1" hits="1"/>
            <line number="2" hits="1"/>
            <line number="3" hits="1"/>
            <line number="4" hits="1"/>
            <line number="5" hits="1"/>
            <line number="6" hits="1"/>
            <line number="7" hits="1"/>
            <line number="8" hits="1"/>
            <line number="11" hits="1"/>
            <line number="32" hits="0"/>
            <line number="33" hits="0"/>
            <line number="38" hits="0"/>
            <line number="39" hits="0"/>
            <line number="43" hits="1"/>
            <line number="44" hits="1"/>
            <line number="49" hits="0"/>
            <line number="50" hits="0"/>
            <line number="51" hits="0"/>
            <line number="52" hits="0"/>
            <line number="54" hits="0"/>
            <line number="56" hits="0"/>
            <line number="60" hits="0"/>
            <line number="63" hits="1"/>
            <line number="65" hits="1"/>
            <line number="69" hits="1"/>
            <line number="75" hits="1"/>
            <line number="82" hits="1"/>
            <line number="90" hits="1"/>
            <line number="96" hits="1"/>
            <line number="104" hits="1"/>
            <line number="44" hits="0"/>
            <line number="45" hits="0"/>
            <line number="47" hits="0"/>
            <line number="48" hits="0"/>
            <line number="49" hits="0"/>
            <line number="50" hits="0"/>
            <line number="51" hits="0"/>
            <line number="52" hits="0"/>
            <line number="55" hits="0"/>
            <line number="56" hits="0"/>
            <line number="57" hits="0"/>
            <line number="62" hits="0"/>
            <line number="63" hits="0"/>
            <line number="64" hits="0"/>
            <line number="67" hits="0"/>
            <line number="69" hits="0"/>
            <line number="70" hits="0"/>
            <line number="71" hits="0"/>
            <line number="73" hits="1"/>
            <line number="74" hits="1"/>
            <line number="76" hits="0"/>
          </lines>
        </class>
        <class name="zenodo.py" filename="/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/contentproviders/zenodo.py" complexity="0" line-rate="0.4412" branch-rate="0">
          <methods/>
          <lines>
            <line number="1" hits="1"/>
            <line number="2" hits="1"/>
            <line number="3" hits="1"/>
            <line number="5" hits="1"/>
            <line number="6" hits="1"/>
            <line number="7" hits="1"/>
            <line number="8" hits="1"/>
            <line number="10" hits="1"/>
            <line number="11" hits="1"/>
            <line number="14" hits="1"/>
            <line number="17" hits="1"/>
            <line number="18" hits="0"/>
            <line number="22" hits="0"/>
            <line number="44" hits="1"/>
            <line number="46" hits="0"/>
            <line number="48" hits="0"/>
            <line number="49" hits="0"/>
            <line number="50" hits="0"/>
            <line number="51" hits="0"/>
            <line number="53" hits="1"/>
            <line number="55" hits="0"/>
            <line number="56" hits="0"/>
            <line number="58" hits="0"/>
            <line number="59" hits="0"/>
            <line number="64" hits="0"/>
            <line number="66" hits="0"/>
            <line number="67" hits="0"/>
            <line number="68" hits="0"/>
            <line number="69" hits="0"/>
            <line number="70" hits="0"/>
            <line number="73" hits="0"/>
            <line number="75" hits="1"/>
            <line number="76" hits="1"/>
            <line number="78" hits="0"/>
          </lines>
        </class>
      </classes>
    </package>
  </packages>
</coverage>

pytest is running the repo2docker files that have been installed (/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/__main__.py) instead of the local files in the working directory ./repo2docker/__main__.py, so maybe the paths need to be mapped?

pytest is running the repo2docker files that have been installed (/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/__main__.py) instead of the local files in the working directory ./repo2docker/__main__.py, so maybe the paths need to be mapped?

I think so too. Do you want to make an attempt at doing that? I think I've tried before but didn't manage to find the right settings.

pytest is running the repo2docker files that have been installed (/opt/hostedtoolcache/Python/3.8.6/x64/lib/python3.8/site-packages/repo2docker/__main__.py) instead of the local files in the working directory ./repo2docker/__main__.py, so maybe the paths need to be mapped?

I think so too. Do you want to make an attempt at doing that? I think I've tried before but didn't manage to find the right settings.


ImportError undefined symbol when loading .so calling Python from Rust

🐛 Bug Reports
🌍 Environment

Your operating system and version: Fedora 31
Your python version: 3.7.5
How did you install python (e.g. apt or pyenv)? Did you use a virtualenv?: dnf package
Your rust version (rustc --version): rustc 1.42.0-nightly (0de96d37f 2019-12-19)
Are you using the latest pyo3 version? Have you tried using latest master (replace version = "0.x.y" with git = "https://github.com/PyO3/pyo3")? Reproduced with 0.8.4 and c8cb3adc23d297955bf8a08be19976fdb11e3a76

💥 Reproducing
You'll need to install Tensorflow and fetch my test code in order to reproduce:

pip install tensorflow==1.14.0
git clone https://github.com/gdesmott/pyo3-bug.git
cd pyo3-bug
rustup override set nightly

First check that pyo3 is able to import Tensorflow from the Rust executable (src/bin/test.rs):

cargo run
TensorFlow should display some FutureWarning but you shouldn't get any error.

Now let's try to run the exact same code but from a .so file instead:

cargo build
gcc test.c -ldl
./a.out

You should get this error:
Traceback (most recent call last):
  File "/home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
    from tensorflow.python.pywrap_tensorflow_internal import *
  File "/home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 28, in <module>
    _pywrap_tensorflow_internal = swig_import_helper()
  File "/home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 24, in swig_import_helper
    _mod = imp.load_module('_pywrap_tensorflow_internal', fp, pathname, description)
  File "/usr/lib64/python3.7/imp.py", line 242, in load_module
    return load_dynamic(name, filename, file)
  File "/usr/lib64/python3.7/imp.py", line 342, in load_dynamic
    return _load(spec)
ImportError: /home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so: undefined symbol: PyExc_RuntimeError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 2, in <module>
  File "/home/cassidy/.local/lib/python3.7/site-packages/tensorflow/__init__.py", line 28, in <module>
    from tensorflow.python import pywrap_tensorflow  # pylint: disable=unused-import
  File "/home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/__init__.py", line 49, in <module>
    from tensorflow.python import pywrap_tensorflow
  File "/home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow.py", line 74, in <module>
    raise ImportError(msg)
ImportError: Traceback (most recent call last):
  File "/home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
    from tensorflow.python.pywrap_tensorflow_internal import *
  File "/home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 28, in <module>
    _pywrap_tensorflow_internal = swig_import_helper()
  File "/home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 24, in swig_import_helper
    _mod = imp.load_module('_pywrap_tensorflow_internal', fp, pathname, description)
  File "/usr/lib64/python3.7/imp.py", line 242, in load_module
    return load_dynamic(name, filename, file)
  File "/usr/lib64/python3.7/imp.py", line 342, in load_dynamic
    return _load(spec)
ImportError: /home/cassidy/.local/lib/python3.7/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so: undefined symbol: PyExc_RuntimeError

Failed to load the native TensorFlow runtime.

See https://www.tensorflow.org/install/errors

for some common reasons and solutions.  Include the entire stack trace
above this error message when asking for help.
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: ()', src/libcore/result.rs:1188:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
fatal runtime error: failed to initiate panic, error 5
Aborted (core dumped)

The problem is that your a.out binary is not linked against Python, and so when the Python c extensions are being loaded they cannot find the Python C API symbols. We can see this from the output of ldd:
$ ldd ./a.out
    linux-vdso.so.1 (0x00007fff9dbcf000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff75d5e7000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff75d1f6000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ff75d9ed000)

You have three options on how to solve this:

Manually link in the python shared library by changing your gcc invocation:
 gcc ./test.c -ldl -Wl,--no-as-needed -lpython3.7m

Manually add the python shared library to the global symbol table by opening it with dlopen before your other dlopen call:
 assert (dlopen("/usr/lib/x86_64-linux-gnu/libpython3.7m.so", RTLD_LAZY | RTLD_GLOBAL));
 handle = dlopen("./target/debug/libbadger.so", RTLD_LAZY);

Link against the rust library, which will automatically pull in the correct python as a dependency:
 // test2.c
 void test_badger();

 int main (void) {
   test_badger ();
   return 0;
 }

Compile test2.c with:
 gcc test2.c -L target/debug/ -lbadger -Wl,-rpath target/debug

The third option is probably best unless you absolutely must use runtime dynamic linking.

Thanks for your reply @davidhewitt.
Actually yes, I do need runtime dynamic linking. I'm implementing a GStreamer plugin in Rust which is built as a shared .so. So I'd need a way to force the linking on Python from the plugin itself, not the application. What would the right way to do that then?

Ah, I see - in which case the second option is probably the way to go. If you call dlopen in your plugin initialisation code with the RTLD_GLOBAL flag then the Python library symbols should become accessible for python c extensions to load.
In Rust, I think it'll be something like this:
extern {
    fn dlopen(filename: *const libc::c_char, flags: libc::c_int) -> *mut libc::c_void;
    fn dlclose(handle: *mut libc::c_void) -> libc::c_int;
}

const RTLD_GLOBAL: libc::c_int = 0x00100;
const RTLD_LAZY: libc::c_int = 0x00001;

// make sure this path is null-terminated
const libpython: &'static str = "/path/to/libpython3.7m.so\0";
let handle = dlopen(libpython.as_ptr(), RTLD_GLOBAL | RTLD_LAZY);
assert!(!handle.is_null());

You'll need to make sure your Rust project is linking against libdl. (e.g. with a links entry in your Cargo.toml)

Great, that works! Thank you so much for your help.
For the record here is the exact code I used:
fn init() {
    use libc;

    extern "C" {
        fn dlopen(filename: *const libc::c_char, flags: libc::c_int) -> *mut libc::c_void;
        fn dlclose(handle: *mut libc::c_void) -> libc::c_int;
    }

    const RTLD_GLOBAL: libc::c_int = 0x00100;
    const RTLD_LAZY: libc::c_int = 0x00001;

    // make sure this path is null-terminated
    const LIBPYTHON: &'static str = "/usr/lib64/libpython3.7m.so\0";
    unsafe {
        let handle = dlopen(LIBPYTHON.as_ptr() as *const i8, RTLD_GLOBAL | RTLD_LAZY);
        assert!(!handle.is_null());
    }
}


FIX: replace hardcoded urls with Django generated ones. Fixes #1171

The My Tickets view generated ticket urls with a '/view' string prefix. This is replaced by proper Django URL resolution.
The public and staff ticket view used a '../../' string prefix which brakes in the public ticket view. They are both replaced with proper Django URL resolution.

@uhurusurfa I think this can be merged too :)


Unit tests failing with "AssertionError: If capturable=False, state_steps should not be CUDA tensors."

test_adam_option (test_fused_optimizer.TestFusedAdam): due to https://github.com/pytorch/pytorch/issues/80809#issuecomment-1175211598
test_multi_device (test_fused_optimizer.TestFusedAdam): due to https://github.com/pytorch/pytorch/issues/80809#issuecomment-1175211598
test_float (test_fused_optimizer.TestFusedAdam): due to https://github.com/pytorch/pytorch/issues/80809#issuecomment-1175211598
Reference: https://github.com/ROCmSoftwarePlatform/apex/pull/78#issuecomment-1201839061

The tests failed due to a regression introduced from PyTorch upstream: https://github.com/pytorch/pytorch/issues/80809#issuecomment-1175211598. They can be unskipped once the fix is integrated into PyTorch ROCm fork from PyTorch upstream.


NoSuchMethodError ... LightAdminRepositoryRestMvcConfiguration.entityLinks

I am having a problem with the current version of lightadmin.
You can reproduce it exactly with the lightadmin-springboot example:
git clone https://github.com/la-team/lightadmin-springboot.git
cd lightadmin-springboot
mvn package
java -jar target/lightadmin-boot.jar

results in
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.lightadmin.core.web.json.DomainTypeToJsonMetadataConverter org.lightadmin.core.config.context.LightAdminRepositoryRestMvcConfiguration.domainTypeToJsonMetadataConverter()] threw exception; nested exception is java.lang.NoSuchMethodError: org.lightadmin.core.config.context.LightAdminRepositoryRestMvcConfiguration.entityLinks()Lorg/springframework/data/rest/webmvc/support/RepositoryEntityLinks;
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188) ~[spring-beans-4.1.0.RELEASE.jar!/:4.1.0.RELEASE]
...

same problem when using snapshot build <lightadmin.version>1.2.0.BUILD-SNAPSHOT</lightadmin.version>

@dsteinkopf, you're right. Reworking spring-boot apps is in progress

@dsteinkopf Hi, I've just updated lightadmin-springboot application to use the latest LA.
Can you check the issue is closed now, please?

Fixed according to #172

Confirmed. lightadmin-springboot example is now working for me, thank you. I will try in my own application, now.

In my spring boot application everything seems to work fine with currrent lightadmin-1.2.0.BUILD-SNAPSHOT from lightadmin-nexus-snapshots (see lightadmin-springboot example). Thank you again.


haskellPackages.gi-gtk: fix build on ghc > 9.6

Description of changes
Extend already existing fix for ghc-9.6.x to ghc > 9.6 as they are also affected by the same issue.
(https://gitlab.haskell.org/ghc/ghc/-/issues/23392)
Things done

Built on platform(s)

[x] x86_64-linux
[ ] aarch64-linux
[ ] x86_64-darwin
[ ] aarch64-darwin

For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)

[ ] sandbox = relaxed
[x] sandbox = true

[ ] Tested, as applicable:

NixOS test(s) (look inside nixos/tests)
and/or package tests
or, for functions and "core" functionality, tests in lib/tests or pkgs/test
made sure NixOS tests are linked to the relevant packages

[ ] Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
[ ] Tested basic functionality of all binary files (usually in ./result/bin/)
24.11 Release Notes (or backporting 23.11 and 24.05 Release notes)

[ ] (Package updates) Added a release notes entry if the change is major or breaking
[ ] (Module updates) Added a release notes entry if the change is significant
[ ] (Module addition) Added a release notes entry if adding a new NixOS module

[ ] Fits CONTRIBUTING.md.

Add a :+1: reaction to pull requests you find important.

The threshold is that it has to be documented then.


Restructure keymap files

Based on #3022
Most of our users are using Linux, and hence 'evdev' key mappings. These key mappings are more comprehensive than the 'base' key mappings, in that several media keys are supported. This is why #3022 was raised.
During the course of #3022. a number of issues with the existing keymaps were identified:-

The code to map the RDP scancodes received from the client to X11 keycodes is in three places, namely xrdp/lang.c, genkeymap/*.c and xorgxrdp itself. This makes a wholesale change to evdev challenging and tricky to test.
The keymaps aren't all auto-generated, and some are out-of-date (see this comment)
XKB changes over time, and the old way of supporting NumLock by pretending it's a shift isn't supported in newer releases (see this comment)

This PR attempts to address these deficiencies as follows:-

There's now a single module to map RDP scancodes to evdev (or base) key codes in common/scancode.c.
The keymap file format has been updated to be indexed by RDP scancode rather than base key code. This should make it easier to triage user problems, as scancodes are readily viewable on (e.g.) https://kbdlayout.info/, and also removes the need to know the X11 keycode for the login screen or the VNC back-end.
Keymap files now contain a short [numlock] section
The X11 keycode to be used by xorgxrdp is now sent directly to xorgxrdp as part of a KEY_UP / KEY_DOWN message in place of the Unicode field. This should allow for some simplification on the keyboard driver in xorgxrdp.

This is where I think we should be going after merging #3022, but I'd appreciate some constructive criticism around this, particularly from @sasha0552 and @jsorg71

I think it's ready for updating the xorgxrdp interface. The only possible change in this area is to pass the rules over from xrdp in the same way as we're passing the model and variant.
Next I'm going to look at getting manpages done for xrdp-genkeymap and the keymap files themselves, so I won't be messing much with the functionality.

I've updated a few things to make this more platform independent. The changes are all around the genkeymap utility.
The scancode module now understands both base/xfree86 and evdev keycode mappings - it's no longer a compile-time option. This is used by the genkeymap utility to select the correct table at runtime. It's similar to what it was doing before, but the tables are separate from each other within the scancode module. This should aid maintainability and make it possible to add other tables if we ever need to.
I've verified manually that the only differences between keymap files generated using 'evdev' rules and 'base' rules are the scancode mappings for extra keys. This is what we'd expect with the keymap tables now being based on RDP scancodes.
There's now a separate manpage documenting the key mapping file format, and the manpage for xrdp-genkeymap has been updated.
Comment still very welcome. If I get nothing by around the middle of next week I'll merge this, and we can get on with updating and (hopefully) simplifying xorgxrdp.

@matt335672
I'm late to join this discussion, what about switching to TOML as I suggested #2659 before? I postponed merging #2659 because it breaks compatibility. This is also a breaking change so I think it is a good time to switch from our own ini parser to TOML library.

Actually, I'd used the TOML parser in this PR anyway as the format was changing!
I'd forgotten #2659 was in this area. I'll have a look and figure out the best way to get both PRs merged.

Ah,  I only have a quick look at this so I didn't notice TOML is used since keymap files have .ini suffix. That sounds good then.
I prefer .toml suffix to indicate that keymap file is parsed by TOML v1.0.0 compliant parser.

Since I'm breaking the format anyway, it's probably a good idea to rename these as .toml. That way any customisations made by users to old files won't be wiped out. I'll do that.

Having reviewed #2659, I think the following should be added to this PR from it:-

Rename keyboard files to .toml from .ini.
Add a test case for loading a keyboard file. The original purpose of the test in #2659 was to check the ini and TOML parsers returned the same result. The new test case can't fall back on an ini file to test, but at the very least it gives us a way to check memory is being allocated and de-allocated properly which IIRC is part of the test added for #3065.

LGTM

Thanks.
I've updated NEWS with suitable notices as this is a backwards-incompatible change. I'll pop something on gitter too.


Still have incorrect skip flush change set because of commitTS inconsistency.

[ERROR] [meta.go:276] ["223:33 skip duplicated flush commitTS:763501, meta commitTS:763502"]

CommitTS is used as the version of Lock CF and also used to order the L0 files.
In order to complete solve the inconsistency problem, we should remove the commitTS and use the raft log index instead.

The newly split region's initial raft log index should inherent the parent region's raft log index, so the old L0 table's sequence will always be smaller than new L0 table's sequence.

Changing the initial index of a raft group may cause some potential problems. In kv engine, adding parent index to shard may be a better choice. Using the new split region's index plus parent index as the commit timestamp. The commit timestamp will keep increments sequentially from the old region to the new region.

Fixed by https://github.com/ngaut/unistore/pull/632


RN 63 new PlatformColor issue

Environment
System:

OS: macOS 10.15.5
CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
Memory: 276.91 MB / 16.00 GB
Shell: 5.7.1 - /bin/zsh

Binaries:

Node: 13.9.0 - /usr/local/bin/node
Yarn: 1.22.4 - ~/Developer/projects/projectx/node_modules/.bin/yarn
npm: 6.13.7 - /usr/local/bin/npm

npmPackages:

babel-plugin-styled-components: ^1.10.7 => 1.10.7
styled-components: ^5.1.1 => 5.1.1

Steps to reproduce

Upgrade project to React Native 0.63
Added PlatformColor to my theme object
Used the color within a Styled Component as a background property

Expected Behavior

Color should just be shows as usual

Actual Behavior

Reproduction Repo Link: https://github.com/tomacotuna/PlatformColorStyledComponents
Terminal Error Log:
Invariant Violation: Invalid prop `backgroundColor` supplied to `StyleSheet generated`: semantic:
Valid color formats are
  - '#f0f' (#rgb)
  - '#f0fc' (#rgba)
  - '#ff00ff' (#rrggbb)
  - '#ff00ff00' (#rrggbbaa)
  - 'rgb(255, 255, 255)'
  - 'rgba(255, 255, 255, 1.0)'
  - 'hsl(360, 100%, 100%)'
  - 'hsla(360, 100%, 100%, 1.0)'
  - 'transparent'
  - 'red'
  - 0xff00ff00 (0xrrggbbaa)

StyleSheet generated: {
  "backgroundColor": "semantic:",
  "systemBackground": ""
}

This error is located at:
    in StyledNativeComponent (created by Styled(View))
    in Styled(View) (at App.js:39)
    in RCTSafeAreaView (at SafeAreaView.js:51)
    in ForwardRef(SafeAreaView) (at App.js:38)
    in App (at renderApplication.js:45)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:106)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:132)
    in AppContainer (at renderApplication.js:39)
✨  Done in 428.20s.```

An important thing to note is that styled-components' native version parses all interpolations as strings. That means that all tagged template literals are flattened to a single string before it becomes a style object.
So that interpolation doesn't survive the conversion since it's not a string, like the Animated usage. This is a known limitation ✌

Was this resolved? I have the same problem

Same here! and here https://github.com/styled-components/styled-components/issues/3119

Could be fixed with https://github.com/styled-components/styled-components/pull/3504

Closing due to inactivity.
This isn't really an issue I think we should resolve, unless we make the React Native version a separate package of the mainline one. In general, we convert CSS to a string and then parse it with css-to-react-native for React Native, which limits the amount of dynamic interpolations we can use, just like with Animated values. See: https://github.com/styled-components/styled-components/issues/3119#issuecomment-895253096


Gill Sans not loading on Macs

Referencing post: https://github.com/data-edu/data-science-in-education/issues/519
Gill Sans MT is a font that is bundled only on some Macs, and {extrafont} doesn't necessarily load it unless it's already on the user's computer. To be able to use theme_dataedu(), some Mac users have to download Gill Sans MT, use extrafont::font_import(), then loadfonts(). Not sure if this is also the case with Windows users.
Need to decide how to fix this in the package, either by directing users to download the font, throwing an informative warning if the font is not installed on their computers and letting users render the plot with the default font, or changing Gill Sans to a font that doesn't have these issues.

thx for cross-reffing this. Is there a good source for downloading Gill Sans MT? I'm having some difficulty but this may be to my "font newbie status" 😂

Try this site out!

Oh I don't remember where I got it. But I followed Isabella's lead on this
so it was probably the site she suggested
On Fri, May 15, 2020 at 6:43 AM Isabella Velásquez<EMAIL_ADDRESS>wrote:

Try this site
https://www.dafontfree.net/freefonts-gill-sans-mt-f64845.htm out!
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/data-edu/dataedu/issues/82#issuecomment-629243494,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ADXLW3ML47K2TBHCHYMRUOLRRVBITANCNFSM4MEONKGQ
.

Do you have any thoughts on switching to another font (that is more likely to be installed) - or having something nifty like IF gill sans is not installed then use this font instead?

Hi @joshuarosenberg - I have used {emojifont} as an example and now Gill Sans MT is included within the package itself. Give it a spin :)

@jrosen48 did this work?


Make imagemagick available on lagoon

There will be many cases when we will use imagemagick (convert) as the image toolkit in Drupal, instead of the old PHP GD. We should have this package also available.

Workaround:
Adding imagemagick to Dockerfile.php and Dockerfile.cli

RUN apk add --no-cache imagemagick

+1 from another client that would like to have that.


digitsOptional: true + suffix not working as expected. can't enter decimal digits

Hi there, I just try to get a currency input running using the iso code instead of the currency sign. It works quite well as long as I leave the digitsOptional parameter on false. When I set it to true I can't anymore input decimal digits.
    'alias': 'decimal',
    'groupSeparator': ',',
    'suffix': " [EUR]",
    'digits': 2,
    'digitsOptional': true, // BUG

Here a (working) example: https://jsfiddle.net/wittich/5z8hesc4/
Any reason/explanation for that?
Regards

@wittich ,
This is fixed in version 5.0.0-beta.310
https://jsfiddle.net/0qxLcn62/


docs:minor changes.

What is it?

[ ] Feature / enhancement
[ ] Bug
[x] Docs / tests

Description
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
Use cases and why

One use case

Another use case

Checklist:

[x] My code follows the developer guidelines of this project
[x] I have performed a self-review of my own code
[x] I have made corresponding changes to the documentation
[ ] Added new tests to cover the fix / functionality

Thanks @the-r3aper7
Added a comment

@shairez i have made my changes according to #1744.

Thanks @the-r3aper7 !


Question: bitcode in j2objc necessary before releasing?

As I understand it, it's compulsory nowadays, to bake-in your bitcode (aka llvm ir?), do I have to add a parameter (i.e. -fembed-bitcode) to the j2objc Makefile process?
As I understand the release procedure, during the app review process, the offered ipa is stripped from its arch-specific bits and bobs, then the bitcode is used to recompile for that specific device+os version that requires it.

That flag is already used in the jre_emul and other library builds.


Support for Android Platform

I was trying to compile spotify-player in Termux (Android Linux Distribution) which depends on souvlaki.
I got the following error
/src/platform/mod.rs:25:1
 | mod platform;
 ^^^^^^^^^^^^^ `platform` redefined here
 = note: `platform` must be defined only once
in the type namespace of this module

Hi. Can you execute the following command in spotify-player's directory while in Termux and post its result here?
cargo rustc -- --print cfg

I tried to compile termusic in Termux
error[E0428]: the name `platform` is defined multiple times
  --> /data/data/com.termux/files/home/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/souvlaki-0.7.3/src/platform/mod.rs:25:1
   |
13 | mod platform;
   | ------------- previous definition of the module `platform` here
...
25 | mod platform;
   | ^^^^^^^^^^^^^ `platform` redefined here
   |
   = note: `platform` must be defined only once in the type namespace of this module

For more information about this error, try `rustc --explain E0428`.
error: could not compile `souvlaki` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: failed to compile `termusic v0.9.1`, intermediate artifacts can be found at `/data/data/com.termux/files/usr/tmp/cargo-install6q446v`.
To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.

Can you execute the command I commented above? Thanks.

error: manifest path /data/data/com.termux/files/home/termusic/Cargo.toml is a virtual manifest, but this command requires running against an actual package in this workspace

Can you run the command inside the tui directory of termmusic?


Ability to filter on certain tables

An ability to export data based on predefined filters belonging to certain tables and columns would be helpful to remove unnecessary noise. For example, only send data to kafka when table X, column Y gets modified. Even better approach would be able to specify when column Y of table X gets data inserted (not updated or deleted).

Good idea. We're already tracking this under #21, so I'll close this as duplicate. Would be great if you want to contribute a patch.


Rebuild for libboost 1.82

Bot could not open a PR due to pybind pin

@Tobias-Fischer
So I unpinned pybind here, because that's what kept the bot from opening this PR, but it seems this might be the reason this is now failing:
import: 'pycolmap'
Traceback (most recent call last):
  File "/home/conda/feedstock_root/build_artifacts/pycolmap_1696851618019/test_tmp/run_test.py", line 2, in <module>
    import pycolmap
ImportError: generic_type: cannot initialize type "KeysView[int]": an object with that name is already defined

Any ideas?

Gentle ping @Tobias-Fischer

I think we might be running into https://github.com/pybind/pybind11/issues/4529

The pybind11 issue seems to be resolved.
We are now running into the same issues as in #9:
  /home/conda/feedstock_root/build_artifacts/pycolmap_1697589028940/_build_env/bin/../lib/gcc/aarch64-conda-linux-gnu/10.4.0/../../../../aarch64-conda-linux-gnu/bin/ld: /usr/local/cuda/lib64/libcudart_static.a(cudart_static.o): Relocations in generic ELF (EM: 62)

I have no idea how to tackle it though, and I am not sure why it appears now.

Well it is linking to the x86_64 library while building of aarch64. The linker understandably errors
The question is, what is handing the linker the x86_64 library instead of the aarch64 library?
This probably involves more knowledge of how the build here occurs (probably combined with more verbose builds)

Also this warning on CI seems important. Maybe worth raising upstream?
  CMake Warning (dev) at /home/conda/feedstock_root/build_artifacts/pycolmap_1697589028940/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pl/share/colmap/COLMAPConfig.cmake:211 (find_package):
    Policy CMP0146 is not set: The FindCUDA module is removed.  Run "cmake
    --help-policy CMP0146" for policy details.  Use the cmake_policy command to
    set the policy and suppress this warning.

I think the issue is that this change has not been incorporated in the CmakeConfig of colmap that is being used here: https://github.com/colmap/colmap/blob/43de802cfb3ed2bd155150e7e5e3e8c8dd5aaa3e/cmake/CMakeConfig.cmake.in#L206

@conda-forge-admin  please rerender

@conda-forge-admin please rerender

@conda-forge-admin please rerender

Thank you both! 🙏


Added interface for Fpdf and Tpl

Adding an interface allows passing either a Fpdf object or a Tpl without caring which one you are getting when adding content.

Thanks, @d1ngd0.


While displaying list of work items, can we display latest 5/10 work items as release notes having limitation of 5000 characters in App center

Azure DevOps Extensions
Generate Release Notes (Node Cross Platform)
Is your feature request related to a problem? Please describe.
Yaml template which is describing Work items and Pull request showing all items and pull request in release notes.
my requirement is latest 5 items to be displayed in release notes
Describe the solution you'd like
We can loop through work items and get the latest 5 elements.
Describe alternatives you've considered
No response
Additional context
No response

You don't need an enhancement of the task, you can write it yourself using the customization options available.
Basically you write your own JavaScript based module  to implement your own loop See this loop sample that loops with sort. You could modify this exit after returning a fixed number of  items.
See this part of WIKI on using extensions

I think you module needs to be more like  https://github.com/rfennell/AzurePipelines/blob/main/SampleTemplates/XplatGenerateReleaseNotes (Node based)/Version 3 (and later)/each_with_sort_by_field.js
passing the array back as an enumerable item

Thank you very much Richard.
solution suggested by you worked for me.


docs: add documentation for assetPath for remote assets

Promised documentation for https://github.com/callstack/repack/pull/651

Great comments, thank you! I'm going off for a few days, will back to it in the beginning of next week!

Thanks for your work @adammruk, much appreciated ❤

Thanks for your support! Happy to contribute.


Showing the changelog in the play store

Would be cool if the changelog could be shown in the play store update screen. Currently there is just a link shown, which we can’t even click on.

I join the issue. There is no way to download the new version 1.2.4. After a week of its release, it doesn't even appear on F-Droid.
@dmfs Did something go wrong with the release?

The newest release 1.2.4 is still not at available on the Play Store. Any reason for that?


Etax 2015 Cask

This years online tax application for Australia.
Note: This is not a new version of e-tax2014 - it's completely new.

I'm going to create a universal package for this instead, as there seems to be a convention for naming I can use.


Rename implicit future instances to avoid shadowing by cats versions

futureInstance  => twitterFutureInstance
futureSemigroup => twitterFututreSemigroup
futureMonoid    => twitterFutureMonoid

Thanks for catching this, @aeons! I'll probably wait for the next Finagle release for 0.4.0, but I've just updated the snapshot with this change.

That's fine, thanks!

For the record, here's the conversation on Gitter about this issue.


[parrot-translate] There are problems with the translation results of some words

Extension – parrot-translate

Author: @Haojen

Description
I found that there are problems with the translation results of some words. I'm not sure whether there is a problem with the way to call Youdao translation API or the API itself.
But, for the same word, I use the Eudic dictionary to query, and its translation shows that it is normal. Need to check.

The current behavior
Translate 'heel'

Translate 'favor'

The expected behavior
Eudic translate

youdao web translate

Raycast version
Version: 1.34.1

I think maybe I've found the reason. It's the automatic language selection that causes certain words that some English words to be translated as other languages, orz...
https://fanyi.youdao.com/

https://www.youdao.com/w/favor/#keyfrom=dict2.top


Fix cask loading after adding an artifact type

[x] Have you followed the guidelines in our Contributing document?
[x] Have you checked to ensure there aren't other open Pull Requests for the same change?
[x] Have you added an explanation of what your changes do and why you'd like us to include them?
[x] Have you written new tests for your changes? Here's an example.

[ ] Have you successfully run brew tests with your changes locally? A couple of tests fail on my local machine but all of them seem to be unrelated. For example:

expected block to not output to stderr, but output "Warning: Your Xcode (11.0) is outdated.\nPlease update to Xcode 11.3.1 (or delete it).\nXcode can be updated from the App Store.\n\n"

Summary
This PR fixes an issue where we added a new global artifact and then updated a cask to make use of that new artifact. This caused a number of brew cask commands to fail for users who had the cask installed before the artifact was added.
Root cause
When loading the definition of an installed cask, we configure it using a snapshot from install time, e. g. /usr/local/Caskroom/markdownmdimporter/.metadata/config.json.
The snapshot looks like this:
{
  "default": {
    "appdir": "/Applications",
    "prefpanedir": "/Users/claudia/Library/PreferencePanes",
    "qlplugindir": "/Users/claudia/Library/QuickLook",
    "dictionarydir": "/Users/claudia/Library/Dictionaries",
    "fontdir": "/Users/claudia/Library/Fonts",
    "colorpickerdir": "/Users/claudia/Library/ColorPickers",
    "servicedir": "/Users/claudia/Library/Services",
    "input_methoddir": "/Users/claudia/Library/Input Methods",
    "internet_plugindir": "/Users/claudia/Library/Internet Plug-Ins",
    "audio_unit_plugindir": "/Users/claudia/Library/Audio/Plug-Ins/Components",
    "vst_plugindir": "/Users/claudia/Library/Audio/Plug-Ins/VST",
    "vst3_plugindir": "/Users/claudia/Library/Audio/Plug-Ins/VST3",
    "screen_saverdir": "/Users/claudia/Library/Screen Savers"
  },
  "env": {},
  "explicit": {}
}

Note that there is no mdimporterdir because the cask was installed before the artifact was added.
The root cause is that the cask loading code still expects the snapshot to contain directory configuration for all artifact types.
Since the snapshot never learned about the new artifact type, cask loading would fail.
Proposed fix
The fix is to fall back to the global default whenever the default directory map of a configuration snapshot is incomplete.

Thanks @claui!


README: name misspelled

says
Kris Zip

should say
Kris Zyp

TY!

also consider linking to https://github.com/jrburke/amdefine


defaultMessage information added to message metadata if mapping is not using defaultMessage as key

1- Added a new property to message named  defaulted to 'defaultMessage' in default mapper and key in custom mapper
2- If a message mappedBy property truthy and not equal to 'defaultMessage' then a  comment is added to current message
3- Also added a potCommentMultiLineWrapper helper to avoid breaking comments if comment has line break in it

Current coverage is 100% (diff: 100%)

Merging #60 into master will not change coverage

@@           master   #60   diff @@
===================================
  Files           5     5
  Lines          69    80    +11
  Methods         0     0
  Messages        0     0
  Branches        0     0
===================================
+ Hits           69    80    +11
  Misses          0     0
  Partials        0     0

Powered by Codecov. Last update da1731b...9eaf1cb

I'll try to push an alternate version without the mappedBy field.

Sorry for my late reply, but I have been very busy with my work past weeks.
I quickly pick some your core changes to another PR #65 so I can work on this today.
Thank you so much. 😀 😅

Released v2.0.1 with your changes.


Accessibility: Comment indicators aren't readable by assistive technologies

From Andrew's accessibility audit:
In comments, the text showing the number of the comment or whether the comment is from an ALA’er is not able to be read by assistive technologies.
Using CSS ::before and content: attr(data-count); to populate numbers and “staff” icon.  Neither is expressed in content.

These issues represent WCAG 2.0 1.3.1 Failures

@awkawk Does that fact that this is an ordered list not mitigate that?

The use of the OL mitigates the need for the "3" in the above screenshot, but not for the ALA indicator.  For that one an assistive technology user would know that it is the 6th comment, but the missing information is that the comment comes from an official ALA person.

Very good point. We've often said it might be a too-subtle indicator ever for sighted readers, so t's something we've been intending to revisit at some point.

@sarawb: I (and I think @awkawk) would like to suggest adding a text-based indication that an author has composed a particular comment. At the moment we do what is above — namely show a laurel instead of a number, and darken the comment's border.
What do you think of adding something like "Rick Pastoor (article author) 2:24 am on July 15, 2015"?

@murtaugh: are you suggesting something like "Rick Pastoor (article author) 2:24 am on July 15, 2015" as the full title that everyone sees or as an alt or title attribute?

I think that the indication is clear visually (although authors and ALA'ers have the same iconography) so this can be handled with aria-label.  We are already using "commenter name" with aria-label (and VoiceOver is doing something funky with that which I need to look into) so perhaps we could do some differentiation along those lines.

Some people don't think the current visual indicator is enough, so yeah I think "(article author)" or something might be helpful. If that conflicts with an aria role, we could remove the role, no?

Right now the aria-labels in use in this area aren't doing what they should.  The label is not being read at all, just the link text.  If looking to augment the current information I'd do this:

Anne Gibson

10:38 am on September 08, 2015

But I'd also like to add something visual, so we wouldn't really need this, right?

possibly for the date if we still want to augment that part

This is turning out to be trouble — I'd forgotten that the logic for the User addon makes this sort of thing stupidly tricky. I've asked Michelle to look into some PHP I can't get to work, for unknown reasons.

Michelle spotted what I was doing wrong. I've committed some updates, but they won't be available to test until dev is showing the right branch.
In the meantime, here's my proposal for a new display for an author's comments:

Tim, I'm wondering if the "(article author)" will be part of the link with the name or with timestamp.  I think that it should be part of the name.  I wonder whether the styling should indicate that more explicitly to avoid mouse users clicking on the first part of the bunch of light grey text to get a link to the specific comment and being confused why they are at the author bio.

It's not part of either link, actually. I don't think it needs to be, and, IMO, the parenthesis set it apart enough from the date stamp that I'm not concerned about confusion.
@mikepick should take a look at it in any case.

I don't think that it needs to be part of the link with the author name, so long as it isn't linked at all.  So I think that we agree there.  As far as whether the parentheses set it off enough I don't have a strong opinion.

This solution seems fine to me.


Add a plugin to generate the size of every page on the site

This is a first step towards #854 – I'm starting to track how big the files are, so I can compare it to the sizes on a given pull request build.

🚀 Deployed on https://66f9011590b096df82dcee54--alexwlchan.netlify.app


Add link to CWA FAQ entry "TAN Procedure" to "Request TAN for PCR Test" screen

Current Implementation
Currently, the app does not link to the newly created FAQ entry "TAN Procedure" in the "Request TAN for PCR Test" screen.
Suggested Enhancement
Add a link to the FAQ entry https://www.coronawarn.app/en/faq/results/#tan_procedure / https://www.coronawarn.app/de/faq/results/#tan_procedure to the screen.
Expected Benefits
If the user has open questions or wants to find more details reg. the TAN process, they can easily find the relevant FAQ entry.

Internal Tracking ID: EXPOSUREAPP-13885

@Ein-Tim
This is obsolete with CWA 3.0, since there is no longer a "Request TAN for PCR Test" option in the app.


✨ TypeScript SDK: resolve introspection by reference

The current TypeScript introspector is quite limited and remove a bunch of interesting feature that are natively available and broadly uses by TS engineers such as the complete type system, generics and complex default value.
The global idea is to make the TS SDK DX much more natural to a TS engineer.
For example, this simple snippet isn't working with dagger but should after this improvement:
type User = {
  name: string
  age: number
}

const DEFAULT_NAME = "john"

@object()
export class Test {

  // This is broken because `User` will not be registered in the Dagger API.
  @func()
  greet(user: User): string {
     return `Hey I'm ${user.name}, ${user.age.toString()} years old`
  }

  // This is broken because `DEFAULT_NAME` isn't resolved during the introspection.
  @func()
  newPerson(name = DEFAULT_NAME): User {
     return { name, age: 19 }
  }
}

Right now, you need to create a class User, exposing field using decorator and creating a constructor if you don't want to assign fields one by one. It's possible to hack it using Object.assign but it's doesn't feels right and it's not commonly used in TypeScript project.
Then why don't we just supports the typekeyword?
The answer is simple: how do we know if the type should actually be exposed to the API or not? We managed that with decorators like @object() and @func() but type, enum and interface keywords doesn't support decorators.
So if we aim to support these keywords, we would need to resolve types & value when they are references.
How does this work
If we reuse the same example, the flow of introspection would be:

Get the module name, convert it to PascalCase with will result in Test
Search for the Test class in the user's module code (verify that it's decorated)
Register existing functions and detect if there's a reference to an external declaration
Lookup all reference (here it would be User and DEFAULT_NAME) and register them (for default value it's just resolving what the value is)
Continue recursively until there's no more reference.

What does it enable
This would also enable constructing complex nested type without a huge boilerplate such as
type File = {
   name: string
   size: number
}

type Directory = {
  files: File[]
  path: string
}

Instead of

@object()
class File {
  @func()
  name: string

  @func()
  size: number

  constructor(
    name: string
    size: number
  ) {
     this.name = name
     this.size = size
  }
}

// ... I think it's pretty explicit for the rest

And also indeed, resolve default value in a more accurate way.
It would also be an occasion to improve the introspection error handling to give more hint to the user.
For example: type XXX is referenced in function XXX but isn't exposed to the dagger API. Please decorate your class with @object(), same for specific types that are not supported yet like type Status = "online" | "offline".
Specs of the new supported TS features
⚠ ALL these new keywords would be supported implicitely since they cannot be decorated.
type
Can be used to create dagger object but we can imagine supporting union types also (in a simple way for now)
// A dagger object with a field name & age
// For now properties are public (but there might be ways to actually make it private with generics)
type User {
   name: string
   age: number
}

enum
Resolving references would also enabling using native TypeScript eum, instead of our current noisy notation.
It's not perfect though since you cannot add metadata yet, but this can be solved with generic (gonna write an issue soon about that)
// This could be a better notation for enum also (can be supported in a follow up)
enum Status {
  Online = "online"
  Offline = "Offline"
}

💡 interface keyword will not be supported yet since it's pretty confusing with actual Dagger interface. TS interface allows to create data structure like type but also containing function, it's more or less a class with only public properties and no constructor. Making it very hard to pick in the context of Dagger.
Referenced default value
Thanks to #8653, the introspection will be done in 2 phases.

Check what's exported from the user's module (any function, class etc... can be resolved, meaning that an exported default value can be resolved and registered to the GraphQL!)
Resolve class, values and use the introspector for specific data.

### Tasks
- [ ] Start introspection by importing user's module
- [ ] List references of the main class
- [ ] Convert `type` to dagQL notation (object...)
- [ ] Convert `enum` to dagQL enum
- [ ] Correctly resolve complex default value (and document the limits)
- [ ] Rework tests to map the new way
- [ ] Ensure backward compatibility <- Should be okay
- [ ] Document all new features supported

I am very excited for this.  Wanted to point out some incorrect assumptions with this though.

💡 interface keyword will not be supported yet since it's pretty confusing with actual Dagger interface. TS interface allows to create data structure like type but also containing function, it's more or less a class with only public properties and no constructor.

The differences between type and interface are actually a lot more subtle that you described.  Both of them can have fields and methods, and both can be composed (extends / implements)
The interface in Typescript is pretty much like an interface in 'normal' OOP languages.  It simply defines the shape of an object, but doesn't supply any of the implementation.
interfaces can also be extended, so they can have "partial" definitions in separate files.
type can be as simple as you have in your original post, or they can get really complex.  The type system is actually turing complete.
A very simple usage of the type system would be
type PartialUser = Partial<User>

Partial is built into the language, but its definition looks something like
type Partial<T extends object> = {
  [K in keyof T]?: T[K]
}

That iterates through all of the properties of T and makes them optional. So,
type PartialUser = Partial<User>

is the same as
type PartialUser = {
  name?: string
  age?: number

I'm not suggesting having full support for these types, but just wanted to expand your knowledge on them a little bit more

The interface in Typescript is pretty much like an interface in 'normal' OOP languages. It simply defines the shape of an object, but doesn't supply any of the implementation.

I totally agree! However in the context of dagger, an Interface is the same as a Go interface, which is quite different that OOP since you cannot have any property in an Go interface. Originally, I wanted to support both type and interface but after talking with some of my peers and seeing how much they got lost between interface & dagger interface, I rollbacked my idea.

type can be as simple as you have in your original post, or they can get really complex. The type system is actually turing complete.

Of course! I tried to kept it scope of what we want to support. It would be too much of work for now to support specific Partial, Require, Pick, Omit etc... but maybe one day ;)

Originally, I wanted to support both type and interface but after talking with some of my peers and seeing how much they got lost between interface & dagger interface

This is where some of my concerns come in on the ts-sdk side, since most thinks, it seems (from my perspective, anyway) is based on go, and not on typescript.  It's the same as the @field() vs @func().
I would assume that the majority of people using the typescript sdk, would have a lot more experience with typescript than go, so having some go'isms creep into the ts-sdk feels a little out of place.

I would assume that the majority of people using the typescript sdk, would have a lot more experience with typescript than go, so having some go'isms creep into the ts-sdk feels a little out of place.

So you think I should support both interface and type but then how would you define a dagger interface?
If interface can be use to describe a dagger object, what's left to define a dagger interface?

If interface can be use to describe a dagger object, what's left to define a dagger interface?

I don't really know enough about a "dagger interface" to be of much help for that question, but I would think that interface and dag.Interface would be different, unrelated things.

So you think I should support both interface and type

I'm just saying that some people would instinctively use interface when definining their local types.  You could just support one, but it does still get a little messy.  Especially if interface is overloaded to be restricted to dag.Interface

If you are just using javascript, then you definitely won't access to the types.
For this stuff it will all need to be with the compiler api.
There is also a way to get the compiler api to simplify a type for you.  So it would take something like
type User = {name: string, age: number}
type PartialUser = Partial<User>

and give you
type PartialUser = {name?: string, age?: number}

I can't remember the exact way off of the top of my head, but it did involve getting the symbols for the types IIRC

I can't remember the exact way off of the top of my head, but it did involve getting the symbols for the types IIRC

This will definitely be helpful! I almost at this part haha

That would also simplify the 'do we use type or interface for dag.Interface' question.
As long as you can simplify the type, it doesn't matter which one is used.
There is also ts-morph which may help out in using the compiler api

I'm currently hitting an issue with ts-morph, I'll need to change the way I actually resolve typedef in case of intersection.
I opened an issue, hopefully I can get unblock fast on that because it's another level of difficulity to do an hybrid resolution: https://github.com/dsherret/ts-morph/issues/1580

Update related to the Type resolution:
I'm having an issue with ts-morph, he's not able to properly resolve some types for some reason so I'll need to change my strategie and fallback to backward resolution.
Basically the idea is:

Solve what I can (and easy type)
If I cannot solve it (if the type is a reference to another type): store it as undefined until it's solved by reference later.

Because sometime, ts-morph will think a type is something while it's actually another, example:
Here's in the first case, type is correctly resolve but not in the other because the default value seems to impact the type resolution (ts-morph tries to do some inference but it doesn't really work well).
  @func()
  testEnum(test: TestEnum = defaultEnum): TestEnum {
    return test
  }

  @func()
  testEnumStatic(test: TestEnum = TestEnum.A): TestEnum {
    return test
  }

        "testEnum": {
          "name": "testEnum",
          "arguments": {
            "test": {
              "type": {
                "kind": "ENUM_KIND",
                "name": "TestEnum"
              },
              "defaultValue": "b"
            }
          }
        },
        "testEnumStatic": {
          "name": "testEnumStatic",
          "arguments": {
            "test": {
              "type": {
                "kind": "OBJECT_KIND",
                "name": "References"
              },
            }
          }
        },


Please publish for Scala 2.12.20

...which is now on Maven Central, as per https://contributors.scala-lang.org/t/scala-2-12-20-release-planning/6580/8

https://repo1.maven.org/maven2/com/lihaoyi/acyclic_2.12.20/


Support for Heroku 22 stack.

Thanks.

@j4rs
https://github.com/kwrdie/heroku-22-buildpack-wkhtmltopdf


Develop iOS application

It's a big epic, should be split to the following tasks:

develop a UI similar to one in Android (2-4 Views with navigation to and from one another)
discover Bluetooth devices
pair and unpair with a Bluetooth device
store and load files to local file system
play back stored WAV file
utilize voice recognition API (Google API or one from Apple - compare them and research)

Done: https://github.com/rundb/dictofun_ios_app