cordova-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brian LeRoux...@brian.io>
Subject RE: cordova plugin save
Date Mon, 18 Aug 2014 20:50:55 GMT
Totally.
On Aug 18, 2014 1:34 PM, "Parashuram Narasimhan (MS OPEN TECH)" <
panarasi@microsoft.com> wrote:

> How about storing all this information in a project's package.json  ?
>
> If all Cordova CLI projects were simply NodeJS projects and Cordova was
> the builder, like Grunt or Gulp  (Thinking about it, Cordova actually is a
> builder)
> Plugins are runtime dependencies and will be in the dependencies section
> of the project's package.json. Platforms are required only for the build
> time and they would be in devDependencies. This way, we can also install
> semver'ed plugins, and plugins themselves can be published to npmjs.org.
>
> Additionally, people could even build native code using node-gyp, and all
> post-plugin hooks to build C/C++ based plugins would work.
>
> This may be a deviation from the current config.xml, but does this sound
> like something we would like to target for the future?
>
> -----Original Message-----
> From: mmocny@google.com [mailto:mmocny@google.com] On Behalf Of Michal
> Mocny
> Sent: Monday, August 18, 2014 5:53 AM
> To: Treggiari, Leo
> Cc: Michal Mocny; dev
> Subject: Re: cordova plugin save
>
> On Fri, Aug 15, 2014 at 10:29 PM, Treggiari, Leo <leo.treggiari@intel.com>
> wrote:
>
> >  I have a few follow-on questions / comments:
> >
> >
> >
> > > Run-time Platform-specific config:
> >
> > >  - Automatically created on prepare from a combination of initial
> > application template and many project properties
> >
> > >  - Currently, this is the cordova "platform" config.xml, but also
> > > the
> > various platform metadata files like AndroidManifest.xml and App.plist
> > etc
> >
> >
> >
> > So, part of the job of config.xml is to hold other application
> > definition metadata.  In particular, one set of properties is used
> > during preparation to generate the platform specific manifest files.
> > Is this set of config.xml properties ever used directly by a platform
> > at installation or loading, or is it just used during preparation?
> >
>
> Yes it is used at runtime.  Platforms/plugins can query <preference>s at
> runtime for all sorts of settings (simple things like colors, or complex
> things like how to cloud backup, where files should live)
>
>
> >
> > > Build-time Platform-generic App config:
> >
> > >   - Settings *every* developer would agree with.
> >
> > >   - Goes into VC, required to build the project.
> >
> > >   - Currently, this is /config.xml
> >
> >
> >
> > However, the fact that Cordova CLI does not store the list of
> > platforms and plugins in config.xml, makes it quite incomplete.
> >
>
> Yes.
>
> >
> >
> > Project config:
> >
> >   - Settings local to a given developers machine / project instance.
> >
> >   - Currently, this is /.cordova/config.json
> >
> >   - Can also have a global version that applies to all projects, but
> > the content is the same as per-project, conceptually the same.
> >
> >      - and ~/.cordova/config.json
> >
> >   - [I've been calling "Project config" the "Workspace config".  I
> > think both terms are overloaded and confusing.  Perhaps we should just
> > call it the "Local config"?]
> >
> >
> >
> > Sounds good.
> >
> >
> >
> > > I think the point of this thread was to figure out if the list of
> > platform/plugins to restore from should go.  With the above
> > descriptions, here are my 2c:
> >
> >
> >
> > I’m still at a higher level question which is why save/restore at all?
> > It seems like it would be better if the ‘plugin/platform add/remove’
> > commands maintained their lists in config.xml.  There’s no need for a
> > ‘save’ command then.  ‘restore’ could be interesting if it can’t be
> > done automatically – i.e. if Cordova CLI knows the list of plugins
> > from config.xml, then it could automatically  fetch them if they are
> > missing from the plugins directory.
> >
>
> Gorkems answer is spot on.  We agree, we just don't have it *yet*.
>  Waiting on PR's to address some of the issues raised in recent reviews.
>
> >
> >
> > As an IDE developer, my overall goal would be to make it such that
> > Cordova CLI and an IDE could be used seamlessly on the same application.
>  E.g.
> > support a user who likes to use both at different times, and teams
> > where some users want to use the CLI and other users want to use an IDE.
> >
>
> >
> > Leo
> >
> >
> >
> > *From:* mmocny@google.com [mailto:mmocny@google.com] *On Behalf Of
> > *Michal Mocny
> > *Sent:* Thursday, August 14, 2014 5:53 AM
> > *To:* dev
> > *Cc:* Treggiari, Leo
> >
> > *Subject:* Re: cordova plugin save
> >
> >
> >
> > Summarizing / simplifying since this thread has run away:
> >
> >
> >
> > Run-time Platform-specific config:
> >
> >   - Automatically created on prepare from a combination of initial
> > application template and many project properties
> >
> >   - Currently, this is the cordova "platform" config.xml, but also the
> > various platform metadata files like AndroidManifest.xml and App.plist
> > etc
> >
> >
> >
> > Build-time Platform-generic App config:
> >
> >   - Settings *every* developer would agree with.
> >
> >   - Goes into VC, required to build the project.
> >
> >   - Currently, this is /config.xml
> >
> >
> >
> > Project config:
> >
> >   - Settings local to a given developers machine / project instance.
> >
> >   - Currently, this is /.cordova/config.json
> >
> >   - Can also have a global version that applies to all projects, but
> > the content is the same as per-project, conceptually the same.
> >
> >      - and ~/.cordova/config.json
> >
> >   - [I've been calling "Project config" the "Workspace config".  I
> > think both terms are overloaded and confusing.  Perhaps we should just
> > call it the "Local config"?]
> >
> >
> >
> >
> >
> > I think the point of this thread was to figure out if the list of
> > platform/plugins to restore from should go.  With the above
> > descriptions, here are my 2c:
> >
> > - The list of plugin id / url and optional version go into the App
> config.
> >  Every developer I believe will agree with the list itself being a
> > requirement to build the app.
> >
> > - Local settings such as searchpaths go in the local config, since I
> > may have cloned my repos differently than you have.
> >
> > - I should be able to override the list of version requirements
> > easily, these are just suggestions to help simplify sharing, not rules.
> >
> > - Ditto for platforms.
> >
> >
> >
> > Does that make sense?
> >
> >
> >
> > If we don't like the current app/local config, lets bring that up in a
> > different thread!
> >
> >
> >
> > -Michal
> >
> >
> >
> > On Thu, Aug 14, 2014 at 4:15 AM, Gorkem Ercan <gorkem.ercan@gmail.com>
> > wrote:
> >
> >
> > The goal with the save/restore work is to make it as convenient as
> > possible to share cordova projects, so Chuck was right on the money.
> > We also have an accompanying "save/restore platforms" command. Once
> > the work is complete CLI should be able to restore plugins and
> > platforms folders of a shared project with the plugins installed and
> > platforms that was worked on.
> >
> > I actually think of config.xml as an app metadata file. Another of my
> > ramblings has been to have a single config.xml and remove the need for
> > platform specific ones. So I would prefer to avoid putting data that
> > is not relevant at runtime to config.xml.
> >
> > For instance, Eclipse Thym [1] ,that I work on, uses config.json to
> > save the engine information. I tend to think it is a more proper place
> > for it.
> >
> > Answers to some of your questions.
> >
> >
> > > -  Where does 'save' find the definitive list of plugins that it
> > > should
> > save?  There may be some plugins specified in config.xml and there are
> > other metadata (<platform>.json)  files that believe they know the list.
> >
> >   The list of plugins is simply a list of directories under the
> > plugins folder
> >
> > > -  What does it save and where?  Does it save the argument that was
> > passed to 'corodva platform add xxx'?  Does it save the id, (and
> > possibly additional information) from the sources that were actually
> fetched?
> >
> >   It saves the id and if shrinkwrap flag is set also the installed
> >   version to the config.xml. It does not use the information passed to
> >   "cordova platform add". The plan is to add git url information to be
> > saved
> >   when appropriate  so that plugins that were installed using git can be
> >   restored too.
> >
> > > -  Can 'restore' be guaranteed to fetch the same exact sources that
> > > were
> > in the project that was 'save'd?  Does it need to?
> >
> >   If shrinkwrap is set then restore will restore the exact version of
> >   the plugin from the registry. Otherwise it will get the latest
> >   available. In case of git URL it will be whatever that URL points to.
> >
> > [1] http://www.eclipse.org/thym
> >
> > --
> > Gorkem
> >
> >
> > On Thu, Aug 14, 2014 at 02:14:32AM +0000, Chuck Lantz wrote:
> > > Yeah I guess what I'm getting at is it is more of an app descriptor.
> > > It
> > describes things about the app that are immutable across the native
> > underlying projects used to build the app, different IDEs, or project
> > structures. If there was a way to import and export Cordova apps
> > across any number of IDEs or products and services (PhoneGap Build,
> > WorkLight, Intel, Telerik, etc) there are a set of things about the app
> that wouldn't change.
> > A transformed version of config.xml lands in underlying native
> > projects in the platforms folder as well.
> > >
> > > Another example, lets say that Gulp becomes the build system instead
> > > of
> > the CLI (not saying that will happen - just jumping to an extreme). We
> > need a place to keep the things that would not change.
> > >
> > > Speaking for VS, I would never put typescript compilation settings,
> > build configs, and other IDE settings that pertain to the app project
> > in config.xml. That's specific to the VS world and belongs in the VS
> project.
> > Similarly I would not force a project structure on another IDE let
> > alone someone hand editing config.xml in sublime text. Most likely
> > will not change from the CLI structure anyway.
> > >
> > > Now, how that is presented to the developer is a completely
> > > different
> > story.
> > >
> > > Whether config.xml is the right long term place for what I describe
> > > is
> > another topic entirely.  It's pretty engrained. I do think it will be
> > important to easily separate the concepts, however.
> > >
> > > On the other questions - hop on that thread. I didn't make the PR so
> > > I
> > can only speak to the code verses the exact intent. :) The issue is
> > that there is no single definitive list of plugins or platforms to
> > install today (plugins pull in dependencies for specific platforms so
> > the contents of the plugins folder is actually not the definitive
> > list).  That's what it was trying to fix.
> > > ________________________________
> > > From: Treggiari, Leo<mailto:leo.treggiari@intel.com>
> > > Sent: ‎8/‎13/‎2014 6:48 PM
> > > To: Chuck Lantz<mailto:clantz@microsoft.com>; dev@cordova.apache.org
> > <mailto:dev@cordova.apache.org>
> > > Cc: Treggiari, Leo<mailto:leo.treggiari@intel.com>
> > > Subject: RE: cordova plugin save
> > >
> > > Hi Chuck,
> > >
> > > Thanks for adding the other 'app metadata file' (like
> > AndroidManifest.xml or package.appxmanifest.xml.) to the conversation.
> >  It's important to consider that as well.  Those are somewhat
> > different because they contain information that is not built into the
> > app executable, but rather handled by an installer or loader.  Does
> > that make those settings somehow different to the app developer?  I'm
> > not sure.  But I'm sure you're right that items in the existing set of
> > metadata files affect all of the app executable, the accompanying app
> > 'manifest' file, and the accompanying cordova.js file.
> > >
> > > To start, I'm not sure that it makes sense to add any new metadata
> > > to
> > the app config.xml file.  I'm not sure that, because of its history,
> > it fits cleanly into any metadata category we might want to define.
> > Maybe a new file is needed.  Others than I are better suited to judge
> > that since I don't have the Cordova history.
> > >
> > > However, I don't agree with some of the categorizations you've made.
> > > I
> > don't see why the list of plugins your app uses is a different kind of
> > metadata than the directories where you would find portable sources,
> > plugins, merge sources, etc.  Both are required to fully define how to
> > build the app based upon a set of sources pulled from a repository.
> >  Thinking in terms of a Visual Studio example, wouldn't both be
> > defined in a single project file?  More files just leads to more
> > things to maintain and accidentally overlook.
> > >
> > > > The idea behind  save/restore is to make it easier to share a
> > > > project
> > and reduce the amount of redundant code that you'd check in to a
> > source repo.  (You could omit the plugins and platforms folders from
> > source control and then "restore".)
> > >
> > > So is that the primary use case for the new commands?  I didn't
> > > realize
> > that from the discussion I had read, but now I understand.  I  thought
> > it was specifically recommended to not put the platforms folder under
> > source code control.  So, the savings could come with the plugins
> > folder.  There are, at least, a couple of issues/questions with this
> > that have already been mentioned (just adding them here to keep them in
> one place...):
> > > -  Where does 'save' find the definitive list of plugins that it
> > > should
> > save?  There may be some plugins specified in config.xml and there are
> > other metadata (<platform>.json)  files that believe they know the list.
> > > -  What does it save and where?  Does it save the argument that was
> > passed to 'corodva platform add xxx'?  Does it save the id, (and
> > possibly additional information) from the sources that were actually
> fetched?
> > > -  Can 'restore' be guaranteed to fetch the same exact sources that
> > > were
> > in the project that was 'save'd?  Does it need to?
> > >
> > > Thanks,
> > > Leo
> > >
> > > -----Original Message-----
> > > From: Chuck Lantz [mailto:clantz@microsoft.com]
> > > Sent: Wednesday, August 13, 2014 3:58 PM
> > > To: dev@cordova.apache.org; Treggiari, Leo
> > > Subject: RE: cordova plugin save
> > >
> > > My two cents - there are three things here:
> > >
> > > 1. App metadata
> > > 2. Project metadata
> > > 3. Workspace metadata
> > >
> > > $project/.cordova/config.json is probably the closest thing to an
> > > IDE
> > project file. The closest thing to workspace level settings is
> > $home/.cordova/config.json.
> > >
> > > Given config.xml's roots, it's more of an app metadata file like
> > AndroidManifest.xml or package.appxmanifest.xml.  Its contents should
> > describe the app intendant of IDE or build system (as far as that is
> > possible). So, regarding, "The newly proposed metadata for specifying
> > project directory structure would be part of this metadata," I don't
> > think config.xml is the right place for that. It's build system config
> > - which I believe belongs in config.json. Plugins in many ways equate
> > to capabilities or intents which is why that makes sense to exist in
> > config.xml.  The platforms that the app is designed to target also by
> > extension appear to make sense (though admittedly less cleanly since
> > there isn't a native platform equivalent).
> > >
> > > On the plugin operations - Question is whether that would annoy
> > developers that prefer to edit by hand (vs IDE use). The idea behind
> > save/restore is to make it easier to share a project and reduce the
> > amount of redundant code that you'd check in to a source repo.  (You
> > could omit the plugins and platforms folders from source control and
> > then "restore".)
> > >
> > > -Chuck
> > >
> > > -----Original Message-----
> > > From: Michal Mocny [mailto:mmocny@google.com]
> > > Sent: Wednesday, August 13, 2014 3:27 PM
> > > To: Treggiari, Leo
> > > Cc: dev@cordova.apache.org
> > > Subject: Re: cordova plugin save
> > >
> > > On Wed, Aug 13, 2014 at 6:07 PM, Treggiari, Leo
> > > <leo.treggiari@intel.com
> > >
> > > wrote:
> > >
> > > >  Hi Michal,
> > > >
> > > >
> > > >
> > > > Thanks for your answers.  They were quite helpful.  I have a few
> > > > follow-ups.
> > > >
> > > >
> > > >
> > > > With your answers, and references, and I found
> > > > https://wiki.apache.org/cordova/ConfigurationFiles,
> > > >
> > > > I have a better understanding of the existing metadata files.
> > > >
> > > >
> > > >
> > > > However there seem to be quite a few of them  and I’m not yet sure
> > > > about where different types of information should go.
> > > >
> > > >
> > > >
> > > > https://wiki.apache.org/cordova/ConfigurationFiles goes into the
> > > > answers I’m looking for, except it just seems to be documenting
> > > > the current situation.
> > > >
> > > > -  What types of metadata are there?
> > > >
> > > > -  Where is each type saved?
> > > >
> > > > -  Who owns each type and can change it?
> > > >
> > > I think we are figuring this out ourselves.  There are differing
> > opinions.
> > >  Thanks for speaking up and voicing yours.
> > >
> > > >
> > > >
> > > > Here are my thoughts:
> > > >
> > > >
> > > >
> > > > - “App” (or “Project”) metadata defines everything about the “app”
> > > > that should be shared by all developers who want to develop/build
> > > > the app.  In the case of Cordova CLI, this is primarily a “build
> recipe”.
> > > > I.e. with this metadata (plus given proper “workspace” (or
> > > > “environment”) setup), anyone can build the same app.  Tooling (e.g.
> > > > Cordova CLI) or IDEs would normally be used to maintain some/all
> > > > of this metadata.  For example, Cordova CLI may handle the plugins
> > > > and platforms but document how to add icons and splash screens to
> > > > the app using this metadata file.  An IDE might manage all of that
> > > > inside the IDE itself.  The newly proposed metadata for specifying
> > > > project
> > directory structure would be part of this metadata.
> > > >
> > > Personally, this is exactly my mental model as well.  But its
> > >
> > >
> > > >
> > > >
> > > > - “Workspace” (or “Environment” or “Project specific user
> > > > settings”) metadata describe the settings that a user (or tools on
> > > > the user’s
> > > > behalf) have to make to set up an environment for
> > > > developing/building
> > the app.
> > > > E.g. the location of native SDKs.
> > > >
> > > Ditto.
> > >
> > > >
> > > >
> > > > In general, different tooling/IDEs could have different rules
> > > > regarding who creates these metadata files and who is allowed to
> > > > edit
> > them and how.
> > > >
> > > >
> > > >
> > > > Is app config.xml intended to be the “App” metadata file?
> > > >
> > > Yes.  Though it should be noted that most everyone would rather
> > > there
> > was a different file for this.
> > >
> > > config.xml is based on a deprecated proposal for app metadata
> > > (widget
> > spec).  There are several new app manifest formats roaming around,
> > most based on json.  However, I think we will likely use what we
> > already have for the foreseeable future since we're already spending
> > way too much time on tooling and changing this is not worthwhile
> bang-for-buck.
> > >
> > > >  Is .cordova/config.json intended to be the “Workspace” metadata
> file?
> > > >
> > > I think so.  I'm less sure about how everyone feels about this file,
> > > but
> > its likely that we will stick with what we have.  Its also possible
> > that IDE's/downstream tooling can just use some internal settings
> > representation since most the the config.json values can be passed in
> > to the CLI through the command line or node interface.
> > >
> > > >
> > > >
> > > > > - Aside from the initial create script that sets name etc, the
> > > >
> > > > > plugin/platform save command is the first tooling command to
> > > > > edit the
> > > > file
> > > >
> > > > > directly (I think?).
> > > >
> > > >
> > > >
> > > > I don’t understand why ‘cordova plugin/platform add/remove’ would
> > > > not modify app config.xml, but now ‘cordova plugin/platform save’
> would.
> > > > Or is that really the distinction between the 2?  And how does
> > > > that list of plugins interact with what the user may have added
> > > > themselves
> > to config.xml?
> > > >
> > > I think this was Andrew's point and Gorkems original intention.  We
> > agree that `plugin add/remove` should update the list.  The
> > save/restore was just a non-intrusive way to experiment for now.
> > >
> > > >
> > > >
> > > > Thanks,
> > > >
> > > All good questions raised, with few definitive answers.  It sounds
> > > like
> > you're all caught up to the rest of us, though!
> > >
> > > >  Leo
> > > >
> > > >
> > > >
> > > > > A few answers:
> > > >
> > > > > - There is no spec, since this is an "experimental" feature we
> > > > > aren't
> > > >
> > > > >  ourselves sure yet how it will look when complete.  That was
> > > > > the point
> > > > of
> > > >
> > > > >  recent threads.
> > > >
> > > > > - The file belongs to the app / user, not to the workspace /
> tooling.
> > > >
> > > > > - Aside from the initial create script that sets name etc, the
> > > >
> > > > > plugin/platform save command is the first tooling command to
> > > > > edit the
> > > > file
> > > >
> > > > > directly (I think?).
> > > >
> > > > > - You can read more here:
> > > >
> > > > > https://cordova.apache.org/docs/en/edge/config_ref_index.md.html
> > > >
> > > > > - The top level "app" config.xml is not platform specific, but
> > > > > you can
> > > > have
> > > >
> > > > > platform specific settings in there by using the <platform>
tag
> > > >
> > > > > - It is specific to cordova CLI.  Each platform has another,
> > > > > different
> > > >
> > > > > config.xml (we usually call it the "platform" config.xml) which
> > > > > is
> > > > created
> > > >
> > > > > during cordova prepare, and thats what edited with non cli
> workflow.
> > > >
> > > > > - Phonegap workflow (also chrome cordova (cca) and likely
> > > > > others) is
> > > >
> > > > > compatible with cordova config.xml, but those often also add
> > > > > extensions
> > > > to
> > > >
> > > > > the options
> > > >
> > > > > - "project-level" (I call this "workspace") metadata should
> > > > > *not* go into
> > > >
> > > > > app config.xml. We already have another file,
> > > > > .cordova/config.json for
> > > >
> > > > > those.  However, the list of plugins that your app needs is
> > > > > arguably not
> > > > a
> > > >
> > > > > property of a workspace, but truly a property of your application.
> > > > > Ditto
> > > >
> > > > > for platforms (to a lesser extent).
> > > >
> > > > >
> > > >
> > > > > I'm not so sure what the proposal is for removing plugins/
> > > > > directory, I
> > > >
> > > > > don't think there is anything concrete for that, it was just
> > > > > ramblings of
> > > >
> > > > > various contributors ;)
> > > >
> > > > >
> > > >
> > > > > -Michal
> > > >
> > > > >
> > > >
> > > > >
> > > >
> > > > > On Wed, Aug 13, 2014 at 2:41 PM, Treggiari, Leo
> > > > > <leo.treggiari@intel.com
> > > > >
> > > >
> > > > > wrote:
> > > >
> > > > >
> > > >
> > > > >> I'm new to this mailing list.  I work on the Intel(r) XDK which
> > > > >> is
> > > > another
> > > >
> > > > >> IDE which supports the creation of hybrid apps using Cordova
> > plugins.
> > > >
> > > > >>
> > > >
> > > > >> I'm having trouble figuring out what the proposed 'cordova
> > > > >> plugin
> > save'
> > > >
> > > > >> command does.  Is there an up-to-date 'spec' that explains the
> > > > >> goals of
> > > > the
> > > >
> > > > >> command and the implementation?
> > > >
> > > > >>
> > > >
> > > > >> A couple of things that I have read in the mailing list concern
> me.
> > > >
> > > > >>
> > > >
> > > > >> There is mention of saving information in config.xml.  The
> > > > >> usage of
> > > >
> > > > >> config.xml is somewhat of a mystery to me:
> > > >
> > > > >> -  Who owns the file?  Does the user own and edit it?  Do
> > > > >> certain
> > > > Cordova
> > > >
> > > > >> CLI commands edit it?  What are the valid entries?
> > > >
> > > > >> -  Is it treated differently by different platform builds - e.g.
> > iOS vs.
> > > >
> > > > >> Android?  Is it treated differently by Cordova CLI vs. other
> > > > >> Cordova
> > > > IDEs
> > > >
> > > > >> which directly use Cordova CLI or not - e.g. PhoneGap build?
> > > >
> > > > >> -  If Cordova CLI wants to store 'project-level' metadata, is
> > > > >> this a
> > > > good
> > > >
> > > > >> place to put it?  If the answer to the first question above is
> > > > >> not well
> > > >
> > > > >> defined, or the answer to the second question is that different
> > 'things'
> > > >
> > > > >> are using it differently, then config.xml may not be a good
> > > > >> place to be
> > > >
> > > > >> putting new metadata.
> > > >
> > > > >>
> > > >
> > > > >> There is a mention of plugin "restoring" and making the plugins
> > > > directory
> > > >
> > > > >> optional.  This relates to the issue of plugin 'versions'.
> > > > >> Now, when a
> > > >
> > > > >> user executes 'cordova plugin add', plugin sources are fetched
> > > > >> and the
> > > >
> > > > >> version of the plugin that was added is fixed until the user
> > > > >> explicitly
> > > >
> > > > >> removes and re-adds it.  Is 'cordova plugin save' & 'restore'
> > > > suggesting a
> > > >
> > > > >> new version management model?  E.g. if I add a plugin without
a
> > > > >> specific
> > > >
> > > > >> version suffix and 'restore' it later, I may not get the same
> > > > >> version,
> > > >
> > > > >> right?
> > > >
> > > > >>
> > > >
> > > > >> If there is a 'spec', I should be able to answer these
> > > > >> questions
> > myself.
> > > >
> > > > >>
> > > >
> > > > >> Thanks,
> > > >
> > > > >> Leo Treggiari
> > > >
> > > >
> > > >
> >
> >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message