A vector version of the XcodeCapp logo is needed for ongoing maintenance and isn’t present in the repo. Does anyone remember who did the original artwork? It’s not obvious from the commit history.
I have autotraced the raster version and it’s a good starting point for cleanup - but it would be nice to have the original.
So I'm trying to install Cappuccino NPM from source—and I got this error.
cappuccino % jake install
(in /Users/gtavares/cappuccino)
Error on line 53 of file [unknown]
Error: require error: couldn't find "fs"
My guess is that Jake was not installed for npm.
Fair enough so I do:
jake install
And now I get:
cappuccino % jake install
jake aborted.
ReferenceError: ObjectiveJ is not defined
Where am I screwing up??
npm install
only runs locally and I needed to run npm -g install
to place it in the ~/.npm/bin
Preprocessor.j
file and was trying to figure out where #if
is implemented because I consider the Preprocessor to have a bug (#if
does not work until it we call @import <Foundation/Foundation.j>
. The hash
function really confuses me. Where can I maybe find the implementation or understand how #if
works so I can fix my issue? Preprocessor.prototype.hash = function(tokens, aStringBuffer)
{
var buffer = aStringBuffer ? aStringBuffer : new StringBuffer(),
token = tokens.next();
if (token === TOKEN_PRAGMA)
{
token = tokens.skip_whitespace();
if (token === TOKEN_MARK)
{
while ((token = tokens.next()).indexOf("\n") < 0);
} } else
throw new SyntaxError(this.error_message("*** Expected \"pragma\" to follow # but instead saw \"" + token + "\"."));
};
Preprocessor.j
is deprecated and not used anymore. Actually it should be removed from the repository. It is the old compiler that was a kind of advanced search and replace of parts of the code to transpile it from Objective-J to Javascript.
await
/async
. The latest Acorn has a poor man type of plugin architecture that can be used to extend the parser. But it is very dependent of the internal workings so not very good at extending more complex things like we do with the Objective-J language. It is also hard if not impossible to extend the Tokenizer with that plugin architecture. The Tokenizer is modified in our version to implementation our preprocessor. It is not built like a regular preprocessor that "preprocess" the file and creates a new file that is then compiled. It is implemented as a Recursive Token Transformer. It will transform tokens on the fly to the "preprocessed" result. This allow it to be very fast and only do one scan over the source file when compiling.
tests.js
at https://github.com/mrcarlberg/acorn. Should be nice if we could get your problem as a test case too.
@mrcarlberg afaik we can build and test XcodeCapp using github actions too. I began looking at this several months ago. From what I saw, the oldest support OS is High Sierra.
Does limiting XcodeCapp support to macOS 10.13 to fit Github’s CI pipeline cause problems for us?
XcodeCloud is available now too, but that is tied to individual Apple IDs - Github Actions seems the better choice.
I continue picking away at the problems in XcodeCapp as time permits and will set up CI actions for it.
@import
/ and #import
statements because Objective-J so far as I know does not really understand #import
. Technically—Objective-J should never see my #import
statements because these are hidden behind an #if
statement
@mrcarlberg This question is probaby for you (but anyone with large app experience should chime in)…
Our main app is best approached as a plugin host, with something like 1 1/2 dozen modules which a user can activate. They all have content displayed in the host app, in a defined subview.
Until now, all the modules have lived in a Modules bundle in the main app, each with their own sub-bundle. This works, but it is a subtle invitation for unwanted coupling.
Moving the plugin bundles to the Frameworks folder is more elegant, but they are under active development, including xibs. XcodeCapp won’t see resources in those bundles to recompile (especially xibs). Adding the Framework bundles as separate Xcode projects runs into temporary path permission problems with nib2cib.
It looks as though the only proper way to do this is to move the bundles to their own projects and git repositories.
Thoughts on best practices for large scale development and modularity?
nib2cib
and/or objj2objcskeleton
manually or with a simple bash script.
The OS setup is absolutely standard (Monterey hardly allows anything else). XcodeCapp appears to have been designed with the intent all xibs are stored in the main bundle’s Resources folder and doesn’t seem to behave well if not. Keeping xib resources separate from their associated code resources is increasingly a problem for managing the app, as it grows. Using folders in the Xcode sidebar as logical groups is one answer to that, but, as you point out, XcodeCapp is ill-behaved wrt Xcode project files (in some circumstances). That can, should, and will be fixed, but this app has also grown beyond the point where a monolithic project structure is appropriate. It is also just a nuissance to keep one or more terminal windows open to watch and compile nibs. And also to create Objective-C matching class definitions. And Xcode doesn’t have an integrated terminal capability.
Packaging as frameworks, in the Frameworks folder, seems the best approach. At the moment, the modules are under active development - for refactoring. I’m also somewhat concerned about managing imports in the frameworks scenario - there are currently cross-dependencies, and it’s not yet obvious how those will be sorted out.
An allied problem is that I insist on far more separation of concerns into individual files than most people probably do, with smaller controllers for many, if not most, individual sub-views. That’s before getting to datasources and delegates. It’s reached the point these really should be packaged directly with their associated xib assets. Some will suggest avoiding xibs altogether - my experience is it’s very difficult to get a visually polished result going that route.
Simpling moving the module bundles into the Frameworks folder has resulted in jake build problems though. It looks to me as though, as frameworks, they need to be kept entirely out of the main app, built separately, and the build artifacts symlinked or copied in. I assume the reason XcodeCapp allows adding multiple projects which are actively watched is to accommodate just such an approach. I was hoping someone might actually have experience with such, but it seems not.
For the moment, staying with the monolithic project structure is workable. A single module is currently being factored out into a separate app, and that can be used as a base to work back upwards in complexity.
One thing I’ve noticed is the monolithic on-disk structure of this app has negatively influenced coupling of the constituent parts - it’s more rigid than need be.
It’s probably time to revisit Nuage’s project structure - it’s of the scale I envisage this app soon reaching and perhaps it offers some guidance.
Info.plist
file. This allows a deep structured project to be compiled in the browser.@mrcarlberg I had come to the same conclusions over the last few years. The best approach available now has been to use Xcode’s sidebar groups to provide useful organization. It works, but one must be careful to not select ‘Group with folder’. I had noticed #2963 when it was posted, but failed to grasp its significance. fwiw, there has long been a Ruby gem to synchronize Xcode’s virtual folder with the on-disk structure: https://github.com/venmo/synx
An analagous automated tool would nicely complement #2963
Anyone able to describe in detail how an app built for release bootstraps itself? I’m in the process of hardening ours, starting with prohibiting everything, then specifically allowing the pathnames required by the app.
Strangely, one of the first URL requests is for main.j, which isn’t a file in the Release build artifacts, despite having a reference in index.html. Having trouble understanding where the request for main.j originates - although I’m guessing it’s a fallback built into the Objective-J runtime file.
Insight welcomed. It will also help in process of defining the offline operation requirements.
Frameworks/Objective-J/Objective-J.js
is read and executed. It will setup the Objective-J runtime../Info.plist
is read and parsed to get stuff like path to main file (usually main.j
), is it prebuilt etc...Frameworks/Foundation.sj
etc.@import
then read each of the imported files.Foundation/CPObject.j
and some other similar classes. The load system now starts execute each source file from the leafs of the recursive tree that is built when loading all the imported files above. If the source files are not pre built the compiler will generate the compiled javascript code from the previously generated AST tree before executing it.main
function. The function is called.