Image download automation with Lingo & LAF
April 23, 20191061 words
6 min read
- What’s the usual flow for getting graphics into an app folder?
- What are the potential shortcomings of that?
- What do I do differently?
- How could it be improved going forward?
Don’t care about thoughts/want the goods? Jump to References
Riding the Squiggle
I was taught to “avoid automating what you don’t understand”. Here’s an ode to understanding the squiggle:
Workflow
1. Export assets from sketch
2. Update the existing assets directory within the app repository:
1. Overwrite the updated
2. Remove the outdated
3. Update file names
4. Git
1. Git status check
2. Confirm that no critical assets are being removed
3. Update repo
Potential Problems
Exporting manually: easy at first, cumbersome over time
Iterating on design constantly? I found that it was obnoxious to have to continually re-export for every little file change. Export. Download. Visually Diff. Add to correct folders. Re-run app. Confirm that image sources aren’t broken. Wait to do it again.
Downloading new files
Overwrite a file name and lose an asset as a result
Downloading old files with updated names
Forget to update an asset name in source and break an image
Unwinding the Squiggle
What are the asset management options I explored?
- Sketch augmented with some plugins (eg. artboard-manager)
- Invision: Love their product. I’m an Invision fanboy. Unfortunately, their DSM fell short.
- Zeplin: Heard great things. Disappointed by experience. Felt like the “Inspect” feature of Invision wrapped in a native mac app.
- Lingo: Hmm… This looks interesting
The good of Lingo
-
Sketch plugin makes it easy to fetch everything from my Sketch file into Lingo in one click
-
Native desktop & web apps
-
Developed by TheNounProject (ie. have established track record in the design community) https://thenounproject.com/ https://github.com/TheNounProject
-
API & JS SDK
The bad of Lingo (aka. the new squiggle)
Immediately after falling for Lingo, I discovered some emotional baggage: you cannot download all of the assets at once. At this point I was torn.
-
On one hand...
Invision had an almost non-existent API experience for their DSM. But they did allow you to batch download all of your assets in a zip file -
On the other hand...
Lingo had a great UX and a workable API. But I have to manually download 200+ assets …? This would wipe out the time saved from the “pull all assets” feature their Sketch plugin offered.
Straightening the Squiggle
Brainstorming
Here’s the (initial) desired workflow I want:
1. Fetch all new assets by pressing “pull assets” in Lingo (one button, no manual adding)
2. Confirm the assets are still where they should be
3. Download all files from lingo
4. Sort them into proper sub-folders (~/MyRepo/assets/:lingo-section-name/:lingo-header-name)
5. Archive the previous assets (ie. move them to a hidden directory be prepending a . )
6. Print a log of all added and archived assets
7. If the “—hard” flag was passed, automatically remove the archived directory
8. If the “—soft” flag (or no flag) was passed, keep both the current and archived directory
Fruits of the brainstorm
I’ve already implemented the first 3 steps via LAF. LAF makes it easy to fetch assets from lingo via package.json or your terminal. The docs contain step-by-step instructions as well as video tutorials to get you started.
Apples, Oranges, Bananas
Let’s compare these three workflows:
- vanilla Sketch
- Sketch with Lingo
- Sketch with Lingo & LAF
Storm of the fruits
Phases 4 - 8 are what I refer to as the “asset diffing” phase. I brainstormed some possible steps to implement that:
Benefits of this approach
- devs can be sure they’re always using the latest version of assets without worry of over/under-fetching
- lingo makes it easy to grab everything all at once (instead of needing to manually add)
- assets will always be downloaded to their relevant directory (ie. don’t have to download to finder & manually move files around)
Negatives of this approach
Seems fairly straight forward. But then it occurred to me that there are (at least) two downfalls to this implementation plan:
- designers can’t change the section/header names in Lingo willy-nilly.
- designers also can’t change the lingo tag names or Sketch layer names (the latter being a massive blocker IMO). Why? If they do, those files will be changed for the developer as well. This means that Lingo “tags” and Sketch “layers” become extremely touchy.
- renaming symbols requires manual renaming from dev (eg. you have “icon-arrow-left” and rename it to “icon-left-arrow” the dev will have to update on their end to match; will show in the file diff but doesn’t make the change for them)
Both of these issues stem from the fact that there’s a hardcoded link between lingo asset structure and app file structure.
Making Babel out of Lingonade
I realized that what I really wanted was the ability to
1. Design something in Sketch
2. Store those assets in Lingo
3. Fetch those assets from package.json as part of my build step
4. Automatically update any symbolic references in my code
This sounds nice but I realized that “asset diffing” was not enough. In order to unlock this final flow, I’m going to need to
1. create a hash map of all assets’ names and their UUIDs
2. store this locally in a keyval store like lowdb
3. create a babel (or similar AST solution) plugin that will allow me to find/replace without accidentally wrecking code
If you’re interested in contributing, would love the help! If you try out LAF in its current form, I would appreciate any feedback (GH issues work great)
References
CLI
@github
: lingo-asset-fetcher-cli@npm
: laf
Lib
@github
: lingo-asset-fetcher-lib@npm
: laf-lib
Video Tutorials
Shoutout
WCByrne & bjudson were extremely helpful. To demonstrate what I mean:
Early on I ran into an API limitation (it was still in private beta so the SDK was pretty sparse). They implemented the feature request within 4 hours. Phenomenal response time. And they continued to be patient with me through my dumbest of questions. The experience was a nice breath of fresh air from a product team.
Written by Alec HP