How to import a Cocoapods subspec/ module instead of the entire pod in Swift - cocoapods

A subspec "represents specification for a module of the library.".
Here's an example of a .Podspec file taken from here:
Pod::Spec.new do |s|
s.name = 'RestKit'
s.subspec 'Core' do |cs|
cs.dependency 'RestKit/ObjectMapping'
cs.dependency 'RestKit/Network'
cs.dependency 'RestKit/CoreData'
end
s.subspec 'ObjectMapping' do |os|
end
end
Inside Swift, how would someone import the only the ObjectMapping subspec, instead of the whole Cocoapos Pod? The documentation does say its a "module of the library" so this leads me to believe there is some way to import the module/ subspec individually. Unfortunately for me, maybe their definition of module is different to a Swift module and this feature doesn't exist. I am aware of only this import for the whole pod:
import RestKit

Not possible
This is not possible, because Podspecs define the clang module generated.
I inferred this from the module_name documentation:
The name to use for the framework / clang module which will be generated for this specification instead of the default (header_dir if set, otherwise the specification name).
...where specification means Podspec.
Workaround
Create multiple Podspec files (clang modules). You can put them in the same directory. For example, Github: mapbox/mapbox-navigation-ios has 2 podspecs in the root directory, which refer to other Podspecs elsewhere.

Related

How do I stop the auto importing of imported item in go outside of my project?

I have my projects that have many packages which import each other and import outside packages. When I make a change to one of my low lever packages, and then push it to git it is fine and works in that section. When I go get it for use in another project that was working perfectly I now get this go get this error:
module declares its path as: github.com/xdg-go/scram
but was required as: github.com/xdg/scram
None of my code uses either of those directly. It looks like it automatically updated some lower external packages and broke things the used to then old import.
How do I either find out the package that is importing the wrong name or stop all auto-updates?
The go.mod file at github.com/xdg/scram declares itself as github.com/xdg-go/scram:
module github.com/xdg-go/scram
go 1.11
require (
github.com/xdg-go/stringprep v1.0.2
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
)
The go.mod file should be updated to reflect the correct import path.
Unfortunately if this module is for you an indirect dependency, the best fix possible is to update whatever project you import that is directly importing it.
When that is not an option, a solution to this error is to clone the problematic repository locally and use the replace directive in your go.mod file:
module mymodule
replace github.com/xdg/stringprep => ../strprep
go 1.16.2
require (
github.com/divjotarora/mgo v0.0.0-20190308170442-1d451d2a3149
)
where ../strprep is where the code of the required module exists in your local machine, relative to the go.mod file of your project.
The downside of this of course is that you have to replicate this palliative fix wherever you plan to go get your modules.
Note also:
divjotarora/mgo is just a random example of a project that imports one of those packages using their old import path.
I'm using xdg/stringprep as an example because I can't find modules that import xdg/scram instead, but apparently it suffers from the same issue
Beside, you can use:
go mod why <package> to find out why a certain package is listed as a dependency of your project
go mod graph to show the full dependency graph. The output is in <package> <requirement> format

genindex and modindex footer links don't work in readthedocs.io

I have a Python project using Sphinx for docs. I am building the docs remotely on readthedocs.io service.
I used sphinx-quickstart and it generated an index.rst file with these links in the footer:
Indices and tables
~~~~~~~~~~~~~~~~~~
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
When I push changes to readthedocs.io and build the docs, my build succeeds. Docs that I manually linked via toctree directive all work fine.
The search link works fine.
But the genindex link goes to an empty page, titled "Index"
And the modindex page links to py-modindex.html, which is a 404.
Following this guide: https://samnicholls.net/2016/06/15/how-to-sphinx-readthedocs I had run sphinx-apidoc -o api-docs/ ../myproject to generate the autodoc .rst files.
I linked the resulting api-docs/modules.rst in the toctree section at the top of my index.rst... That link works and if I click through the api-docs have been generated correctly.
Also generated by sphinx-autodoc were files for each package in my project, they contain directives like:
myproject.whatever module
-------------------------
.. automodule:: myproject.whatever
:members:
:undoc-members:
:show-inheritance:
If I browse directly to these pages they have content, but they don't appear in the index (only the tocs they are manually linked in).
I also have some manually authored pages, again linked via toc.
My docs/conf.py looks like:
import os
import sys
sys.path.insert(0, os.path.abspath("../"))
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.viewcode",
"sphinx.ext.napoleon",
"sphinx_autodoc_typehints",
]
templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
html_theme = "alabaster"
html_static_path = ["_static"]
I believe the fact that html generated from the autodoc .rst stub files are filled with modules and classes extracted from the .py files in my project indicates that the sys path fix and autodoc are basically working.
So my question is:
How to make :ref:`genindex` have some content?
How to fix :ref:`modindex` points to py-modindex.html which does not exist?
genindex and modindex are automatically managed by Sphinx. Two cases should be considered:
Any declaration in a .rst file will be inserted in those indexes. For example, if you declare a function from the Python domain:
Your rst file
-------------
.. py:function:: name(parameters)
It will be inserted in the indexes even if it doesn't have a corresponding function in any .py file.
Using autodoc directives, the same applies with a few more rules. The autodoc extension will substitute domain declarations (like above) depending if the object has a docstring and if you are using the :members: and or :undoc-members: options. So you have to verify you are using the correct option and directive for your case.
Your rst file
-------------
.. autoclass:: Your_Module.Your_Class
:members:
The above example will be substituted by a :py:class:: domain declaration if the corresponding class has a docstring, if not you need to add the :undoc-members: option.
The symptoms you are describing of having empty indexes happens when you haven't declared anything in the .rst files. With the nuance that the autodoc directives may or may not do those declarations for you depending if the objects have docstrings and you used the right options in the directives.
EDIT: You should also run make clean before your builds (e.g.make html) because inconsistencies between builds can break the index.
As I eventually worked out in the comments, thanks to help from #bad_coder, my problem was specific to building the docs in readthedocs.io
Building the docs locally worked fine.
The reason came down to use of sphinx.ext.autodoc, perhaps in conjunction with sphinx_autodoc_typehints, which seems to need to import my actual python code. Checking the logs of my apparently successful readthedocs build showed actually there were warnings like:
WARNING: autodoc: failed to import module 'whatever' from module 'myproject'; the following exception was raised:
No module named 'somelib'
i.e the docs had only partially built, it had skipped the parts it couldn't do.
The build worked locally because I was already in a virtualenv with all my project's dependencies installed.
(IMHO this seems like a bad design of the sphinx.ext.autodoc and/or sphinx_autodoc_typehints ...good static-analysis tools exist for Python which can build an AST or CST and extract structure and docstrings without importing any code.)
Well anyway, this meant that I needed to tell readthedocs.io how to install all my project deps. This is slightly complicated by the fact I'm using Poetry, which is not explicitly supported. This means I don't have a requirements.txt file to point to (and I don't want to manually create one that is a duplicate of everything in my pyproject.toml).
Fortunately the pyproject.toml file is understandable by pip, so we're able to use the pip install method described here for readthedocs.io to install both my project deps, plus extra deps that are only needed for building docs: https://github.com/readthedocs/readthedocs.org/issues/4912#issuecomment-664002569
To summarise:
Deleted my docs/requirements.txt
Added:
[tool.poetry.dependencies]
...
sphinx = {version = "^3.1.1", optional = true}
sphinx-autodoc-typehints ={version = "^1.11.1", optional = true}
and:
[tool.poetry.extras]
docs = [
"sphinx",
"sphinx-autodoc-typehints"
]
to my pyproject.toml
Updated my .readthedocs.yml to:
version: 2
sphinx:
configuration: docs/conf.py
python:
version: 3.8
install:
- method: pip
path: .
extra_requirements:
- docs
Pushed these changes to readthedocs.io ...voilĂ , now it works.

Swift sub-modules in Cocoapods

I'm trying to set up the following arrangement of private Cocoapods:
PodA depends on PodB which depends on CommonCrypto.
CommonCrypto is a dylib that ships with iOS but doesn't have a Swift header module. Within PodB I've created a custom module.modulemap with the following contents:
module CommonCrypto [system] {
header "/usr/include/CommonCrypto/CommonCrypto.h"
}
PodB passes the lint test (pod spec lint PodB.podspec) after adding the following lines:
# Ensure module isn't deleted by CocoaPods
s.preserve_paths = 'path_to/PodB/CommonCrypto'
s.pod_target_xcconfig = { 'HEADER_SEARCH_PATHS' => '$(PODS_ROOT)/path_to/CommonCrypto' }
Within PodA, I depend on PodB with s.dependency = 'PodB'. When linting PodA with pod spec lint --sources=myrepo PodA.podspec I get an error compiling any Swift file with import PodB:
missing required module 'CommonCrypto'
How can I go about fixing this? It doesn't matter to me if CommonCrypto is private or public to PodB.
I tried adding export * to module.modulemap but that made no difference.
I solved this issue with a (slightly) ugly workaround; I exported the include path to the parent project.
Since include paths are multi-valued, a list as opposed to a single setting, Cocoapods can merge whatever the parent project (PodA) sets with whatever the subproject (PodB) requires.
I had tried this solution before but it failed since I was using HEADER_SEARCH_PATHS instead of SWIFT_INCLUDE_PATHS. The relevant bit of the fixed podspec looks like this:
# Ensure module isn't deleted by CocoaPods
s.preserve_paths = 'path_to/PodB/CommonCrypto'
s.pod_target_xcconfig = { 'SWIFT_INCLUDE_PATHS' => '$(PODS_ROOT)/path_to/CommonCrypto' }
s.user_target_xcconfig = { 'SWIFT_INCLUDE_PATHS' => '$(PODS_ROOT)/path_to/CommonCrypto' }
user_target_xcconfig is what allows PodB to inject build settings into PodA. This is generally not a great idea and could be used to screw up all kinds of things, so I'd welcome a better solution, but in the particular case of pointing parent pods to a module I think it is acceptable.
That said I think this solution would fail if PodA depended on both PodB and PodC where both B and C required CommonCrypto...
So far I've had good luck just copying all of the needed CommonCrypto headers into a single bridging header, and including that into the pod. CommonCrypto changes very rarely, and it is reasonably likely that it will be a modular header before any important changes happen to it. See RNCryptor.h for an example header file. Note that all the #ifdef conditionals are included, and each entire header is included (not just what is required for this project). This should protect against multiple packages importing the same file (as long as the header doesn't change).
The resultant podspec just includes the .h as a source:
s.source_files = 'RNCryptor.swift', 'RNCryptor.h'
Did you add the framework to podB's spec file?
s.frameworks = 'CommonCrypto'
using $(PODS_TARGET_SRCROOT) instead of $(PODS_ROOT)/podname/ worked for me
s.source_files = 'Classes/**/*.swift', 'modules/**/*.map'
s.preserve_paths = 'modules/**/*.map'
s.pod_target_xcconfig = {
'SWIFT_INCLUDE_PATHS[sdk=iphoneos*]' => '$(PODS_TARGET_SRCROOT)/modules/iphoneos/CommonCrypto',
'SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]' => '$(PODS_TARGET_SRCROOT)/modules/iphonesimulator/CommonCrypto',
}
module.map files:
modules/iphoneos/CommonCrypto/module.map:
module CommonCrypto [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
}
modules/iphonesimulator/CommonCrypto/module.map:
module CommonCrypto [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
}

Error from XProcxq module in eXist-db

We're running eXist-db version 3.0 and want to try running XProc within it.
We found that the XProcxq Module is now part of eXist: http://exist-db.org/exist/apps/doc/extensions.xml#module_xprocxq
However, in attempting to use it we get the error below and wondered if anyone had suggestions for where we could be going wrong?
As specified at the top of the module page linked to, we added the module to the conf.xml file and restarted eXist. (This could be where we went wrong, but that's a guess on our part)
This is what the module we added looks like in conf.xml:
<module uri="http://xproc.net/xproc" class="org.exist.xquery.modules.xprocxq.XProcxq/>
Here is the simple started XQuery I've attempted to use:
xquery version "1.0" encoding "UTF-8";
import module namespace const = "http://xproc.net/xproc/const";
import module namespace xproc = "http://xproc.net/xproc";
import module namespace u = "http://xproc.net/xproc/util";
declare variable $local:XPROCXQ_EXAMPLES := "/db/examples"; (:CHANGE ME:)
let $stdin :=document{<test>Hello World</test>}
let $pipeline :=document{
<p:pipeline name="pipeline"
xmlns:p="http://www.w3.org/ns/xproc"
xmlns:c="http://www.w3.org/ns/xproc-step">
<p:identity/>
</p:pipeline>
}
return
xproc:run($pipeline,$stdin)
Here is the error:
error found while loading module xproc: IO exception while loading module 'http://xproc.net/xproc' from 'http://xproc.net/xproc'
I posed your question to the exist-open mailing list (where I'd encourage you to join for future eXist-db questions), and it appears XProc support in eXist is currently between a rock and a hard place. The xprocxq library you mentioned is woefully underdeveloped (abandoned by its original creator), and the much better developed Calabash module is incompatible with the current version of Saxon used in eXist, due to a dependency on that version of Saxon. I'd welcome you to join exist-open to discuss further. Perhaps there's some other workaround for you.
It needs to be rebuilt.
According to http://exist-db.org/exist/apps/wiki/blogs/eXist/eXist30RC1
EXPath packages that incorporate Java libraries may no longer work with eXist 3.0 and may need to be recompiled for our API changes; packages should now explicitly specify the eXist versions that they are compatible with.
I am working on the update to the XProc EXPath module.
The XMLCalabash module for eXist has now been rebuilt for a newer version of eXist and Calabash and should work with eXist 3.0.RC1.
To build your own Jar package for eXist 3.0.RC1 run:
$ git clone https://github.com/eXist-db/eXist-XMLCalabash.git
$ cd eXist-XMLCalabash
$ rm -rf src/test
$ mvn package
The Jar is then in the target/ folder. You should copy it to $EXIST_HOME/lib/user modify $EXIST_HOME/conf.xml to load the module and then restart eXist.
Updated
The XML Calabash module for eXist, now also has a PR so that it will support the upcoming eXist 3.0.RC2 -
https://github.com/eXist-db/eXist-XMLCalabash/pull/2
However you cannot built it remotely until eXist 3.0.RC2 is released.

Imported classes from a jar file in JRuby conflict with top level core module

I have a JRuby project that is requiring a third-party .jar file containing several Java classes that I need to use. I am running into an issue where one of the classes is named Process which is conflicting with the top level Ruby Process module.
I have built a github repository with a minimal proof of concept that illustrates the issue: https://github.com/douglasmiller/process_test
Has anyone else encountered a similar issue? What can I do to resolve this?
similar to what you would do in Ruby to solve this - import it under a module (where it's used) or do not import it at all.
do not use java_import org.process_test.Process and use org.process_test.Process::PROCESS_CONSTANT directly
if you really want to import only import where it won't conflict :
module MyApp
java_import org.process_test.Process
# MyApp::Process != ::Process
class ProcessStuff
def initialize; puts Process::PROCESS_CONSTANT end
end
end

Resources